本页面介绍如何指示 Google Kubernetes Engine (GKE) 使用可用区拓扑在特定 Google Cloud 可用区的节点上运行 Pod。此类放置在以下情况下非常有用:
- Pod 必须访问存储在可用区级 Compute Engine 永久性磁盘中的数据。
- Pod 必须与其他可用区级资源(例如 Cloud SQL 实例)一起运行。
您还可以将可用区放置与拓扑感知流量路由结合使用,以缩短客户端和工作负载之间的延迟时间。如需详细了解拓扑感知流量路由,请参阅拓扑感知路由。
使用可用区拓扑控制 Pod 位置是一种高级 Kubernetes 机制,您应该仅在需要 Pod 在特定可用区运行时才使用这种机制。在大多数生产环境中,我们建议您尽可能使用区域级资源(即 GKE 默认值)。
可用区放置方法
可用区拓扑内置于 Kubernetes 中,带有 topology.kubernetes.io/zone: ZONE
节点标签。如需指示 GKE 将 Pod 放置在特定可用区中,请使用以下任一方法:
- nodeAffinity:在 Pod 规范中为一个或多个 Google Cloud 可用区指定 nodeAffinity 规则。此方法比 nodeSelector 更灵活,因为它让您可以将 Pod 放置在多个可用区中。
- nodeSelector:在 Pod 规范中为单个 Google Cloud 可用区指定 nodeSelector。
注意事项
使用可用区拓扑的可用区级 Pod 放置存在以下注意事项:
- 集群必须与请求的可用区位于同一 Google Cloud 区域中。
- 在 Standard 集群中,您必须使用节点自动预配功能,或在请求的可用区中创建具有节点的节点池。Autopilot 集群会自动为您管理此过程。
- Standard 集群必须是区域级集群。
价格
可用区拓扑是一种 Kubernetes 调度功能,在 GKE 中免费提供。
如需详细了解价格,请参阅 GKE 价格。
准备工作
在开始之前,请确保您已执行以下任务:
- 启用 Google Kubernetes Engine API。 启用 Google Kubernetes Engine API
- 如果您要使用 Google Cloud CLI 执行此任务,请安装并初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请运行
gcloud components update
以获取最新版本。
- 确保现有 GKE 集群与要放置 Pod 的可用区位于同一 Google Cloud 区域中。如需创建新集群,请参阅创建 Autopilot 集群。
使用 nodeAffinity 将 Pod 放置在多个可用区中
Kubernetes nodeAffinity 提供灵活的调度控制机制,支持多个标签选择器和逻辑运算符。若要让 Pod 在一组可用区中的其中一个可用区运行(例如在 us-central1-a
或 us-central1-f
中),请使用 nodeAffinity。
将以下清单保存为
multi-zone-affinity.yaml
:apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 3 selector: matchLabels: app: nginx-multi-zone template: metadata: labels: app: nginx-multi-zone spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: topology.kubernetes.io/zone operator: In values: - us-central1-a - us-central1-f
此清单会创建一个具有三个副本的 Deployment,并根据节点可用性将 Pod 放置在
us-central1-a
或us-central1-f
中。确保您的集群位于
us-central1
区域。如果您的集群位于其他区域,请将清单值字段中的可用区更改为集群区域中的有效可用区。创建 Deployment:
kubectl create -f multi-zone-affinity.yaml
GKE 会在其中一个指定可用区的节点中创建 Pod。多个 Pod 可能在同一节点上运行。您可以选择使用 Pod 反亲和性,指示 GKE 将每个 Pod 放在单独的节点上。
使用 nodeSelector 将 Pod 放置在单个可用区中
如需将 Pod 放在单个可用区中,请在 Pod 规范中使用 nodeSelector。nodeSelector 等效于指定了单个可用区的 requiredDuringSchedulingIgnoredDuringExecution
nodeAffinity 规则。
将以下清单保存为
single-zone-selector.yaml
:apiVersion: apps/v1 kind: Deployment metadata: name: nginx-singlezone spec: replicas: 3 selector: matchLabels: app: nginx-singlezone template: metadata: labels: app: nginx-singlezone spec: nodeSelector: topology.kubernetes.io/zone: "us-central1-a" containers: - name: nginx image: nginx:latest ports: - containerPort: 80
此清单指示 GKE 将 Deployment 中的所有副本放在
us-central1-a
可用区中。创建 Deployment:
kubectl create -f single-zone-selector.yaml
验证 Pod 位置
如需验证 Pod 位置,请列出 Pod 并检查节点标签。多个 Pod 可能会在单个节点中运行,因此,如果您使用 nodeAffinity,可能看不到分布在多个可用区中的 Pod。
列出 Pod:
kubectl get pods -o wide
输出是正在运行的 Pod 和相应的 GKE 节点的列表。
描述节点:
kubectl describe node NODE_NAME | grep "topology.kubernetes.io/zone"
将
NODE_NAME
替换为该节点的名称。输出类似于以下内容:
topology.kubernetes.io/zone: us-central1-a
如果您希望 GKE 在多个可用区中均匀分布 Pod,以改善多个故障域的故障切换,请使用 topologySpreadConstraints。