現象
Karpenter をインストールする際に Pod Identity を使うように設定したが、何故か Karpenter Controller が Worker Node の IAM ロールを使って、EC2NodeClass で Failed to resolve AMIs
エラーが発生していた。
原因
- terraform-aws-modules を使って Karpenter の設定をしていたが、namespace が未指定だったので Service Account などは namespace
kube-system
に作成されていた。
- helm_release モジュールを使って Karpenter のインストールをしたが、そのときは namespace
karpenter
を指定していた。
- Pod Identity に紐づく Service Account が見つからないため、Worker Node の IAM ロールが使われていた。
経緯
使った terraform module はこれです。
registry.terraform.io
terraform-aws-modules で Pod Identity を使うように指定した (が、namespace が未指定のままだった)。
module "karpenter" {
source = "terraform-aws-modules/eks/aws//modules/karpenter"
cluster_name = module.eks.cluster_name
enable_pod_identity = true
create_pod_identity_association = true
node_iam_role_additional_policies = {
AmazonSSMManagedInstanceCore = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}
}
Karpenter のインストールを helm_release モジュールで実施してみる。
registry.terraform.io
resource "helm_release" "karpenter" {
namespace = "karpenter"
create_namespace = true
name = "karpenter"
repository = "oci://public.ecr.aws/karpenter"
repository_username = data.aws_ecrpublic_authorization_token.token.user_name
repository_password = data.aws_ecrpublic_authorization_token.token.password
chart = "karpenter"
version = var.karpenter_version
values = [
<<-EOT
serviceAccount:
name: ${module.karpenter.service_account}
settings:
clusterName: ${module.eks.cluster_name}
clusterEndpoint: ${module.eks.cluster_endpoint}
EOT
]
# https://github.com/hashicorp/terraform-provider-helm/issues/593
depends_on = [
module.eks
]
}
Karpenter Controller で発生したエラー。
{
"level": "ERROR",
"time": "2024-07-15T14:51:23.650Z",
"logger": "controller",
"message": "Reconciler error",
"commit": "490ef94",
"controller": "nodeclass.status",
"controllerGroup": "karpenter.k8s.aws",
"controllerKind": "EC2NodeClass",
"EC2NodeClass": {
"name": "default"
},
"namespace": "",
"name": "default",
"reconcileID": "3d9e21ea-5b21-441f-886b-9aa94562b1c8",
"error": "creating instance profile, getting instance profile \"karpenter_xxxxxxxxxx\", AccessDenied: User: arn:aws:sts::999999999999:assumed-role/default-eks-node-group-xxxxxxxxxxx/i-9999999999is not authorized to perform: iam:GetInstanceProfile on resource: instance profile karpenter_xxxxxxxxxx because no identity-based policy allows the iam:GetInstanceProfile action\n\tstatus code: 403, request id: 825b11e9-54b3-4631-88ff-885fb83357b8"
}
EC2NodeClass も見てみるとエラーになっている。
$ kubectl describe EC2NodeClass default
〜略〜
Message: Failed to resolve AMIs
ただし、EC2NodeClass には Karpenter Controller を動かすのに必要なロールが
付与されていた。
Role: Karpenter-multi-arch-inference-xxxxxxxxxx
AMI 系のエラーを調査すべく CloudTrail を見ると、ec2:DescribeImages
で失敗しているログがでているが、ユーザーは何故か Worker Node の IAM ロールだった。
You are not authorized to perform this operation.
User: arn:aws:sts::999999999999:assumed-role/default-eks-node-group-xxxxxxxxxxx/i-002aefdbea1442380 is not authorized to perform: ec2:DescribeImages because no identity-based policy allows the ec2:DescribeImages action"
Karpenter module の namespace を "karpenter" に合わせたところエラーは解消した。
module "karpenter" {
source = "terraform-aws-modules/eks/aws//modules/karpenter"
cluster_name = module.eks.cluster_name
namespace = "karpenter"
enable_pod_identity = true
create_pod_identity_association = true
node_iam_role_additional_policies = {
AmazonSSMManagedInstanceCore = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}
}
関連ドキュメント
おそらくこれか?Service Account が見つからず、Worker Node の IAM ロールが使われた。しかし Worker Node の IAM には必要な権限が付与されていなかった。
Pod がサービスアカウントに関連付けられた IAM ロールの AWS 認証情報を使用する場合、AWS CLI またはその Pod のコンテナ内の他の SDK は、そのロールによって提供される認証情報を使用します。
Amazon EKS ノード IAM ロール に提供された認証情報へのアクセスを制限しない場合、Pod は引き続きこれらの認証情報にアクセスできます。
詳細については、「ワーカーノードに割り当てられたインスタンスプロファイルへのアクセスを制限する」を参照してください。
docs.aws.amazon.com