概要

  • こんにちわ、新川です。今回は、以前に執筆したハンズオンブログの応用になります。以下の記事で構築したEKSクラスタをベースに、さらに実運用に役立つ3つの重要な設定変更方法を解説します。
  • 具体的には、以下3つの設定方法について、eksctl のYAMLファイルに定義する方法を紹介します。
    • マネージドノードグループのノードに既存のIAMロールを指定する方法
    • マネージドノードグループのノードのボリューム暗号化設定
    • アドオン(Amazon VPC CNI plugin)の設定変更
  • これらの設定を理解することで、より柔軟でセキュアなEKS環境を構築できるようになります。

 

EKSクラスタ/ノードグループのカスタマイズ手順

マネージドノードグループのノードに既存のIAMロールを指定する

  • 通常、eksctl コマンドでマネージドノードグループを作成すると、専用のIAMロールが自動的に生成され、EC2ノードに付与されます。しかし、特定の要件(例:社内ポリシーに準拠した命名規則、複数のクラスタで共通のロールを使用したい場合など)がある場合、既存のロールを指定したいことがあります。
  • iam.instanceRoleARN のパラメータに既存のIAMロールのARNを指定することで、eksctl コマンドが自動生成するロールではなく、指定したロールがEC2ノードにアタッチされます。
managedNodeGroups に以下を設定

  iam:
    instanceRoleARN: "arn:${AWS_PARTITION}:iam::${AWS_ACCOUNT_ID}:role/<ロール名>"

 

マネージドノードグループのノードのボリューム暗号化設定

  • マネージドノードグループのEC2 ノードには、デフォルトでルートボリューム(OSがインストールされているボリューム)がアタッチされています。このボリュームサイズや暗号化設定は、カスタマイズできます。
    • volumeName:ルートボリュームのデバイス名(Linuxの場合は通常/dev/xvda)。変更は不要なケースがほとんどです。
    • volumeSize:ノードのルートボリュームのサイズをGB単位で指定します。デフォルトのサイズでは不足する場合や、ログやキャッシュなど追加のデータを保存したい場合に増やします。
    • volumeEncrypted:ボリュームの暗号化を有効にするかをブール値(true or false)で設定します。セキュリティ要件の高い環境では必須の設定項目です。
    • volumeKmsKeyID:「volumeEncrypted: true」と設定した場合、暗号化に使用するKMSカスタマー管理型キーのARNを指定します。これにより、デフォルトのAWS管理キーではなく、ユーザーが管理するキーでボリュームを暗号化できます。
managedNodeGroups に以下を設定

  volumeName: /dev/xvda
  volumeSize: 20
  volumeEncrypted: true
  volumeKmsKeyID: ${KMS_KEY_ID}
  • 事前準備として、KMS でカスタマー管理型キーを作成します。キーを作成後、ARN を控えます。

  • EKS のサービスロールがキーにアクセスするため、キーポリシーを追加します。このポリシーがなければ、「The KMS key provided is in an incorrect state」のエラーとなりノードが起動しません。
    {
      "Sid": "Allow attachment of persistent resources",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "kms:*",
      "Resource": "KMSカスタマー管理型キーのARN"
    }

 

 

アドオン(Amazon VPC CNI plugin)の設定変更

  • EKS のアドオンは、クラスタの機能を拡張する重要なコンポーネントです。eksctl コマンドのYAMLファイルでは、アドオン有無の指定だけでなく、詳細な設定も行えます。今回は、Amazon VPC CNIプラグインの「ENABLE_POD_ENI」設定を変更する例です。
    • addons:EKSにインストールするアドオンを指定するセクションです。
    • resolveConflicts:既存のアドオン設定と競合する場合に、overwriteの設定で上書きすることを指示します。これにより、手動で加えた変更が意図せず元に戻されることを防げます。
    • configurationValues:アドオンの設定をJSON形式で記述します。この例では、vpc-cniの環境変数として「ENABLE_POD_ENI: true」を設定しています。(Pod 単位にENI を割り当てる動作モードの設定となります)
  • アドオンの設定変更の詳細は、こちらのAWS ドキュメントを参照ください。

 

addons に以下を設定
- name: vpc-cni
  resolveConflicts: overwrite
  configurationValues: '{"env":{"ENABLE_POD_ENI":"true"}}'

 

設定例

  • 以前のハンズオンで使用したYAMLファイルに上記カスタマイズを行った以下のファイルを使用します。
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: ${CLUSTER_NAME}
  region: ${AWS_DEFAULT_REGION}
  version: "${K8S_VERSION}"
  tags:
    karpenter.sh/discovery: ${CLUSTER_NAME}

vpc:
  id: ${VPC_ID}
  subnets:
    private:
      ${AWS_AVAILABILITY_ZONE_A}: { id: ${PRIVATE_SUBNET_A_ID} }
      ${AWS_AVAILABILITY_ZONE_B}: { id: ${PRIVATE_SUBNET_B_ID} }
    public:
      ${AWS_AVAILABILITY_ZONE_A}: { id: ${PUBLIC_SUBNET_A_ID} }
      ${AWS_AVAILABILITY_ZONE_B}: { id: ${PUBLIC_SUBNET_B_ID} }
  clusterEndpoints:
    publicAccess: true
    privateAccess: false

iam:
  withOIDC: true
  podIdentityAssociations:
  - namespace: "${KARPENTER_NAMESPACE}"
    serviceAccountName: karpenter
    roleName: ${CLUSTER_NAME}-karpenter
    permissionPolicyARNs:
    - arn:${AWS_PARTITION}:iam::${AWS_ACCOUNT_ID}:policy/KarpenterControllerPolicy-${CLUSTER_NAME}

iamIdentityMappings:
- arn: "arn:${AWS_PARTITION}:iam::${AWS_ACCOUNT_ID}:role/KarpenterNodeRole-${CLUSTER_NAME}"
  username: system:node:{{EC2PrivateDNSName}}
  groups:
  - system:bootstrappers
  - system:nodes

managedNodeGroups:
- name: ${CLUSTER_NAME}-ng
  iam:
    instanceRoleARN: "arn:${AWS_PARTITION}:iam::${AWS_ACCOUNT_ID}:role/KarpenterNodeRole-${CLUSTER_NAME}"
  instanceType: m5.large
  amiFamily: AmazonLinux2023
  desiredCapacity: 2
  minSize: 1
  maxSize: 5
  privateNetworking: true
  subnets:
  - ${PRIVATE_SUBNET_A_ID}
  - ${PRIVATE_SUBNET_B_ID}
  volumeName: /dev/xvda
  volumeSize: 20
  volumeEncrypted: true
  volumeKmsKeyID: ${KMS_KEY_ID}

addons:
- name: vpc-cni
  resolveConflicts: overwrite
  configurationValues: '{"env":{"ENABLE_POD_ENI":"true"}}' 
- name: eks-pod-identity-agent
- name: amazon-cloudwatch-observability
- name: kube-proxy
- name: coredns

 

  • 以下オペレーションの実行例です。cat コマンドで環境変数を設定したYAML ファイルを作成し、eksctl コマンドでクラスタとノードグループを作成します。
$ export KARPENTER_NAMESPACE="karpenter"
$ export KARPENTER_VERSION="1.6.3"
$ export K8S_VERSION="1.33"
$ export AWS_PARTITION=$(aws sts get-caller-identity --query "Arn" | cut -d: -f2)
$ export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
$ export AWS_DEFAULT_REGION="us-west-2"
$ export CLUSTER_NAME="niikawa-karpenter-demo"
$ export VPC_ID="vpc-0a7b230729923d078"
$ export AWS_AVAILABILITY_ZONE_A="us-west-2a"
$ export AWS_AVAILABILITY_ZONE_B="us-west-2b"
$ export PRIVATE_SUBNET_A_ID="subnet-078769ea3a250f04f"
$ export PRIVATE_SUBNET_B_ID="subnet-0d5c6423d30407c1c"
$ export PUBLIC_SUBNET_A_ID="subnet-02505e6f42011d08b"
$ export PUBLIC_SUBNET_B_ID="subnet-004f6c6d374b5a3e4"

$ export KMS_KEY_ID="arn:aws:kms:us-west-2:111111111111:key/1a99192c-4362-40ac-b96c-02c7274e8d96"

$ cat << EOF > karpenter-cluster-customize.yaml
** 前述のYAMLをここに貼りつけ **
← EOFを入力

$ eksctl create cluster -f karpenter-cluster-customize.yaml 
2025-09-15 14:49:52 [ℹ]  eksctl version 0.214.0
2025-09-15 14:49:52 [ℹ]  using region us-west-2
2025-09-15 14:49:52 [✔]  using existing VPC (vpc-0a7b230729923d078) and subnets (private:map[us-west-2a:{subnet-078769ea3a250f04f us-west-2a 10.100.0.128/26 0 } us-west-2b:{subnet-0d5c6423d30407c1c us-west-2b 10.100.0.192/26 0 }] public:map[us-west-2a:{subnet-02505e6f42011d08b us-west-2a 10.100.0.0/27 0 } us-west-2b:{subnet-004f6c6d374b5a3e4 us-west-2b 10.100.0.32/27 0 }])
2025-09-15 14:49:52 [!]  custom VPC/subnets will be used; if resulting cluster doesn't function as expected, make sure to review the configuration of VPC/subnets
2025-09-15 14:49:52 [ℹ]  nodegroup "niikawa-karpenter-demo-ng" will use "" [AmazonLinux2023/1.33]
2025-09-15 14:49:52 [ℹ]  using Kubernetes version 1.33
2025-09-15 14:49:52 [ℹ]  creating EKS cluster "niikawa-karpenter-demo" in "us-west-2" region with managed nodes
2025-09-15 14:49:52 [ℹ]  1 nodegroup (niikawa-karpenter-demo-ng) was included (based on the include/exclude rules)
2025-09-15 14:49:52 [ℹ]  will create a CloudFormation stack for cluster itself and 1 managed nodegroup stack(s)
2025-09-15 14:49:52 [ℹ]  if you encounter any issues, check CloudFormation console or try 'eksctl utils describe-stacks --region=us-west-2 --cluster=niikawa-karpenter-demo'
2025-09-15 14:49:52 [ℹ]  Kubernetes API endpoint access will use default of {publicAccess=true, privateAccess=false} for cluster "niikawa-karpenter-demo" in "us-west-2"
2025-09-15 14:49:52 [ℹ]  CloudWatch logging will not be enabled for cluster "niikawa-karpenter-demo" in "us-west-2"
2025-09-15 14:49:52 [ℹ]  you can enable it with 'eksctl utils update-cluster-logging --enable-types={SPECIFY-YOUR-LOG-TYPES-HERE (e.g. all)} --region=us-west-2 --cluster=niikawa-karpenter-demo'
2025-09-15 14:49:52 [ℹ]  default addons metrics-server were not specified, will install them as EKS addons
2025-09-15 14:49:52 [ℹ]  
2 sequential tasks: { create cluster control plane "niikawa-karpenter-demo", 
    2 sequential sub-tasks: { 
        6 sequential sub-tasks: { 
            1 task: { create addons },
            wait for control plane to become ready,
            associate IAM OIDC provider,
            no tasks,
            update VPC CNI to use IRSA if required,
            create IAM identity mappings,
        },
        create managed nodegroup "niikawa-karpenter-demo-ng",
    } 
}
2025-09-15 14:49:52 [ℹ]  building cluster stack "eksctl-niikawa-karpenter-demo-cluster"
2025-09-15 14:49:53 [ℹ]  deploying stack "eksctl-niikawa-karpenter-demo-cluster"
2025-09-15 14:50:23 [ℹ]  waiting for CloudFormation stack "eksctl-niikawa-karpenter-demo-cluster"
2025-09-15 14:50:53 [ℹ]  waiting for CloudFormation stack "eksctl-niikawa-karpenter-demo-cluster"
2025-09-15 14:51:53 [ℹ]  waiting for CloudFormation stack "eksctl-niikawa-karpenter-demo-cluster"
2025-09-15 14:52:53 [ℹ]  waiting for CloudFormation stack "eksctl-niikawa-karpenter-demo-cluster"
2025-09-15 14:53:53 [ℹ]  waiting for CloudFormation stack "eksctl-niikawa-karpenter-demo-cluster"
2025-09-15 14:54:53 [ℹ]  waiting for CloudFormation stack "eksctl-niikawa-karpenter-demo-cluster"
2025-09-15 14:55:53 [ℹ]  waiting for CloudFormation stack "eksctl-niikawa-karpenter-demo-cluster"
2025-09-15 14:56:53 [ℹ]  waiting for CloudFormation stack "eksctl-niikawa-karpenter-demo-cluster"
2025-09-15 14:57:53 [ℹ]  waiting for CloudFormation stack "eksctl-niikawa-karpenter-demo-cluster"
2025-09-15 14:57:55 [ℹ]  creating addon: eks-pod-identity-agent
2025-09-15 14:57:55 [ℹ]  successfully created addon: eks-pod-identity-agent
2025-09-15 14:57:56 [!]  recommended policies were found for "vpc-cni" addon, but since OIDC is disabled on the cluster, eksctl cannot configure the requested permissions; the recommended way to provide IAM permissions for "vpc-cni" addon is via pod identity associations; after addon creation is completed, add all recommended policies to the config file, under `addon.PodIdentityAssociations`, and run `eksctl update addon`
2025-09-15 14:57:56 [ℹ]  creating addon: vpc-cni
2025-09-15 14:57:56 [ℹ]  successfully created addon: vpc-cni
2025-09-15 14:57:57 [ℹ]  creating addon: kube-proxy
2025-09-15 14:57:57 [ℹ]  successfully created addon: kube-proxy
2025-09-15 14:57:57 [ℹ]  creating addon: coredns
2025-09-15 14:57:58 [ℹ]  successfully created addon: coredns
2025-09-15 14:57:58 [ℹ]  creating addon: metrics-server
2025-09-15 14:57:58 [ℹ]  successfully created addon: metrics-server
2025-09-15 14:59:59 [ℹ]  addon "vpc-cni" active
2025-09-15 15:00:00 [ℹ]  deploying stack "eksctl-niikawa-karpenter-demo-addon-vpc-cni"
2025-09-15 15:00:00 [ℹ]  waiting for CloudFormation stack "eksctl-niikawa-karpenter-demo-addon-vpc-cni"
2025-09-15 15:00:30 [ℹ]  waiting for CloudFormation stack "eksctl-niikawa-karpenter-demo-addon-vpc-cni"
2025-09-15 15:00:31 [ℹ]  updating addon
2025-09-15 15:00:41 [ℹ]  addon "vpc-cni" active
2025-09-15 15:00:41 [ℹ]  checking arn arn:aws:iam::111111111111:role/KarpenterNodeRole-niikawa-karpenter-demo against entries in the auth ConfigMap
2025-09-15 15:00:41 [ℹ]  adding identity "arn:aws:iam::111111111111:role/KarpenterNodeRole-niikawa-karpenter-demo" to auth ConfigMap
2025-09-15 15:00:42 [ℹ]  building managed nodegroup stack "eksctl-niikawa-karpenter-demo-nodegroup-niikawa-karpenter-demo-ng"
2025-09-15 15:00:42 [ℹ]  deploying stack "eksctl-niikawa-karpenter-demo-nodegroup-niikawa-karpenter-demo-ng"
2025-09-15 15:00:42 [ℹ]  waiting for CloudFormation stack "eksctl-niikawa-karpenter-demo-nodegroup-niikawa-karpenter-demo-ng"
2025-09-15 15:01:12 [ℹ]  waiting for CloudFormation stack "eksctl-niikawa-karpenter-demo-nodegroup-niikawa-karpenter-demo-ng"
2025-09-15 15:01:56 [ℹ]  waiting for CloudFormation stack "eksctl-niikawa-karpenter-demo-nodegroup-niikawa-karpenter-demo-ng"
2025-09-15 15:03:27 [ℹ]  waiting for CloudFormation stack "eksctl-niikawa-karpenter-demo-nodegroup-niikawa-karpenter-demo-ng"
2025-09-15 15:03:27 [ℹ]  waiting for the control plane to become ready
2025-09-15 15:03:27 [✔]  saved kubeconfig as "/home/cloudshell-user/.kube/config"
2025-09-15 15:03:27 [ℹ]  no tasks
2025-09-15 15:03:27 [✔]  all EKS cluster resources for "niikawa-karpenter-demo" have been created
2025-09-15 15:03:27 [ℹ]  nodegroup "niikawa-karpenter-demo-ng" has 2 node(s)
2025-09-15 15:03:27 [ℹ]  node "ip-10-100-0-188.us-west-2.compute.internal" is ready
2025-09-15 15:03:27 [ℹ]  node "ip-10-100-0-254.us-west-2.compute.internal" is ready
2025-09-15 15:03:27 [ℹ]  waiting for at least 1 node(s) to become ready in "niikawa-karpenter-demo-ng"
2025-09-15 15:03:27 [ℹ]  nodegroup "niikawa-karpenter-demo-ng" has 2 node(s)
2025-09-15 15:03:27 [ℹ]  node "ip-10-100-0-188.us-west-2.compute.internal" is ready
2025-09-15 15:03:27 [ℹ]  node "ip-10-100-0-254.us-west-2.compute.internal" is ready
2025-09-15 15:03:27 [✔]  created 1 managed nodegroup(s) in cluster "niikawa-karpenter-demo"
2025-09-15 15:03:28 [!]  IAM permissions are required for "amazon-cloudwatch-observability" addon; the recommended way to provide IAM permissions for "amazon-cloudwatch-observability" addon is via pod identity associations; after addon creation is completed, add all recommended policies to the config file, under `addon.PodIdentityAssociations`, and run `eksctl update addon`
2025-09-15 15:03:28 [ℹ]  creating addon: amazon-cloudwatch-observability
2025-09-15 15:04:11 [ℹ]  addon "amazon-cloudwatch-observability" active
2025-09-15 15:04:11 [ℹ]  1 task: { 
    2 sequential sub-tasks: { 
        create IAM role for pod identity association for service account "karpenter/karpenter",
        create pod identity association for service account "karpenter/karpenter",
    } }2025-09-15 15:04:11 [ℹ]  deploying stack "eksctl-niikawa-karpenter-demo-podidentityrole-karpenter-karpenter"
2025-09-15 15:04:11 [ℹ]  waiting for CloudFormation stack "eksctl-niikawa-karpenter-demo-podidentityrole-karpenter-karpenter"
2025-09-15 15:04:41 [ℹ]  waiting for CloudFormation stack "eksctl-niikawa-karpenter-demo-podidentityrole-karpenter-karpenter"
2025-09-15 15:04:42 [ℹ]  created pod identity association for service account "karpenter" in namespace "karpenter"
2025-09-15 15:04:42 [ℹ]  all tasks were completed successfully
2025-09-15 15:04:44 [ℹ]  kubectl command should work with "/home/cloudshell-user/.kube/config", try 'kubectl get nodes'
2025-09-15 15:04:44 [✔]  EKS cluster "niikawa-karpenter-demo" in "us-west-2" region is ready
~ $

 

  • マネジメントコンソールからカスタマイズした設定が反映されていることを確認しましょう。
  • 以下の通り、マネージドノードグループのノードに既存のIAMロールが指定されています。

 

  • 以下の通り、マネージドノードグループのノードのボリュームが暗号化されました。さらに、暗号化にはKMSのカスタマー管理型キーが使用されていることが確認できました。

 

  • 以下の通り、アドオン(Amazon VPC CNI plugin)の設定変更が行われた状態でアドオンが追加されました。

 

まとめ

  • EKSクラスタ/ノードグループのカスタマイズ手順を紹介しました。この記事が、EKS 環境をより深くカスタマイズするための参考になれば幸いです。さらに詳しいカスタマイズの方法は、AWS ドキュメントを参照ください。