2. Karpenter 控制器权限与 IRSA 配置排查
IRSA 权限链路:从 ServiceAccount 到 EC2 动作
Karpenter 控制器要能创建、终止 EC2 实例并读取价格、子网、安全组等信息,必须通过 IRSA(IAM Roles for Service Accounts)获得 AWS 权限。排查时不要只看 Pod 是否 Running,而要沿着“ServiceAccount → OIDC 信任 → IAM Role → 权限策略 → AWS API 调用”这条链路逐段确认。
配置 IRSA 的关键步骤
以下操作假设集群已启用 OIDC Provider,且 Karpenter 安装在 kube-system 命名空间。先确认 OIDC Provider 是否存在:
aws eks describe-cluster --name <cluster-name> \
--query "cluster.identity.oidc.issuer" --output text
输出形如 https://oidc.eks.cn-north-1.amazonaws.com.cn/id/EXAMPLED539D4633E53DE1B71EXAMPLE。若该 Provider 未在 IAM 中注册,需先创建:
eksctl utils associate-iam-oidc-provider \
--cluster <cluster-name> --approve
接着创建信任策略文件 karpenter-trust-policy.json,将 <OIDC_ID> 替换为上一步输出中的 ID:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<account-id>:oidc-provider/oidc.eks.<region>.amazonaws.com/id/<OIDC_ID>"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.<region>.amazonaws.com/id/<OIDC_ID>:sub": "system:serviceaccount:kube-system:karpenter",
"oidc.eks.<region>.amazonaws.com/id/<OIDC_ID>:aud": "sts.amazonaws.com"
}
}
}
]
}
创建 IAM Role 并附加最小权限策略。Karpenter 控制器需要的核心权限包括:
| 权限类别 | Action 示例 | 用途 |
|---|---|---|
| 实例生命周期 | ec2:RunInstances、ec2:TerminateInstances | 创建与终止节点 |
| 资源发现 | ec2:DescribeSubnets、ec2:DescribeSecurityGroups、ec2:DescribeImages | 选择子网、安全组、AMI |
| 实例状态 | ec2:DescribeInstances、ec2:DescribeInstanceTypes | 同步节点状态与规格 |
| 价格查询 | pricing:GetProducts | 成本感知的实例选择 |
| IAM 传递 | iam:PassRole | 为节点实例传递 NodeRole |
ec2:RunInstances 的 Resource 应限制为具体的 AMI、子网、安全组 ARN,而不是 *。但排查阶段可先放宽到 * 确认链路通,再逐步收紧。验证控制器是否真正具备权限
配置完成后,先确认 ServiceAccount 注解已正确注入:
kubectl get sa karpenter -n kube-system -o yaml | grep eks.amazonaws.com/role-arn
预期输出包含 eks.amazonaws.com/role-arn: arn:aws:iam::<account-id>:role/KarpenterControllerRole。若为空,说明 Helm 安装时未设置 serviceAccount.annotations,需要重新配置。
然后查看控制器日志,确认没有权限错误:
kubectl logs -n kube-system -l app.kubernetes.io/name=karpenter --tail=100
正常日志中不应出现 AccessDenied、UnauthorizedOperation 或 InvalidIdentityToken。若出现,按 SVG 中的排查判断区逐项对照。
最后用一次真实的扩容触发来验证权限闭环:提交一个资源请求较大的 Pod,观察 Karpenter 是否能成功调用 RunInstances 并创建节点。若节点成功加入集群,说明 IRSA 链路与权限策略均已生效。
sub 条件必须与 ServiceAccount 的命名空间和名称完全一致。如果 Karpenter 安装在 karpenter 命名空间而非 kube-system,而信任策略仍写 system:serviceaccount:kube-system:karpenter,STS 会拒绝 AssumeRole,日志中表现为 InvalidIdentityToken 或 AccessDenied。