本文档介绍了如何在 Google Distributed Cloud (GDC) air-gapped 中通过在专用节点池内隔离容器工作负载来增强 Kubernetes 集群的安全性和管理能力。隔离工作负载可让您更好地控制 Pod,并降低 Kubernetes 集群中发生提权攻击的风险。如需详细了解专用节点池的优势和限制,请参阅节点隔离概览。
隔离容器工作负载涉及多个工作流程,包括:
为节点池添加污点和标签:为节点池添加污点和标签,以便将 pod 排斥在该节点池之外,除非这些 pod 专门标记为在该节点池中运行。
添加容忍和节点亲和性规则:将容忍和规则应用于您的 pod,以强制它们仅在指定的节点池池上运行。
验证分离是否有效:确认带有污点的节点池仅运行您标记为在该节点池中运行的 pod。
这些工作流适用于平台管理员群组中的 IT 管理员(负责管理 Kubernetes 集群的节点池)和应用运营者群组中的应用开发者(负责管理容器工作负载)等受众群体。如需了解详情,请参阅 GDC 气隙环境文档的受众群体。
准备工作
在开始之前,请确保您已执行以下任务:
为您想要用于专用节点池的节点污点和节点标签选择特定名称。例如
workloadType=untrusted
。如有必要,请让组织 IAM 管理员为您授予未绑定到命名空间的 User Cluster Developer 角色 (
user-cluster-developer
)。
为新节点池添加污点和标签
向新节点池应用污点或标签时,所有节点(包括稍后添加的任何节点)都将自动获取指定的污点和标签。
如需向新节点池添加污点和标签,请完成以下步骤:
在创建节点池时,直接修改
Cluster
自定义资源的nodePools
部分:nodePools: # Several lines of code are omitted here. - machineTypeName: n2-standard-2-gdc name: nodepool-1 nodeCount: 3 taints: - key: "TAINT_KEY" value: "TAINT_VALUE" effect: "TAINT_EFFECT" labels: LABEL_KEY: LABEL_VALUE
替换以下内容:
TAINT_KEY
:与调度TAINT_EFFECT
关联的键值对的污点键部分。例如workloadType
。TAINT_VALUE
:与调度TAINT_EFFECT
关联的键值对的污点值部分。例如untrusted
。TAINT_EFFECT
:以下效果值之一:NoSchedule
:不能容忍此污点的 pod 不会被调度到节点上;现有 pod 不会从节点中逐出。PreferNoSchedule
:Kubernetes 会尽量避免将不能容忍此污点的 Pod 调度到节点上。NoExecute
:如果 Pod 已在节点上运行,则该 Pod 会从节点中被逐出;如果尚未在节点上运行,则不会被调度到节点上。
LABEL_KEY: LABEL_VALUE
:节点标签的键值对,与您在工作负载清单中指定的选择器对应。
应用
Cluster
资源以创建新的节点池:kubectl apply -f cluster.yaml --kubeconfig MANAGEMENT_API_SERVER
将
MANAGEMENT_API_SERVER
替换为托管 Kubernetes 集群的区域 API 服务器的 kubeconfig 路径。如果您尚未为目标可用区中的 API 服务器生成 kubeconfig 文件,请参阅可用区级管理 API 服务器资源了解详情。
为现有节点池添加污点和标签
如需将污点或标签应用于现有节点池,您必须将更改应用于每个现有节点。您无法动态更新节点池配置。
如需向现有节点池添加污点和标签,请完成以下步骤:
列出专用节点池中的节点:
kubectl get node --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG \ -l baremetal.cluster.gke.io/node-pool=NODE_POOL_NAME
执行以下变量替换操作:
KUBERNETES_CLUSTER_KUBECONFIG
:Kubernetes 集群的 kubeconfig 路径。NODE_POOL_NAME
:专用节点池的名称。
记下输出中节点池中所有节点的每个节点 ID。
对于节点池中的每个节点,应用以下污点:
kubectl taint nodes NODE_ID \ TAINT_KEY=TAINT_VALUE:TAINT_EFFECT \ --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG
执行以下变量替换操作:
NODE_ID
:专用节点池中工作器节点的 ID。TAINT_KEY=TAINT_VALUE
:与调度TAINT_EFFECT
关联的键值对。例如workloadType=untrusted
。TAINT_EFFECT
:以下效果值之一:NoSchedule
:不能容忍此污点的 pod 不会被调度到节点上;现有 pod 不会从节点中逐出。PreferNoSchedule
:Kubernetes 会尽量避免将不能容忍此污点的 Pod 调度到节点上。NoExecute
:如果 Pod 已在节点上运行,则该 Pod 会从节点中被逐出;如果尚未在节点上运行,则不会被调度到节点上。
KUBERNETES_CLUSTER_KUBECONFIG
:Kubernetes 集群的 kubeconfig 路径。
对于节点池中的每个节点,应用与您将在容器工作负载中定义的节点选择器对应的标签:
kubectl label NODE_ID \ LABEL_KEY:LABEL_VALUE \ --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG
执行以下变量替换操作:
NODE_ID
:专用节点池中工作器节点的 ID。LABEL_KEY:LABEL_VALUE
:节点标签的键值对,与您在工作负载清单中指定的选择器对应。KUBERNETES_CLUSTER_KUBECONFIG
:Kubernetes 集群的 kubeconfig 路径。
添加容忍和节点亲和性规则
污染专用节点池后,任何工作负载都无法在其上调度,除非它们具有与您添加的污染相对应的容忍度。将容忍度添加到您的工作负载规范中,让这些 Pod 在您的受污染节点池调度。
如果您已为专用节点池添加标签,则还可以添加节点亲和性规则,以指示 GDC 仅在该节点池上调度工作负载。
如需配置容器工作负载以在专用节点池中运行,请完成以下步骤:
将以下部分添加到容器工作负载清单文件(例如
Deployment
自定义资源)的.spec.template.spec
部分:# Several lines of code are omitted here. spec: template: spec: tolerations: - key: TAINT_KEY operator: Equal value: TAINT_VALUE effect: TAINT_EFFECT affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: LABEL_KEY operator: In values: - "LABEL_VALUE" # Several lines of code are omitted here.
替换以下内容:
TAINT_KEY
:您应用于专用节点池的污点键。TAINT_VALUE
:您应用于专用节点池的污点值。TAINT_EFFECT
:以下效果值之一:NoSchedule
:不能容忍此污点的 pod 不会被调度到节点上;现有 pod 不会从节点中逐出。PreferNoSchedule
:Kubernetes 会尽量避免将不能容忍此污点的 Pod 调度到节点上。NoExecute
:如果 Pod 已在节点上运行,则该 Pod 会从节点中被逐出;如果尚未在节点上运行,则不会被调度到节点上。
LABEL_KEY
:您应用于专用节点池的节点标签键。LABEL_VALUE
:您应用于专用节点池的节点标签值。
例如,以下
Deployment
资源为workloadType=untrusted:NoExecute
污点添加容忍设置,并为workloadType=untrusted
节点标签添加节点亲和性规则:kind: Deployment apiVersion: apps/v1 metadata: name: my-app namespace: default labels: app: my-app spec: replicas: 1 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: tolerations: - key: workloadType operator: Equal value: untrusted effect: NoExecute affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: workloadType operator: In values: - "untrusted" containers: - name: my-app image: harbor-1.org-1.zone1.google.gdc.test/harborproject/my-app ports: - containerPort: 80 imagePullSecrets: - name: SECRET
更新容器工作负载:
kubectl apply -f deployment.yaml -n NAMESPACE \ --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG
执行以下变量替换操作:
NAMESPACE
:容器工作负载的项目命名空间。KUBERNETES_CLUSTER_KUBECONFIG
:Kubernetes 集群的 kubeconfig 路径。
GDC 会重新创建受影响的 pod。节点亲和性规则强制 Pod 推送到您创建的专用节点池。容忍设置仅允许将这些 Pod 放置在节点上。
验证分离是否有效
验证您指定的 pod 是否在带有标签的节点池中运行。
列出指定命名空间中的 Pod:
kubectl get pods -o=wide -n NAMESPACE \ --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG
执行以下变量替换操作:
NAMESPACE
:容器工作负载的项目命名空间。KUBERNETES_CLUSTER_KUBECONFIG
:Kubernetes 集群的 kubeconfig 路径。
输出类似于以下内容:
pod/kube-abc-12tyuj pod/kube-abc-39oplef pod/kube-abc-95rzkap
确认工作负载是否在专用节点池中运行。