4. 使用IaC创建生产级AKS集群
用门户点选创建 AKS 只能算“跑通”,生产级集群必须做到可重复、可审计、可回滚。IaC 的价值不在于把点击换成代码,而在于把集群的每一个决策——网络模型、节点池规格、可用区分布、标签体系、状态存放位置——都固化成可评审的声明。本节以 Terraform 为主线,Bicep 作为对照,讲清模块化设计、节点池与可用区、标签与资源组策略、状态管理与 CI 集成这五件事如何落到一份能真正上生产的代码里。
一、模块化设计:把“集群”拆成可复用的三层
生产级 AKS 的 Terraform 代码不应是一个几百行的 main.tf,而应按职责分层。推荐三层结构:基础层负责资源组、Log Analytics 工作区、容器注册表(ACR)、虚拟网络与子网;集群层负责 AKS 本身与系统节点池;工作负载层负责业务节点池、ACR 拉取角色分配、诊断设置。三层之间通过模块输出(output)传递 ID,而不是硬编码名称。
模块的输入变量要收敛到真正需要按环境变化的参数,例如 environment、location、kubernetes_version、node_pools、tags。凡是“所有环境都一样”的值应写成模块内默认值,避免变量爆炸。下面是一个集群层模块调用的骨架示例:
module "aks" {
source = "./modules/aks-cluster"
cluster_name = "aks-prod-eastus"
resource_group_name = module.base.rg_name
location = "eastus"
kubernetes_version = "1.29"
subnet_id = module.base.aks_subnet_id
log_analytics_id = module.base.log_analytics_id
system_node_pool = {
vm_size = "Standard_D4s_v5"
min_count = 3
max_count = 6
zones = ["1", "2", "3"]
}
tags = local.common_tags
}
Bicep 的模块化思路一致,用 module 引用 br/public:avm/res/container-service/managed-cluster 这类已验证模块,参数以对象形式传入。两者取舍:Terraform 生态成熟、状态与 plan 机制清晰,适合多云与复杂依赖;Bicep 与 ARM 原生贴合、无需管理状态文件,适合纯 Azure 团队。生产上不建议同一集群混用两套 IaC 管理,否则会出现“谁覆盖谁”的漂移。
二、节点池配置:系统池与业务池必须分开
AKS 默认只给一个节点池,生产环境必须显式拆分。系统节点池只跑 CoreDNS、metrics-server、CSI 驱动等关键组件,业务节点池按负载特征划分。关键参数包括:vm_size、min_count/max_count、os_disk_size_gb、max_pods、node_labels、node_taints、mode。
一个常见的生产配置是:系统池 3 节点、Standard_D4s_v5、开启自动伸缩 3–6;通用业务池 3–20 节点、Standard_D8s_v5;内存密集型池用 Standard_E8s_v5 并打上 workload=memory 标签与 sku=memory:NoSchedule 污点,让业务通过 nodeSelector 与 toleration 精确调度。系统池必须设置 only_critical_addons_enabled = true(或等价参数),防止业务 Pod 抢占系统资源。
max_pods 与子网容量强相关。Azure CNI 下每个 Pod 占一个 IP,若子网为 /24(约 251 个可用 IP),单池 20 节点 × 30 Pod 就会耗尽。规划时按“节点数 × max_pods + 预留”反推子网大小,或改用 Azure CNI Overlay 降低 IP 消耗。三、可用区与多区域部署
可用区决定单区域内的高可用,多区域决定区域级容灾,两者不是一回事。生产集群的系统节点池应跨三个可用区(zones = ["1","2","3"]),业务池至少跨两个。注意:可用区在集群创建时确定,节点池创建后无法追加可用区,只能新建节点池迁移。
多区域部署有三种典型形态:主动-主动(两个区域各一套 AKS,前置 Front Door 或 Traffic Manager 分流,数据层做异地复制);主动-被动(主区域承载流量,备区域集群常驻但缩容到最小,故障时扩容接管);成对区域(利用 Azure 区域对,如 East US / West US,享受平台级更新顺序与复制优先)。选择依据是 RTO/RPO 与成本:主动-主动成本约两倍但 RTO 接近分钟级,主动-被动成本可控但切换需验证扩容速度与镜像预热。
四、标签与资源组策略
标签是成本分摊、自动化运维和合规审计的基础。生产集群至少应统一以下标签:environment(prod/staging)、owner、cost-center、managed-by(terraform)、data-classification。在 Terraform 中用 locals 定义 common_tags 并合并到每个资源,避免逐个手写。
资源组策略上,推荐“按生命周期分组”而非“按类型分组”:AKS 集群、节点池、ACR、Log Analytics 放在同一资源组,因为它们同生共死;网络与共享服务(如 Hub VNet、防火墙)放在独立资源组,由平台团队管理。这样销毁一套环境时只需删除一个资源组,不会误伤共享网络。同时用 Azure Policy 强制要求资源组必须带 environment 标签,未打标签的部署直接拒绝。
五、状态管理与 CI 集成
Terraform 状态文件是生产 IaC 的生命线。必须使用远程后端,推荐 Azure Storage Account + Blob 容器,并开启版本控制与软删除。状态文件按环境隔离:prod.tfstate、staging.tfstate 分不同 key,避免一次 plan 影响所有环境。后端配置示例:
terraform {
backend "azurerm" {
resource_group_name = "rg-tfstate"
storage_account_name = "sttfstateprod001"
container_name = "tfstate"
key = "aks/prod.tfstate"
}
}
CI 集成推荐“PR 阶段 plan、合并后 apply”的两段式流水线。PR 触发 terraform fmt -check、terraform validate、terraform plan,plan 结果作为评论贴回 PR 供评审;合并到 main 后触发 terraform apply -auto-approve。凭据使用 OIDC 联邦身份而非长期密钥,GitHub Actions 或 Azure DevOps 通过 azure/login 获取短期令牌。apply 后追加一步 az aks get-credentials 与 kubectl get nodes,确认集群真实可达,而不是只看 Terraform 返回成功。
最后,IaC 不是一次性交付。集群创建后要定期执行 terraform plan 检测漂移——如果有人通过门户改了节点池,plan 会显示差异。把漂移检测纳入每日定时流水线,发现差异即告警,才能保证“代码即真相”长期成立。