停止手动管理 EKS Add-ons
Source: Dev.to
Originally published on graycloudarch.com.
问题
我正准备将生产环境的 EKS 集群升级到 v1.32,却发现四个核心插件的版本 不兼容 新的 EKS 发行版:
| 插件 | 安装模式 | 当前版本 | 问题 |
|---|---|---|---|
| VPC CNI | 自行管理(自动安装) | ❌ | 不兼容 |
| CoreDNS | 自行管理(自动安装) | ❌ | 不兼容 |
| kube‑proxy | 自行管理(自动安装) | ❌ | 不兼容 |
| Metrics Server | 通过 kubectl apply -f 安装 | ❌ | 不兼容 |
没有 版本锁定,没有变更历史,也没有安全测试升级的方法。于是我决定不再手动管理 EKS 插件。
两类 EKS 插件
| 类别 | 谁管理? | 你得到的 |
|---|---|---|
| 自管 | 你 – 你负责安装、更新并确保兼容性。AWS 不会帮助排查。 | 完全控制,但必须在每个 EKS 发行版上手动验证兼容性。 |
| EKS‑受管 | AWS – 生命周期、版本兼容性、安全补丁和支持由 AWS 处理。 | 升级更简便;AWS 为每个 EKS 发行版发布兼容版本。 |
如果你在创建集群时没有显式启用受管插件,VPC CNI、CoreDNS 和 kube‑proxy 目前是自管的。
解决办法很直接:将它们迁移到 EKS‑受管。
然而,Metrics Server 是通过普通 kubectl 安装的资源,未被任何管理。
Source: …
一个 Terraform 模块管理所有插件
我构建了一个名为 eks-addons 的 Terraform 模块,将所有内容集中管理。
由 AWS 管理(EKS‑managed)
| 插件 | 用途 |
|---|---|
| VPC CNI | Pod 网络 |
| EBS CSI Driver | 持久卷(顺手一起加的) |
| CoreDNS | DNS 解析 |
| kube‑proxy | 网络代理 |
由 Helm 管理(Helm‑managed)
| 插件 | 用途 |
|---|---|
| Metrics Server | 为 kubectl top 和 HPA 提供资源指标 |
| Reloader | 当 ConfigMap 或 Secret 变更时自动重启 Pod |
为什么使用单一模块?
所有插件共享同一个依赖——EKS 集群。将它们合并意味着:
- 一次
terragrunt apply部署全部。- 一次
terraform plan即可查看所有插件的漂移情况。- 一个 PR 即可更新任意版本。
Core Terraform for an EKS‑managed add‑on
resource "aws_eks_addon" "vpc_cni" {
count = var.enable_vpc_cni ? 1 : 0
cluster_name = var.cluster_name
addon_name = "vpc-cni"
addon_version = var.vpc_cni_version
resolve_conflicts_on_create = "OVERWRITE"
resolve_conflicts_on_update = "OVERWRITE"
preserve = true
}Two important flags
resolve_conflicts = "OVERWRITE"– Terraform 是唯一的真实来源;集群中任何手动更改都会在下次 apply 时被覆盖。preserve = true– 如果资源从 Terraform 中移除,插件 仍会保留 在集群中。这在重构期间充当安全网。
EBS CSI 驱动程序 – 额外的 IAM 工作
EBS CSI 驱动程序需要 IAM 权限来创建/挂载 EBS 卷。推荐的做法是 IRSA(IAM Roles for Service Accounts)。
# IAM role for the driver
resource "aws_iam_role" "ebs_csi" {
count = var.enable_ebs_csi ? 1 : 0
name = "${var.cluster_name}-ebs-csi-driver"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { Federated = var.oidc_provider_arn }
Action = "sts:AssumeRoleWithWebIdentity"
Condition = {
StringEquals = {
"${var.oidc_provider}:sub" = "system:serviceaccount:kube-system:ebs-csi-controller-sa"
"${var.oidc_provider}:aud" = "sts.amazonaws.com"
}
}
}]
})
}# Attach the AWS‑managed policy
resource "aws_iam_role_policy_attachment" "ebs_csi" {
count = var.enable_ebs_csi ? 1 : 0
role = aws_iam_role.ebs_csi[0].name
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy"
}Pod 中不使用凭证,自动轮换,并在 CloudTrail 中留下干净的审计记录。
IRSA 是任何需要在 Kubernetes 内部调用 AWS API 的 AWS 服务的正确模式。
迁移 Metrics Server
1️⃣ 删除现有的 kubectl‑安装的资源
kubectl delete deployment metrics-server -n kube-system
kubectl delete service metrics-server -n kube-system
kubectl delete apiservice v1beta1.metrics.k8s.io2️⃣ 通过 Terraform 安装 Helm‑管理的版本
resource "helm_release" "metrics_server" {
count = var.enable_metrics_server ? 1 : 0
name = "metrics-server"
repository = "https://kubernetes-sigs.github.io/metrics-server/"
chart = "metrics-server"
version = var.metrics_server_chart_version
namespace = "kube-system"
values = [yamlencode({
replicas = 2
args = [
"--kubelet-preferred-address-types=InternalIP",
"--kubelet-insecure-tls"
]
podDisruptionBudget = {
enabled = true
minAvailable = 1
}
})]
}预期停机时间: 2‑3 分钟(仅 kubectl top 不可用)。运行中的应用不受影响。
CI/CD 小陷阱
我们的 GitHub Actions 工作流会查找 已修改的 terragrunt.hcl 文件 来决定部署哪些堆栈。当我修改 common/modules/eks-addons/ 下的文件时,工作流被触发但没有发现 任何堆栈(没有 terragrunt.hcl 变更),于是没有执行任何操作。
解决方案:手动部署模块更改。
cd workloads-nonprod/us-east-1/cluster-name/eks-addons
terragrunt init
terragrunt plan # Should show ~10 resources to add
terragrunt apply验证一切健康
# Check EKS‑managed add‑on status
for addon in vpc-cni aws-ebs-csi-driver coredns kube-proxy; do
aws eks describe-addon \
--cluster-name <cluster-name> \
--addon-name $addon \
--query "addon.status" \
--output text
done您应该看到每个插件的状态为 ACTIVE。
Source: …
要点
- Self‑managed add‑ons 需要您自行跟踪版本、兼容性和安全补丁。
- EKS‑managed add‑ons 让 AWS 负责生命周期管理,使您在升级时更有信心。
- 将所有 add‑ons(AWS‑managed、Helm‑managed 和自定义)整合到 单一 Terraform 模块 中,可简化漂移检测、版本升级和 CI/CD 集成。
现在可以在没有之前 add‑on 兼容性麻烦的情况下,将集群升级到 EKS 1.32。
kubectl top nodes之前
- 四个以 self‑managed 模式运行的 add‑ons
- 一个通过
kubectl安装的 add‑on - 没有版本历史记录
- 没有漂移检测
之后
- 所有六个 add‑ons 均在代码中定义,并 固定版本
terraform plan能立即显示任何与声明状态不符的漂移- 回滚只需 git revert + terragrunt apply
EKS 集群升级检查清单
- 更新 Terragrunt 配置中的四个版本字符串。
- 打开 PR。
- 合并 —— 升级会自动应用。
我原本担心的集群升级只用了 30 分钟,而不是整整一天的手动兼容性检查。
遇到 EKS 附加组件管理问题?请联系——这正是我为平台团队提供的运维工作。