Terraform eks_blueprints_addons部署AWS EBS CSI Driver权限异常排查
我通过Terraform使用eks_blueprints_addons部署了AWS EBS CSI Driver插件,确认驱动已在kube-system命名空间中创建,但部署带有PVC的应用时出现如下错误:
Warning ProvisioningFailed 113s (x2 over 4m53s) ebs.csi.aws.com_ebs-csi-controller-c4bc5f559-k6fqp_5a4ed8cc-0085-4875-8070-87fceda36abf (combined from similar events): failed to provision volume with StorageClass "standard": rpc error: code = Internal desc = Could not create volume "pvc-f8f034de-5f7b-4ca6-bb0c-0c3e4be8026d": could not create volume in EC2: operation error EC2: CreateVolume, https response error StatusCode: 403, RequestID: 0d5d6201-4115-4cd9-bc99-201331b97450, api error UnauthorizedOperation: You are not authorized to perform this operation. User: arn:aws:sts::111111111111:assumed-role/default-eks-node-group-2024071204291580710000000e/i-075c478df65c9bd58 is not authorized to perform: ec2:CreateVolume on resource: arn:aws:ec2:ap-northeast-1:111111111111:volume/* because no identity-based policy allows the ec2:CreateVolume action
从错误日志看,当前使用的是EKS节点组角色,我尝试创建IRSA角色并关联到驱动插件,Terraform代码如下:
module "ebs_csi_driver_irsa" { source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks" version = "~> 5.20" role_name_prefix = "ebs-csi-driver-" attach_ebs_csi_policy = true oidc_providers = { main = { provider_arn = module.eks_cluster.oidc_provider_arn namespace_service_accounts = ["kube-system:ebs-csi-controller-sa"] } } tags = var.tags } module "eks_blueprints_addons" { source = "aws-ia/eks-blueprints-addons/aws" version = "~> 1.1" cluster_name = module.eks_cluster.cluster_name cluster_endpoint = module.eks_cluster.cluster_endpoint cluster_version = module.eks_cluster.cluster_version oidc_provider_arn = module.eks_cluster.oidc_provider_arn eks_addons = { aws-ebs-csi-driver = { most_recent = true service_account_role_arn = module.ebs_csi_driver_irsa.iam_role_arn } } }
但问题依旧。不过使用eksctl执行如下命令却能正常工作:
eksctl create addon --name aws-ebs-csi-driver --cluster eks-test --service-account-role-arn arn:aws:iam::11111111:role/AmazonEKS_EBS_CSI_DriverRole --force eksctl create iamserviceaccount \ --name ebs-csi-controller-sa \ --namespace kube-system \ --cluster eks-test \ --role-name AmazonEKS_EBS_CSI_DriverRole \ --role-only \ --attach-policy-arn arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy \ --approve
请问该如何解决Terraform部署下的权限问题?
1. 验证IRSA角色的信任策略
检查Terraform创建的IRSA角色信任关系是否正确,确保仅允许kube-system:ebs-csi-controller-sa这个ServiceAccount扮演该角色:
- 登录AWS控制台,进入IAM角色页面,找到Terraform创建的
ebs-csi-driver-xxx角色 - 查看「信任关系」,确认策略中的
Condition部分包含"StringEquals": {"oidc.eks.<区域>.amazonaws.com/id/<集群OIDC ID>:sub": "system:serviceaccount:kube-system:ebs-csi-controller-sa"}
也可以通过Terraform输出验证:
terraform output -raw module.ebs_csi_driver_irsa.iam_role_policy_document
2. 检查ServiceAccount的IRSA注解
确认kube-system下的ebs-csi-controller-sa已绑定正确的IRSA角色ARN:
kubectl describe sa ebs-csi-controller-sa -n kube-system
查看输出中的Annotations字段,必须包含eks.amazonaws.com/role-arn: arn:aws:iam::<账号ID>:role/ebs-csi-driver-xxx。如果缺失或错误,说明Terraform模块未正确配置,可手动添加注解或调整代码。
3. 强制更新EBS CSI Driver Addon
若之前部署过无IRSA配置的驱动,可能存在残留配置。在Terraform的eks_addons配置中添加force_update = true,强制AWS重新关联IRSA角色:
eks_addons = { aws-ebs-csi-driver = { most_recent = true service_account_role_arn = module.ebs_csi_driver_irsa.iam_role_arn force_update = true } }
执行terraform apply后,重启EBS CSI控制器Pod:
kubectl rollout restart deployment ebs-csi-controller -n kube-system
4. 升级eks_blueprints_addons模块版本
你使用的~>1.1版本存在IRSA关联的已知兼容性问题,建议升级到最新稳定版本(如~>1.15),新版本对EBS CSI Driver的IRSA配置支持更完善。
5. 替换默认StorageClass
默认的standard StorageClass可能未指定EBS CSI Driver作为provisioner,创建一个专用的StorageClass:
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: ebs-sc provisioner: ebs.csi.aws.com volumeBindingMode: WaitForFirstConsumer
将PVC的storageClassName指定为ebs-sc,确保使用EBS CSI Driver创建卷。
6. 确认控制器Pod使用正确ServiceAccount
检查EBS CSI控制器Pod是否使用ebs-csi-controller-sa:
kubectl get pods -n kube-system | grep ebs-csi-controller kubectl describe pod <控制器Pod名称> -n kube-system | grep ServiceAccount
若显示的ServiceAccount不是ebs-csi-controller-sa,说明驱动部署时未正确指定,需调整Terraform配置或手动修改Deployment的ServiceAccount字段。
内容的提问来源于stack exchange,提问作者Alpin Cleopatra

