Terraform AWS EKS Blueprints 常见问题深度解析
前言
在使用 Terraform AWS EKS Blueprints 进行 Kubernetes 集群部署时,开发者可能会遇到一些典型问题。本文将从技术原理和最佳实践角度,深入分析这些常见问题的成因和解决方案,帮助用户更顺畅地使用该蓝图项目。
一、环境销毁时的超时问题
问题现象
在执行 terraform destroy
命令删除环境时,VPC 删除操作经常会出现超时错误。
根本原因
这个问题源于 VPC CNI 组件的一个已知行为:当 EKS 托管节点(或自管理节点)上的 ENI(弹性网络接口)未被 VPC CNI 按预期删除时,会导致:
- ENI 残留在子网中
- 附加到 ENI 的 EKS 托管安全组无法被 EKS 删除
推荐解决方案
按照以下顺序执行清理操作:
- 删除集群中的所有 Pod:确保没有工作负载正在使用网络资源
- 添加延迟/等待:给系统足够时间完成资源释放
- 删除 VPC CNI:移除网络插件组件
- 删除节点:清理计算资源
- 删除集群:最后删除 EKS 集群本身
这种顺序化操作可以避免资源依赖导致的删除失败。
二、CloudWatch 日志组残留问题
问题背景
在执行 terraform destroy
后,EKS 集群的 CloudWatch 日志组有时会残留。这是因为:
- 即使 Terraform 删除了日志组,AWS EKS 服务后台仍在处理日志
- EKS 服务会使用其服务 IAM 角色重新创建日志组继续写入日志
- 当重新部署相同蓝图时,会因日志组已存在而失败
解决方案对比
方案一:让 EKS 服务管理日志组
- 设置
create_cloudwatch_log_group = false
- 优点:避免 Terraform 重建时的冲突
- 缺点:日志组不会被自动清理,需要手动删除
方案二:由 Terraform 管理日志组
- 设置
create_cloudwatch_log_group = true
- 优点:符合基础设施即代码原则
- 缺点:可能仍需手动干预删除残留日志组
操作建议
对于生产环境,建议采用方案二并结合自动化清理脚本。对于临时测试环境,方案一更为简便。
三、Provider 认证机制详解
认证流程背景
蓝图部署通常分为三个阶段:
- VPC 创建
- EKS 集群部署
- 插件和清单配置
两种认证方法对比
1. 静态令牌认证
特点:
- 令牌有效期为15分钟
- 简单易用,无需额外依赖
- 过期后需执行
terraform refresh
更新令牌
适用场景:
- 快速原型开发
- 自动化流水线中短期运行的任务
2. exec() 动态认证
特点:
- 实时获取令牌
- 需要本地安装 awscli 并保持最新版本
- 支持更安全的认证流程
适用场景:
- 长期运行的开发环境
- 需要更高安全性的生产环境
配置示例
静态令牌配置要点
provider "kubernetes" {
token = data.aws_eks_cluster_auth.this.token
# 其他配置...
}
exec() 动态认证配置要点
provider "kubernetes" {
exec {
api_version = "client.authentication.k8s.io/v1beta1"
command = "aws"
args = ["eks", "get-token", "--cluster-name", module.eks.cluster_name]
}
# 其他配置...
}
版本兼容性提示
使用 exec() 方法时,务必确保:
- awscli 版本支持所需的认证 API 版本
- 执行 Terraform 的环境已正确配置 AWS 凭证
四、Terraform 无法删除命名空间问题
问题成因
当通过 Terraform 删除 Kubernetes 资源(如命名空间)时,可能会遇到超时错误。这通常是因为:
- 由插件(如 ArgoCD、AWS LBC 等)通过 CRD 创建的资源未被完全清理
- 资源上的 finalizers 阻止了删除操作
排查与解决步骤
-
检查命名空间状态:
kubectl get namespaces
-
查找残留资源(替换
<namespace_name>
):kubectl api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl get --show-kind --ignore-not-found -n <namespace_name>
-
清理 finalizers:
kubectl patch <RESOURCE> <NAME> -p '{"metadata":{"finalizers":[]}}' --type=merge
-
必要时清理命名空间 finalizer:
kubectl patch ns <ns-name> -p '{"spec":{"finalizers":null}}'
预防建议
在删除集群前,建议:
- 先手动删除所有插件
- 确认所有自定义资源已被清理
- 检查并清理所有 finalizers
最佳实践总结
- 资源删除顺序:遵循从内到外的删除原则,先工作负载后基础设施
- 日志管理:根据环境类型选择合适的日志组管理策略
- 认证选择:开发环境可用静态令牌,生产环境推荐 exec() 动态认证
- 命名空间清理:建立预删除检查清单,确保资源完全释放
通过理解这些常见问题背后的原理和掌握相应的解决方案,开发者可以更高效地使用 Terraform AWS EKS Blueprints 部署和管理 Kubernetes 集群。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考