本页面介绍了如何使用标记在 Google Kubernetes Engine (GKE) 中有选择性地强制执行 Cloud 新一代防火墙网络防火墙政策。与默认 Google Cloud 资源层次结构相比,标记可提供更精细的控制,以便整理资源层次结构。标记还允许有条件地强制执行政策。
本页面适用于希望对 GKE 中的防火墙政策进行精细控制的安全专家。如需详细了解我们在 Google Cloud 内容中提及的常见角色和示例任务,请参阅常见的 GKE 用户角色和任务。
在阅读本页面之前,请确保您熟悉以下概念:
关于标记
标记是键值对,可让您在组织级或项目级为Google Cloud 资源添加注释和进行管理。您可以使用标记来整理资源并按条件应用政策(例如防火墙或 IAM 政策)。您可以使用 IAM 访问权限控制来规定谁可以附加、创建、更新或删除标记。
如需了解有关标记的更多信息,请参阅 Resource Manager 文档中的标记概览。
使用标记强制执行网络防火墙政策
您可以使用标记有条件地将全球或区域级网络防火墙政策应用于您的 GKE 节点。您必须为希望与网络防火墙政策搭配使用的标记指定 GCE_FIREWALL 用途。当您将防火墙用途的标记应用于 GKE 集群或节点池时,GKE 会自动将这些标记附加到相应的 Compute Engine 虚拟机。
有了网络防火墙政策标记,您便无需使用网络标记。网络标记是任何人均可以附加到底层 Compute Engine 虚拟机以强制执行 Virtual Private Cloud 防火墙规则的元数据,并且不支持 IAM 访问权限控制。如果您将网络标记与 VPC 防火墙规则搭配使用,我们建议您改用网络防火墙政策并使用安全防火墙标记。如需查看详细的比较情况,请参阅本文档中的将网络标记与标记进行比较。
用于网络防火墙政策工作流的标记
如需在 GKE 中将标记与网络防火墙政策搭配使用,请执行以下操作:
创建标记:
- 在组织级层或项目级层定义标记键,例如
env。 - 定义该键可能的标记值,例如
dev、staging和prod。 指定该标记用于网络防火墙政策目的。
- 在组织级层或项目级层定义标记键,例如
向用户授予与防火墙标记交互的权限。
将标记键值对应用于特定 GKE 集群、节点池,或在自定义 ComputeClass 中使用它们,以将其应用于特定工作负载的节点。GKE 会自动将标记附加到底层 Compute Engine 虚拟机,以强制执行防火墙政策。
准备工作
在开始之前,请确保您已执行以下任务:
- 启用 Google Kubernetes Engine API。 启用 Google Kubernetes Engine API
- 如果您要使用 Google Cloud CLI 执行此任务,请安装并初始化 gcloud CLI。如果您之前安装了 gcloud CLI,请通过运行
gcloud components update命令来获取最新版本。较早版本的 gcloud CLI 可能不支持运行本文档中的命令。
要求和限制
- GKE 1.28 及更高版本支持用于网络防火墙政策的标记。如果您使用早于 1.28 版的 GKE 版本,请改为搭配使用网络标记与 VPC 防火墙规则。
- 在 Standard 集群中,每个节点池最多支持五个附加的防火墙标记。
- Autopilot 集群最多支持五个防火墙标记。
- 自定义计算类最多支持 5 个标记。
- GKE 会拒绝使用
gke-managed前缀的标记键。 - 您必须先创建标记键值对,然后才能将其附加到集群或节点池。
IAM 角色和权限
如需获得在 GKE 中将标记用于防火墙政策所需的权限,请让您的管理员授予您以下 IAM 角色:
-
向用户和 GKE 服务代理授予标记所需的权限:
- 您项目的 Project IAM Admin (
roles/resourcemanager.projectIamAdmin) - 组织的 Organization Administrator (
roles/resourcemanager.organizationAdmin)
- 您项目的 Project IAM Admin (
-
创建和管理标记:组织或项目的 Tag Administrator (
roles/resourcemanager.tagAdmin) -
将标记附加到资源:项目的 Tag User (
roles/resourcemanager.tagUser)
如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限。
创建标记
标记必须存在才能附加到集群或节点。如需创建标记,请参阅 Cloud NGFW 文档中的使用防火墙标记。
标记键的 parent 可以是 projects/PROJECT_ID 或 organizations/ORGANIZATION_ID
如需将安全标记键与 Cloud NGFW 搭配使用,您必须将 purpose 属性设置为 GCE_FIREWALL,并且必须将 purpose-data 属性的值指定为 network 或 organization=auto。
创建标记键:
创建网络级范围的标记键:
此标记键的范围限定为
purpose-data字段中指定的 VPC 网络。gcloud resource-manager tags keys create TAG_KEY \ --parent=projects/PROJECT_ID \ --purpose=GCE_FIREWALL \ --purpose-data=network=PROJECT_ID/NETWORK_NAME替换以下内容:
TAG_KEY:标记键的名称,例如envPROJECT_ID:您的 Google Cloud 项目 IDNETWORK_NAME:您将与标记搭配使用的 VPC 网络的名称
创建组织级标记键:
此标记键可用于组织内的任何 VPC 网络。
gcloud resource-manager tags keys create TAG_KEY \ --parent=projects/PROJECT_ID \ --purpose=GCE_FIREWALL \ --purpose-data=organization=auto替换以下内容:
TAG_KEY:标记键的名称,例如envPROJECT_ID:您的 Google Cloud 项目 ID
organization=auto将自动替换为组织 ID。例如:purposeData: organization: '123456789012'
获取标记键的 ID:
gcloud resource-manager tags keys describe PROJECT_ID/TAG_KEY \ --format="value(name)"输出为
tagKeys/KEY_ID,其中KEY_ID是该键的数字 ID。记下此 ID 以供日后使用。向该标记键添加标记值:
gcloud resource-manager tags values create TAG_VALUE \ --parent=tagKeys/KEY_ID将
TAG_VALUE替换为该标记键允许的值的名称,例如dev。
在 gcloud CLI 命令中使用正确的标记语法
使用 gcloud CLI 引用标记时,您必须使用以下语法之一设置键值对的格式:
| 标记语法 | |
|---|---|
tagKeys/KEY_ID=tagValues/VALUE_ID |
替换以下内容:
例如 |
ORGANIZATION_ID/TAG_KEY=TAG_VALUE |
替换以下内容:
例如 |
PROJECT_ID/TAG_KEY=TAG_VALUE |
替换以下内容:
例如 |
PROJECT_NUMBER/TAG_KEY=TAG_VALUE |
替换以下内容:
例如 |
将标记定位至防火墙政策
创建标记后,您可以在防火墙政策规则中引用特定键值对。如需了解相关说明,请参阅使用防火墙标记。
向服务代理授予 IAM 权限
为了使 GKE 在纵向扩容事件期间自动将标记附加到新节点,您必须向 Google Cloud管理的服务账号(也称为“服务代理”)授予相应的 IAM 角色。
向 Kubernetes Engine 服务代理授予 Tag User 角色 (
roles/resourcemanager.tagUser):gcloud projects add-iam-policy-binding PROJECT_ID \ --member=serviceAccount:service-PROJECT_NUMBER@container-engine-robot. \ --role=roles/resourcemanager.tagUser \ --condition=None将
PROJECT_NUMBER替换为该集群的 Google Cloud项目编号。如需查找项目编号,请运行以下命令:gcloud projects describe PROJECT_ID --format="value(projectNumber)"对于标记键值对,向 Kubernetes Engine 服务代理授予 Tag Holds Administrator 角色 (
roles/resourcemanager.tagHoldAdmin):gcloud resource-manager tags values add-iam-policy-binding PROJECT_ID/TAG_KEY/TAG_VALUE \ --member=serviceAccount:service-PROJECT_NUMBER@container-engine-robot. \ --role=roles/resourcemanager.tagHoldAdmin如果 GKE 中仍在使用该键值对,则此角色可使服务代理防止标记被删除。
向 Google API 服务代理授予 Tag User 角色 (
roles/resourcemanager.tagUser):gcloud projects add-iam-policy-binding PROJECT_ID \ --member=serviceAccount:PROJECT_NUMBER@cloudservices. \ --role=roles/resourcemanager.tagUser \ --condition=None
针对项目外的标记授予其他 IAM 角色
如需使用集群项目以外的组织或其他项目所有的标记,请执行以下额外的步骤:
对于对父级资源中标记,向 Kubernetes Engine Service Agent 访问权限授予 Tag User 角色 (
roles/resourcemanager.tagUser):gcloud resource-manager tags keys add-iam-policy-binding PARENT_RESOURCE/TAG_KEY \ --member=serviceAccount:service-PROJECT_NUMBER@container-engine-robot. \ --role=roles/resourcemanager.tagUser \ --condition=None替换以下内容:
PARENT_RESOURCE:拥有该标记的资源的项目 ID 或组织 IDPROJECT_NUMBER:集群项目的项目编号
对于对父级资源中标记,向 Google API 服务代理访问权限授予 Tag User 角色 (
roles/resourcemanager.tagUser):gcloud resource-manager tags keys add-iam-policy-binding PARENT_RESOURCE/TAG_KEY \ --member=serviceAccount:PROJECT_NUMBER@cloudservices. \ --role=roles/resourcemanager.tagUser \ --condition=None向该标记键值对的 Kubernetes Engine 服务代理授予 Tag Holds Administrator 角色 (
roles/resourcemanager.tagHoldAdmin):gcloud resource-manager tags values add-iam-policy-binding PARENT_RESOURCE/TAG_KEY/TAG_VALUE \ --member=serviceAccount:service-PROJECT_NUMBER@container-engine-robot. \ --role=roles/resourcemanager.tagHoldAdmin
将防火墙标记附加到 Autopilot 集群
您可以在集群级将防火墙标记附加到 Autopilot 集群。GKE 会自动将这些集群级标记应用于每个节点。
在创建新的 Autopilot 集群时附加标记
运行以下命令:
gcloud container clusters create-auto CLUSTER_NAME \
--location=LOCATION \
--autoprovisioning-resource-manager-tags=TAG1,TAG2,...
替换以下内容:
CLUSTER_NAME:新集群的名称。LOCATION:集群的 Compute Engine 区域。TAG1,TAG2,...:要附加的一组以逗号分隔的键值对。每个键值对都必须使用受支持的语法(如“命令中的标记语法”部分中所述)。例如example-project/env=dev,1234567901/team=sre。
将标记附加到现有 Autopilot 集群
运行以下命令:
gcloud container clusters update CLUSTER_NAME \
--location=LOCATION \
--autoprovisioning-resource-manager-tags=TAG1,TAG2,...
更新集群上的标记时,GKE 会改写其中所有节点上的任何现有标记。
将防火墙标记附加到 Standard 集群和节点池
用于附加标记的方法取决于您是否希望集群中的其他节点池继承这些标记,如下所示:
| Standard 集群防火墙标记 | |
|---|---|
--autoprovisioning-resource-manager-tags |
集群级设置 GKE 会将这些标记应用于集群中的所有新自动预配的节点池。 如果您在现有集群中使用此标志,GKE 不会将这些标记应用于集群中的现有节点池。现有节点池会保留更新之前已应用的所有标记。如需更新现有节点池的标记,请使用 |
--resource-manager-tags |
节点池级设置 GKE 会将这些标记应用于指定的节点池。如果您在创建集群期间使用此标志,则 GKE 会将这些标记应用于 GKE 创建的默认节点池。如果在自动预配的节点池上使用此标志,则 GKE 会覆盖该节点池上的所有现有标记。 |
将防火墙标记附加到 Standard 集群
您可以将标记附加到新的或现有的 Standard 集群。将标记附加到整个集群时,GKE 会将这些标记视为在集群级上设置的。
将标记附加到具有节点自动预配功能的新 Standard 集群
默认情况下,GKE 会将集群级的标记用于新的自动预配节点。GKE 在集群中创建的默认节点池不会自动预配,也不会获取这些标记。
gcloud container clusters create CLUSTER_NAME \
--location=LOCATION \
--autoprovisioning-resource-manager-tags=TAG1,TAG2,... \
--enable-autoprovisioning \
--max-cpu=MAX_CPU \
--max-memory=MAX_MEMORY
替换以下内容:
CLUSTER_NAME:新集群的名称LOCATION:新集群的 Compute Engine 区域或可用区TAG1,TAG2,...:要附加的一组以逗号分隔的键值对。每个键值对都必须使用受支持的语法(如“命令中的标记语法”部分中所述)。例如example-project/env=dev,1234567901/team=sre。MAX_CPU:集群的核心数量上限MAX_MEMORY:集群的最大内存容量(以 GB 为单位)
在现有集群上启用节点自动预配功能时附加标记
GKE 仅将这些标记应用于新的自动预配节点池。现有节点池会保留更新之前具有的所有标记。
将标记附加到集群:
gcloud container clusters update CLUSTER_NAME \ --location=LOCATION \ --autoprovisioning-resource-manager-tags=TAG1,TAG2,...在集群上启用节点自动预配功能:
gcloud container clusters update CLUSTER_NAME \ --location=LOCATION \ --enable-autoprovisioning \ --max-cpu=MAX_CPU \ --max-memory=MAX_MEMORY
将防火墙标记附加到节点池
无论节点池是否使用节点自动预配功能,您都可以将标记附加到新节点池或现有节点池。GKE 将这些标记视为一种节点池级设置。
将标记附加到默认节点池
GKE 会将您在创建集群时使用 --resource-manager-tags 标志指定的标记附加到 GKE 在集群中创建的默认节点池。
gcloud container clusters create CLUSTER_NAME \
--location=LOCATION \
--resource-manager-tags=TAG1,TAG2,...
替换以下内容:
CLUSTER_NAME:新集群的名称LOCATION:新集群的 Compute Engine 区域或可用区TAG1,TAG2,...:要附加的一组以逗号分隔的键值对。每个键值对都必须使用受支持的语法(如“命令中的标记语法”部分中所述)。例如example-project/env=dev,1234567901/team=sre。
将标记附加到新节点池
如果创建节点池期间使用 --resource-manager-tags 标志,GKE 会将您指定的标记附加到该节点池。
gcloud container node-pools create NODE_POOL_NAME \
--cluster=CLUSTER_NAME \
--location=LOCATION \
--resource-manager-tags=TAG1,TAG2,...
替换以下内容:
NODE_POOL_NAME:新节点池的名称CLUSTER_NAME:集群的名称LOCATION:集群的 Compute Engine 区域或可用区TAG1,TAG2,...:要附加的一组以逗号分隔的键值对。每个键值对都必须使用受支持的语法(如“命令中的标记语法”部分中所述)。例如example-project/env=dev,1234567901/team=sre。
将标记附加到现有节点池
如果使用 --resource-manager-tags 标志更新现有节点池上的标记,GKE 会覆盖该节点池上的所有现有标记。您可以使用此命令更新自动预配节点池上的标记。
gcloud container node-pools update NODE_POOL_NAME \
--cluster=CLUSTER_NAME \
--location=LOCATION \
--resource-manager-tags=TAG1,TAG2,...
将 NODE_POOL_NAME 替换为要更新的节点池的名称。
切换现有集群和节点池中的自动预配设置
您在集群级上更新标记时,GKE 会将这些新标记应用于集群中的所有新节点池,并保留附加到现有节点池的标记。
更新现有节点池以启用或停用节点自动预配功能时,请考虑对标记的以下影响:
- 启用或停用节点自动预配功能时,节点池会保留所有现有标记。GKE 不会使用集群级标记覆盖这些标记,即使在重新创建节点期间也是如此。
- 如果在特定节点池上手动更新这些标记,GKE 会使用您为该节点池的指定标记覆盖现有标记。
将标记应用于具有自定义 ComputeClass 的工作负载
您可以使用自定义 ComputeClass (CCC) 将防火墙标记应用于 Autopilot 集群和使用节点自动预配 (NAP) 的 Standard 集群中的特定节点池。自定义计算类是一种资源,可用于为一组节点定义配置,包括定义要应用于节点的 Resource Manager 标记。
当您部署的工作负载请求具有特定自定义计算类标签的节点时,NAP 会先检查是否已存在符合自定义计算类的所有要求的节点池,包括指定的 Resource Manager 标记。
如果不存在匹配的节点池,NAP 会为工作负载创建一个具有指定配置的新节点池,并将标记附加到基础 Compute Engine 虚拟机。这种自动创建节点池的功能有助于确保工作负载在具有正确防火墙标记的节点上运行,以便强制执行政策。
使用标记创建自定义 ComputeClass
如需使用标记创建
ComputeClass,请将以下清单保存为my-compute-class.yaml。在resourceManagerTags字段中,指定要与使用此类创建的节点池相关联的标记键和值。apiVersion: cloud.google.com/v1 kind: ComputeClass metadata: name: COMPUTE_CLASS_NAME spec: nodePoolConfig: resourceManagerTags: - key: "PROJECT_ID/TAG_KEY_1" value: "TAG_VALUE_1" - key: "ORGANIZATION_ID/TAG_KEY_2" value: "TAG_VALUE_2" - key: "tagKeys/KEY_ID" value: "tagValues/VALUE_ID"替换以下内容:
COMPUTE_CLASS_NAME:自定义计算类的名称,例如my-custom-class。PROJECT_ID:您的 Google Cloud 项目 ID。TAG_KEY_1:第一个标记键的名称。TAG_VALUE_1:第一个标记值的名称。ORGANIZATION_ID: Google Cloud 组织数字 ID。TAG_KEY_2:第二个标记键的名称。TAG_VALUE_2:第二个标记值的名称。KEY_ID:标记键的数字 ID。VALUE_ID:标记值的数字 ID。
应用清单:
kubectl apply -f my-compute-class.yaml
如果您指定的标记无效,或者 GKE 服务代理缺少该标记所需的 IAM 权限,GKE 不会为您的工作负载预配节点池,并且工作负载会保持 Pending 状态。如需详细了解该错误,请参阅 ComputeClass 资源的 Status 字段。
如需检查状态,请运行以下命令:
kubectl get cc COMPUTE_CLASS_NAME -o jsonpath='{.status}' | jq .
将 COMPUTE_CLASS_NAME 替换为自定义计算类的名称。
在工作负载中定位自定义计算类
如需定位您创建的 ComputeClass,请将以下清单保存为
pod-with-ccc.yaml。此清单使用nodeSelector字段来定位计算类。apiVersion: v1 kind: Pod metadata: name: nginx-server spec: nodeSelector: cloud.google.com/compute-class: "COMPUTE_CLASS_NAME" containers: - name: nginx image: nginx:latest将
COMPUTE_CLASS_NAME替换为自定义计算类的名称,例如my-custom-class。应用清单:
kubectl apply -f pod-with-ccc.yaml
当您调度定位自定义计算类的工作负载时,GKE 会自动将污点应用于为该类创建的节点,并为工作负载的 Pod 添加相应的容忍设置,以便只有明确请求该类的 Pod 才会调度到这些节点上。
使用验证准入政策 (VAP) 授权工作负载
为帮助确保只有授权的工作负载才能调度到带有标记的节点池上,我们建议使用验证准入政策。此政策是一项内置的 Kubernetes 功能,可在创建或更新 Pod 的请求被持久化之前拦截这些请求。此拦截可防止未经授权的工作负载在标记的节点上运行。
如果 Pod 包含对所列计算类污点的容忍,但不在许可的命名空间中,则以下政策会拒绝 Pod 创建请求。
将以下清单保存为
restrict-toleration.yaml:应用清单:
kubectl apply -f restrict-toleration.yaml
调整验证准入政策,以满足组织的特定安全需求。
验证集群上的防火墙标
列出 Autopilot 集群上的标记:
gcloud container clusters describe CLUSTER_NAME \ --location=LOCATION \ --format="value(nodePoolAutoConfig.resourceManagerTags)"替换以下内容:
CLUSTER_NAME:集群的名称。LOCATION:集群的 Compute Engine 区域或可用区。
列出特定节点池上的标记:
此命令还会验证由自定义计算类自动预配的节点池上的标记。
gcloud container node-pools describe NODE_POOL_NAME \ --cluster=CLUSTER_NAME \ --location=LOCATION \ --format="value(config.resourceManagerTags)"替换以下内容:
NODE_POOL_NAME:节点池的名称。CLUSTER_NAME:集群的名称。LOCATION:集群的 Compute Engine 区域或可用区。
将防火墙标记从集群和节点池移除
如需从集群和节点池中移除防火墙标记,请使用这些标记的空值更新相应资源。
将标记从 Autopilot 集群移除
运行以下命令:
gcloud container clusters update CLUSTER_NAME \
--location=LOCATION \
--autoprovisioning-resource-manager-tags=
将标记从节点池移除
移除集群级节点
autoprovisioning标记:gcloud container clusters update CLUSTER_NAME \ --location=LOCATION \ --autoprovisioning-resource-manager-tags=GKE 不会将标记附加到新的自动预配节点池。
移除节点池标记:
gcloud container node-pools update NODE_POOL_NAME \ --cluster=CLUSTER_NAME \ --location=LOCATION \ --resource-manager-tags=GKE 会从该节点池中移除现有标记。
删除标记键和标记值
如需删除标记键或标记值,请确保该标记已与所有资源分离。然后,请参阅 Resource Manager 文档中的删除标记。
将网络标记与标记进行比较
与网络标记相比,使用标记强制执行防火墙政策具有明显的安全性和易用性优势。同样,网络防火墙政策可促进在整个组织、文件夹、项目或网络中强制执行防火墙规则,从而改进 VPC 防火墙规则的功能。
将标记与网络防火墙政策配合使用是一种更安全、可扩缩的方式,可用来管理整个组织中对 GKE 环境的访问权限。您可以在同一集群中使用标记和网络标记,但不能使用网络标记来强制执行网络防火墙政策。
如需查看标记和网络标记之间的详细对比,请参阅 Cloud NGFW 文档中的标记与网络标记对比。
自动预配节点池中的功能差异
在 Autopilot 集群和不使用节点自动预配的 Standard 节点池中,网络标记和标记会表现出类似的行为。下表显示了网络标记与 Standard 集群中自动预配节点池中的标记之间的功能差异:
| 操作 | 网络标记行为 | 标记行为 |
|---|---|---|
| GKE 自动预配节点池 | GKE 应用集群级网络标记 | GKE 应用集群级标记 |
| 您更新自动预配节点池上的标记或网络标记 |
|
无论集群级标记是否存在,GKE 都会覆盖节点池的现有标记 |
| 您更新整个集群的标记或网络标记 | GKE 会覆盖集群中新的和现有自动预配节点池的网络标记。 | GKE 会将新的集群级标记应用于新的自动预配节点池。现有自动预配节点池会保留更新之前具有的标记。 |