创建使用可用性区域的 Azure Kubernetes 服务 (AKS) 群集

Azure Kubernetes 服务 (AKS) 群集跨基础 Azure 基础结构的逻辑部分分配节点和存储等资源。 使用可用性区域以物理方式将节点与部署到不同可用性区域的其他节点分开。 使用在群集中配置的多个可用性区域部署的 AKS 群集可提供更高级别的可用性,以防止出现硬件失败或计划内维护事件。

通过在群集中定义跨越多个区域的节点池,即使单个区域已关闭,给定节点池中的节点也可以继续运行。 如果应用程序经协调允许节点子集故障,即使单个数据中心出现物理故障,应用程序仍可以继续运行。

本文介绍如何创建 AKS 群集,以及如何在可用性区域之间分发节点组件。

开始之前

需要安装并配置 Azure CLI 2.0.76 或更高版本。 运行 az --version 即可查找版本。 如果需要进行安装或升级,请参阅安装 Azure CLI

限制和地区可用性

AKS 群集可以在具有可用性区域的任意 Azure 区域中使用可用性区域。

  • 中国北部 3

使用可用性区域创建 AKS 群集时,以下限制适用:

  • 只能在创建群集或节点池期间定义可用性区域。
  • 创建群集后,无法将现有非可用性区域群集更新为使用可用性区域。
  • 选定的“所选节点大小 (VM SKU)”必须在所选的所有可用性区域中可用。
  • 启用了可用性区域的群集要求使用 Azure 标准负载均衡器进行跨区域分发。 只能在群集创建时定义此负载均衡器类型。 有关标准负载均衡器的详细信息和限制,请参阅 Azure 负载均衡器标准 SKU 限制

Azure 磁盘可用性区域支持

  • 使用 Azure 托管 LRS 磁盘的卷不是区域冗余资源,不支持跨区域附加。 需要在托管目标 Pod 的指定节点所在的同一区域中共定位卷。
  • 使用 Azure 托管 ZRS 磁盘(由 Azure 磁盘 CSI 驱动程序 v1.5.0 及更高版本支持)的卷是区域冗余资源。 可以在所有区域和非区域代理节点上计划这些卷。

自版本 1.12 起,Kubernetes 开始注意到 Azure 可用性区域。 可以在多区域 AKS 群集中部署引用 Azure 托管磁盘的 PersistentVolumeClaim 对象,Kubernetes 会负责计划在正确的可用性区域中声明此 PVC 的所有 Pod。

Azure 资源管理器模板和可用性区域

创建 AKS 群集时,请了解以下有关在模板中指定可用性区域的详细信息:

  • 如果你在模板中显式定义了 null 值(例如通过指定 "availabilityZones": null),则资源管理器模板会视属性为不存在。 这意味着你的群集不会部署在可用性区域中。
  • 如果你未在资源管理器模板中包含 "availabilityZones": 属性,则群集不会部署在可用性区域中。
  • 你无法更新现有群集上的可用性区域的设置,在使用资源管理器模板更新 AKS 群集时,此行为会有所不同。 如果你在模板中为可用性区域显式设置了 null 值,并更新了你的群集,则不会更新你的群集的可用性区域。 但是,如果使用 "availabilityZones": [] 之类的语法忽略可用性区域属性,则部署会尝试禁用现有 AKS 群集上的可用性区域,但会失败。

AKS 群集的可用性区域概述

可用性区域是一种高可用性产品/服务,在数据中心发生故障时可以保护应用程序和数据。 这些区域是 Azure 地区中独特的物理位置。 每个区域包含一个或多个配备了独立电源、冷却设备和网络的数据中心。 为了确保复原能力,所有已启用区域的大区域中应始终有多个区域。 数据中心发生故障时,区域中的可用性区域的物理隔离可保护应用程序和数据。

有关详细信息,请参阅 Azure 中的可用性区域是什么?

使用可用性区域部署的 AKS 群集可以在单个地区内的多个区域之间分发节点。 例如,“中国北部 3”区域中的群集可以在“中国北部 3”的所有三个可用性区域中创建节点。**** 这种 AKS 群集资源的分布可提高群集的可用性,因为它们可以在特定区域发生故障时进行恢复。

AKS node distribution across availability zones

如果单个区域不可用,你的应用程序将继续在配置为分布在多个区域的群集上运行。

注意

使用群集自动缩放程序实现可用性区域时,建议为每个区域使用一个节点池。 可以将 --balance-similar-node-groups 参数设置为 True,在纵向扩展操作期间为工作负载保持区域间的节点均衡分布。 如果不这样做,纵向缩减操作可能会破坏区域间的节点平衡。

跨可用性区域创建 AKS 群集

使用 az aks create 命令创建群集时,--zones 参数指定部署代理节点的可用性区域。 托管控制平面组件部署到的可用性区域不受此参数控制。 在群集部署期间,它们会自动分布在该区域的所有可用性区域(如果存在)中。

以下示例在名为 myResourceGroup 的资源组(具有总共三个节点)中创建了名为 myAKSCluster 的 AKS 群集。 一个代理节点在区域 1 中,一个在 2 中,还有一个在 3 中。

az group create --name myResourceGroup --location chinanorth3

az aks create \
    --resource-group myResourceGroup \
    --name myAKSCluster \
    --generate-ssh-keys \
    --vm-set-type VirtualMachineScaleSets \
    --load-balancer-sku standard \
    --node-count 3 \
    --zones 1 2 3

创建 AKS 群集需要几分钟时间。

确定新节点所属的区域时,指定的 AKS 节点池会使用由基础 Azure 虚拟机规模集提供的最佳区域均衡。 如果每个区域中的 VM 数相同或与规模集的所有其他区域中的 VM 数只相差 +- 1,则认为该 AKS 节点池“已实现均衡”。

验证跨区域的节点分布

群集准备就绪后,请列出规模集中的代理节点所在的可用性区域。

首先,使用 az aks get-credentials 命令获取 AKS 群集凭据:

az aks get-credentials --resource-group myResourceGroup --name myAKSCluster

接下来,使用 kubectl describe 命令来列出群集中的节点并按 topology.kubernetes.io/zone 值进行筛选。 下面是 Bash shell 示例。

kubectl describe nodes | grep -e "Name:" -e "topology.kubernetes.io/zone"

以下示例输出显示了在指定地区和可用性区域之间分布的三个节点,如第一个可用性区域的 chinanorth3-1 和第二个可用性区域的 chinanorth3-2:

Name:       aks-nodepool1-28993262-vmss000000
            topology.kubernetes.io/zone=chinanorth3-1
Name:       aks-nodepool1-28993262-vmss000001
            topology.kubernetes.io/zone=chinanorth3-2
Name:       aks-nodepool1-28993262-vmss000002
            topology.kubernetes.io/zone=chinanorth3-3

向代理池添加更多节点时,Azure 平台会自动在指定的可用性区域内分发基础 VM。

在 Kubernetes 版本 1.17.0 及更高版本中,AKS 使用较新的标签 topology.kubernetes.io/zone 和已弃用的 failure-domain.beta.kubernetes.io/zone。 通过运行以下脚本,你可以获得运行上一步中的 kubelet describe nodes 命令的相同结果:

kubectl get nodes -o custom-columns=NAME:'{.metadata.name}',REGION:'{.metadata.labels.topology\.kubernetes\.io/region}',ZONE:'{metadata.labels.topology\.kubernetes\.io/zone}'

以下示例类似于具有更详细信息的输出:

NAME                                REGION   ZONE
aks-nodepool1-34917322-vmss000000   chinanorth3   chinanorth3-1
aks-nodepool1-34917322-vmss000001   chinanorth3   chinanorth3-2
aks-nodepool1-34917322-vmss000002   chinanorth3   chinanorth3-3

验证跨区域的 pod 分布

已知标签、注释和排斥中所述,Kubernetes 使用 topology.kubernetes.io/zone 标签在可用的不同区域中自动分发复制控制器或服务中的 pod。 若要测试标签并将你的群集从 3 个节点扩展到 5 个节点,请运行以下命令以验证 Pod 是否正确分布:

az aks scale \
    --resource-group myResourceGroup \
    --name myAKSCluster \
    --node-count 5

几分钟后缩放操作完成时,在 Bash shell 中运行命令 kubectl describe nodes | grep -e "Name:" -e "topology.kubernetes.io/zone"。 以下输出类似于结果:

Name:       aks-nodepool1-28993262-vmss000000
            topology.kubernetes.io/zone=chinanorth3-1
Name:       aks-nodepool1-28993262-vmss000001
            topology.kubernetes.io/zone=chinanorth3-2
Name:       aks-nodepool1-28993262-vmss000002
            topology.kubernetes.io/zone=chinanorth3-3
Name:       aks-nodepool1-28993262-vmss000003
            topology.kubernetes.io/zone=chinanorth3-1
Name:       aks-nodepool1-28993262-vmss000004
            topology.kubernetes.io/zone=chinanorth3-2

现在,区域 1 和 2 中多了两个节点。 你可以部署包含三个副本的应用程序。 下面的示例使用 NGINX:

kubectl create deployment nginx --image=mcr.azk8s.cn/oss/nginx/nginx:1.15.5-alpine
kubectl scale deployment nginx --replicas=3

通过查看运行 pod 的节点,可以看到 pod 在与三个不同的可用性区域相对应的节点上运行。 例如,在 Bash shell 中使用命令 kubectl describe pod | grep -e "^Name:" -e "^Node:" 时,会看到以下示例输出:

Name:         nginx-6db489d4b7-ktdwg
Node:         aks-nodepool1-28993262-vmss000000/10.240.0.4
Name:         nginx-6db489d4b7-v7zvj
Node:         aks-nodepool1-28993262-vmss000002/10.240.0.6
Name:         nginx-6db489d4b7-xz6wj
Node:         aks-nodepool1-28993262-vmss000004/10.240.0.8

从前面的输出中可以看到,第一个 pod 在节点 0 上运行,该节点位于可用性区域 chinanorth3-1 中。 第二个 pod 在节点 2 上运行(对应 chinanorth3-3),第三个 pod 在 chinanorth3-2 的节点 4 上运行。 如果没有任何其他配置,Kubernetes 会在所有三个可用性区域中正确分配 pod。

后续步骤

本文介绍了如何使用可用性区域创建 AKS 群集。 有关高可用性群集的更多注意事项,请参阅 AKS 中业务连续性和灾难恢复的最佳做法