EKS の組み込みネットワーキングアドオンについて調べてみた

EKS の組み込みネットワーキングアドオンについて調べてみた

EKS の組み込みネットワーキングアドオンについて調べてみました。

EKS の組み込みネットワーキングアドオンとは?

2025 年 4 月現在、EKS アドオンには下記 3 種類が存在します。

  • AWS アドオン(AWS がサポートするアドオン)
  • コミュニティアドオン(AWS が互換性を検証しており、インストール時のみサポートするアドオン)
  • マーケットプレイスアドオン(サードパーティがサポートするアドオン)

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/eks-add-ons.html#addon-support

また、上記と類似ではあるものの別の概念として、組み込みネットワーキングアドオンが存在します。
こちらは VPC CNI plugin や CoreDNS など Kubernetes を動作させるために必要なネットワーク系コンポーネントを自動でセットアップしてくれるものになります。
現在も利用可能ですが、代わりに EKS アドオンを利用することが推奨されています。

コンソール以外の方法でクラスターを作成した場合、各クラスターにセルフマネージド版の組み込みアドオンが付属します。セルフマネージド型バージョンは、AWS Management Console、AWS コマンドラインインターフェイス、SDK のいずれからも管理することはできません。セルフマネージド型アドオンの設定とアップグレードは、ユーザーが管理します。
セルフマネージド型のアドオンを使用する代わりに、アマゾン EKS タイプのアドオンをクラスターに追加することをお勧めします。コンソールを使用してクラスターを作成する場合、これらのアドオンの Amazon EKS タイプがインストールされます。
https://docs.aws.amazon.com/eks/latest/userguide/eks-networking-add-ons.html

組み込みネットワーキングアドオンとして自動でセットアップしてくれるのは楽とも考えられますが、AWS 上のリソースとして管理もできない状態で Kubernetes リソースが勝手に作成されるのは気持ち悪い気もします。
更新する際は、公開されているマニフェストファイルをダウンロードしたり、既存のリソースの設定を参考にして変更を加える形です。

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/vpc-add-on-self-managed-update.html

それであれば、最初から設定込みで EKS アドオンとしてインストールした方が管理上わかりやすいと思います。

Terraform で試してみる

マネジメントコンソールで作成すると組み込みネットワーキングアドオンは有効化されないということなので、Terraform の AWS EKS Terraform module を利用して EKS クラスターを作成してみます。
この際、enable_cluster_creator_admin_permissions が該当する定義になります。

module "eks" {
  source  = "terraform-aws-modules/eks/aws"
  version = "~> 20.35.0"

  cluster_name                    = local.cluster_name
  cluster_version                 = "1.32"
  cluster_endpoint_public_access  = true
  cluster_endpoint_private_access = true

  vpc_id     = module.vpc.vpc_id
  subnet_ids = module.vpc.private_subnets

  enable_cluster_creator_admin_permissions = true

  eks_managed_node_groups = {
    default = {
      name = "default"

      instance_types = ["t3.small"]

      min_size     = 1
      max_size     = 3
      desired_size = 1
    }
  }

  bootstrap_self_managed_addons = true
}

上記の様にクラスターを作成すると、特にセットアップをしなくてもネットワーキングコンポーネントがインストールされました。

% kubectl get pod -n kube-system
NAME                       READY   STATUS    RESTARTS   AGE
aws-node-7846n             2/2     Running   0          77m
coredns-6d78c58c9f-5mgds   1/1     Running   0          81m
coredns-6d78c58c9f-zzk9c   1/1     Running   0          81m
kube-proxy-mttj2           1/1     Running   0          77m

EKS アドオンを利用した場合の定義は下記のようになります。

module "eks" {
  source  = "terraform-aws-modules/eks/aws"
  version = "~> 20.35.0"

  cluster_name                    = local.cluster_name
  cluster_version                 = "1.32"
  cluster_endpoint_public_access  = true
  cluster_endpoint_private_access = true

  vpc_id     = module.vpc.vpc_id
  subnet_ids = module.vpc.private_subnets

  eks_managed_node_groups = {
    default = {
      name = "default"

      instance_types = ["t3.small"]

      min_size     = 1
      max_size     = 3
      desired_size = 1
    }
  }

  bootstrap_self_managed_addons = false

  cluster_addons = {
    coredns = {
      version = "v1.11.4-eksbuild.2"
    }
    kube-proxy = {
      version = "v1.32.0-eksbuild.2"
    }
    vpc-cni = {
      version        = "v1.19.3-eksbuild.1"
      before_compute = true
    }
    eks-pod-identity-agent = {
      version = "v1.3.5-eksbuild.2"
    }
  }
}

AWS 上の設定として各設定を扱いつつ、ネットワーキングアドオンをセットアップすることが可能です。
他のコンポーネント(Pod Identity Agent や EBS CSI driver アドオンなど)と同じやり方で管理できることも嬉しいポイントです。

[補足 1] 
VPC CNI plugin のみ before_compute オプションを指定しているのは VPC CNI plugin のセットアップが終わってからノードグループを作成するようにして、ノードの設定が作成タイミング次第でブレる可能性を抑えるためです。

https://github.com/terraform-aws-modules/terraform-aws-eks/issues/2467

[補足 2]

バージョンのアドオンを指定する際に、version を指定する方法と most_recent = true を指定する方法があります。
AWS EKS Terraform module を利用した時の話であり、組み込みネットワーキングアドオンの話と直接は関係ないですが、バージョンをきちんと指定して管理することを推奨します。

[補足 3]

EKS Auto Mode の場合は、ネットワーキング系のコンポーネントは AWS 管理になるため、組み込みネットワーキングアドオンも対応する EKS アドオンも不要です。

ネットワーキング: EKS Auto Mode は、ポッドとサービスの接続に関する重要なネットワーキングタスクを自動化します。これには、IPv4/IPv6 サポートと、IP アドレススペースを拡張するためのセカンダリ CIDR ブロックの使用が含まれます。
https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/automode.html

bootstrapSelfManagedAddons 属性について

セルフマネージド型アドオンをインストールするかどうかは CreateCluster API に存在する bootstrapSelfManagedAddons で制御できます。

https://docs.aws.amazon.com/ja_jp/eks/latest/APIReference/API_CreateCluster.html#API_CreateCluster_RequestBody

AWS EKS Terraform module でもこちらを制御するパラメータが存在します。

bootstrap_self_managed_addons bool
Description: Indicates whether or not to bootstrap self-managed addons after the cluster has been created

https://registry.terraform.io/modules/terraform-aws-modules/eks/aws/latest?tab=inputs

※ こちらを制御できるようになったのは比較的最近のことで、2024 年頭になります。

https://github.com/terraform-aws-modules/terraform-aws-eks/issues/3093

そもそも EKS アドオンの利用が推奨されていることもあり、AWS EKS Terraform module では、いずれ false にハードコードされるというコメントもありました。

https://github.com/terraform-aws-modules/terraform-aws-eks/issues/3266#issuecomment-2573974714

また、更新する際には指定できず、クラスター作成時のみに設定できる属性になります。

https://docs.aws.amazon.com/ja_jp/eks/latest/APIReference/API_UpdateClusterConfig.html

AWS EKS Terraform module を利用する場合、デフォルトでは true 扱いになるようです。
bootstrap_self_managed_addons 属性を指定しなかった際、CreateCluster の requestParameters は下記のようになりました。

{
  "requestParameters": {
    "bootstrapSelfManagedAddons": true,
    "encryptionConfig": [
      {
        "provider": {
          "keyArn": "arn:aws:kms:ap-northeast-1:xxxxxxxxxxxx:key/745e5cec-24f2-4c1a-98db-9718ad559332"
        },
        "resources": ["secrets"]
      }
    ],
    "resourcesVpcConfig": {
      "endpointPrivateAccess": true,
      "endpointPublicAccess": true,
      "publicAccessCidrs": ["0.0.0.0/0"],
      "securityGroupIds": ["sg-00b1863a923f97f6e"],
      "subnetIds": [
        "subnet-09181196696186fc9",
        "subnet-011609187505c89a3",
        "subnet-0302d2f4c14d12022"
      ]
    },
    "clientRequestToken": "xxxxxxxxxxxx",
    "roleArn": "arn:aws:iam::xxxxxxxxxxxx:role/test-cluster-cluster-20250413094543079300000002",
    "name": "test-cluster",
    "accessConfig": {
      "authenticationMode": "API_AND_CONFIG_MAP",
      "bootstrapClusterCreatorAdminPermissions": false
    },
    "logging": {
      "clusterLogging": [
        {
          "enabled": true,
          "types": ["audit", "api", "authenticator"]
        },
        {
          "enabled": false,
          "types": ["controllerManager", "scheduler"]
        }
      ]
    },
    "kubernetesNetworkConfig": {
      "ipFamily": "ipv4"
    },
    "version": "1.32",
    "tags": {
      "terraform-aws-modules": "eks"
    }
  }
}

モジュールのデフォルト値として、bootstrap_self_managed_addons = true となっているようです。

マネジメントコンソールから作成した場合は公式ドキュメント通り、bootstrapSelfManagedAddons = false となりました。
マネジメントコンソールから作成した場合の CreateCluster の requestParameters を抜き出すと下記でした。

{
  "requestParameters": {
    "zonalShiftConfig": {
      "enabled": false
    },
    "version": "1.32",
    "tags": {},
    "bootstrapSelfManagedAddons": false,
    "upgradePolicy": {
      "supportType": "STANDARD"
    },
    "resourcesVpcConfig": {
      "subnetIds": [
        "subnet-09181196696186fc9",
        "subnet-011609187505c89a3",
        "subnet-0302d2f4c14d12022"
      ],
      "securityGroupIds": [],
      "endpointPublicAccess": true,
      "endpointPrivateAccess": true,
      "publicAccessCidrs": ["0.0.0.0/0"]
    },
    "clientRequestToken": "xxxxxxxxxxxx",
    "roleArn": "arn:aws:iam::xxxxxxxxxxxx:role/test-cluster-cluster-20250413094543079300000002",
    "name": "test-cluster2",
    "logging": {
      "clusterLogging": [
        {
          "enabled": true,
          "types": []
        },
        {
          "enabled": false,
          "types": [
            "api",
            "audit",
            "authenticator",
            "controllerManager",
            "scheduler"
          ]
        }
      ]
    },
    "accessConfig": {
      "bootstrapClusterCreatorAdminPermissions": true,
      "authenticationMode": "API"
    },
    "kubernetesNetworkConfig": {
      "ipFamily": "ipv4"
    }
  }
}

EKS アドオンの利用が推奨されていることやマネジメントコンソールから作成する場合は bootstrap_self_managed_addons = false となることを考えると、新規作成する際は Terraform でもこちらの属性は false で良いように思います。
また、EKS Auto Mode を有効化する場合、bootstrap_self_managed_addons 属性の default 値が false になるという話もあります。

https://github.com/terraform-aws-modules/terraform-aws-eks/issues/3266

本属性は replace 属性になるため、元々特に指定してなくて true 扱いになっていた所から Auto Mode 有効化で実質 false 扱いになった結果、意図しないクラスター置き換えを引き起こす可能性があります。
こちらの属性はクラスター作成時にしか影響を与えないため、明示的に bootstrap_self_managed_addons = true を指定しつつ Auto Mode へ移行しても問題なさそうですが、可能なら最初から false と指定しておいた方が無難な気がします。

組み込みネットワーキングアドオンから EKS アドオンに移行してみる

最初は組み込みネットワーキングアドオンをインストールしていた場合も、後から EKS アドオンをインストールすることで置き換えが可能です。
この際、元々インストールされている組み込みネットワーキングアドオンのバージョンとインストールする EKS アドオンのバージョンは揃えておいた方が良いでしょう。
2025 年 4 月時点で bootstrap_self_managed_addons = true としつつ、EKS 1.32 を作成した場合は下記バージョンがインストールされました。

アドオン名 バージョン
VPC CNI plugin v1.19.2-eksbuild.1
kube-proxy v1.32.0-eksbuild.2
CoreDNS v1.11.4-eksbuild.2

基本的にはその時点でインストールできる最新のアドオン相当のものがインストールされると考えて良さそうです。
VPC CNI plugin アドオンの最新は v1.19.3-eksbuild.1 だったので、厳密にそうなっているとは限りませんが...

組み込みネットワーキングアドオンとしてインストールされる VPC CNI plugin(aws-node) は下記のような構成でした。

% kubectl describe ds aws-node -n kube-system
Name:           aws-node
Selector:       k8s-app=aws-node
Node-Selector:  <none>
Labels:         app.kubernetes.io/instance=aws-vpc-cni
                app.kubernetes.io/managed-by=Helm
                app.kubernetes.io/name=aws-node
                app.kubernetes.io/version=v1.19.2
                helm.sh/chart=aws-vpc-cni-1.19.2
                k8s-app=aws-node
Annotations:    deprecated.daemonset.template.generation: 1
Desired Number of Nodes Scheduled: 1
Current Number of Nodes Scheduled: 1
Number of Nodes Scheduled with Up-to-date Pods: 1
Number of Nodes Scheduled with Available Pods: 1
Number of Nodes Misscheduled: 0
Pods Status:  1 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:           app.kubernetes.io/instance=aws-vpc-cni
                    app.kubernetes.io/name=aws-node
                    k8s-app=aws-node
  Service Account:  aws-node
  Init Containers:
   aws-vpc-cni-init:
    Image:      602401143452.dkr.ecr.ap-northeast-1.amazonaws.com/amazon-k8s-cni-init:v1.19.2-eksbuild.1
    Port:       <none>
    Host Port:  <none>
    Requests:
      cpu:  25m
    Environment:
      DISABLE_TCP_EARLY_DEMUX:  false
      ENABLE_IPv6:              false
    Mounts:
      /host/opt/cni/bin from cni-bin-dir (rw)
  Containers:
   aws-node:
    Image:      602401143452.dkr.ecr.ap-northeast-1.amazonaws.com/amazon-k8s-cni:v1.19.2-eksbuild.1
    Port:       61678/TCP
    Host Port:  0/TCP
    Requests:
      cpu:      25m
    Liveness:   exec [/app/grpc-health-probe -addr=:50051 -connect-timeout=5s -rpc-timeout=5s] delay=60s timeout=10s period=10s #success=1 #failure=3
    Readiness:  exec [/app/grpc-health-probe -addr=:50051 -connect-timeout=5s -rpc-timeout=5s] delay=1s timeout=10s period=10s #success=1 #failure=3
    Environment:
      ADDITIONAL_ENI_TAGS:                    {}
      ANNOTATE_POD_IP:                        false
      AWS_VPC_CNI_NODE_PORT_SUPPORT:          true
      AWS_VPC_ENI_MTU:                        9001
      AWS_VPC_K8S_CNI_CUSTOM_NETWORK_CFG:     false
      AWS_VPC_K8S_CNI_EXTERNALSNAT:           false
      AWS_VPC_K8S_CNI_LOGLEVEL:               DEBUG
      AWS_VPC_K8S_CNI_LOG_FILE:               /host/var/log/aws-routed-eni/ipamd.log
      AWS_VPC_K8S_CNI_RANDOMIZESNAT:          prng
      AWS_VPC_K8S_CNI_VETHPREFIX:             eni
      AWS_VPC_K8S_PLUGIN_LOG_FILE:            /var/log/aws-routed-eni/plugin.log
      AWS_VPC_K8S_PLUGIN_LOG_LEVEL:           DEBUG
      CLUSTER_NAME:                           test-cluster
      DISABLE_INTROSPECTION:                  false
      DISABLE_METRICS:                        false
      DISABLE_NETWORK_RESOURCE_PROVISIONING:  false
      ENABLE_IPv4:                            true
      ENABLE_IPv6:                            false
      ENABLE_POD_ENI:                         false
      ENABLE_PREFIX_DELEGATION:               false
      ENABLE_SUBNET_DISCOVERY:                true
      NETWORK_POLICY_ENFORCING_MODE:          standard
      VPC_CNI_VERSION:                        v1.19.2
      VPC_ID:                                 vpc-045760c352cc63fdb
      WARM_ENI_TARGET:                        1
      WARM_PREFIX_TARGET:                     1
      MY_NODE_NAME:                            (v1:spec.nodeName)
      MY_POD_NAME:                             (v1:metadata.name)
    Mounts:
      /host/etc/cni/net.d from cni-net-dir (rw)
      /host/opt/cni/bin from cni-bin-dir (rw)
      /host/var/log/aws-routed-eni from log-dir (rw)
      /run/xtables.lock from xtables-lock (rw)
      /var/run/aws-node from run-dir (rw)
   aws-eks-nodeagent:
    Image:      602401143452.dkr.ecr.ap-northeast-1.amazonaws.com/amazon/aws-network-policy-agent:v1.1.6-eksbuild.1
    Port:       <none>
    Host Port:  <none>
    Args:
      --enable-ipv6=false
      --enable-network-policy=false
      --enable-cloudwatch-logs=false
      --enable-policy-event-logs=false
      --log-file=/var/log/aws-routed-eni/network-policy-agent.log
      --metrics-bind-addr=:8162
      --health-probe-bind-addr=:8163
      --conntrack-cache-cleanup-period=300
    Requests:
      cpu:  25m
    Environment:
      MY_NODE_NAME:   (v1:spec.nodeName)
    Mounts:
      /host/opt/cni/bin from cni-bin-dir (rw)
      /sys/fs/bpf from bpf-pin-path (rw)
      /var/log/aws-routed-eni from log-dir (rw)
      /var/run/aws-node from run-dir (rw)
  Volumes:
   bpf-pin-path:
    Type:          HostPath (bare host directory volume)
    Path:          /sys/fs/bpf
    HostPathType:
   cni-bin-dir:
    Type:          HostPath (bare host directory volume)
    Path:          /opt/cni/bin
    HostPathType:
   cni-net-dir:
    Type:          HostPath (bare host directory volume)
    Path:          /etc/cni/net.d
    HostPathType:
   log-dir:
    Type:          HostPath (bare host directory volume)
    Path:          /var/log/aws-routed-eni
    HostPathType:  DirectoryOrCreate
   run-dir:
    Type:          HostPath (bare host directory volume)
    Path:          /var/run/aws-node
    HostPathType:  DirectoryOrCreate
   xtables-lock:
    Type:               HostPath (bare host directory volume)
    Path:               /run/xtables.lock
    HostPathType:       FileOrCreate
  Priority Class Name:  system-node-critical
  Node-Selectors:       <none>
  Tolerations:          op=Exists
Events:
  Type    Reason            Age    From                  Message
  ----    ------            ----   ----                  -------
  Normal  SuccessfulCreate  5m36s  daemonset-controller  Created pod: aws-node-ththm

kube-proxy は下記のような構成でした。

% kubectl describe ds kube-proxy -n kube-system
Name:           kube-proxy
Selector:       k8s-app=kube-proxy
Node-Selector:  <none>
Labels:         eks.amazonaws.com/component=kube-proxy
                k8s-app=kube-proxy
Annotations:    deprecated.daemonset.template.generation: 1
Desired Number of Nodes Scheduled: 1
Current Number of Nodes Scheduled: 1
Number of Nodes Scheduled with Up-to-date Pods: 1
Number of Nodes Scheduled with Available Pods: 1
Number of Nodes Misscheduled: 0
Pods Status:  1 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:           k8s-app=kube-proxy
  Service Account:  kube-proxy
  Containers:
   kube-proxy:
    Image:      602401143452.dkr.ecr.ap-northeast-1.amazonaws.com/eks/kube-proxy:v1.32.0-minimal-eksbuild.2
    Port:       <none>
    Host Port:  <none>
    Command:
      kube-proxy
      --v=2
      --config=/var/lib/kube-proxy-config/config
      --hostname-override=$(NODE_NAME)
    Requests:
      cpu:  100m
    Environment:
      NODE_NAME:   (v1:spec.nodeName)
    Mounts:
      /lib/modules from lib-modules (ro)
      /run/xtables.lock from xtables-lock (rw)
      /var/lib/kube-proxy-config/ from config (rw)
      /var/lib/kube-proxy/ from kubeconfig (rw)
      /var/log from varlog (rw)
  Volumes:
   varlog:
    Type:          HostPath (bare host directory volume)
    Path:          /var/log
    HostPathType:
   xtables-lock:
    Type:          HostPath (bare host directory volume)
    Path:          /run/xtables.lock
    HostPathType:  FileOrCreate
   lib-modules:
    Type:          HostPath (bare host directory volume)
    Path:          /lib/modules
    HostPathType:
   kubeconfig:
    Type:      ConfigMap (a volume populated by a ConfigMap)
    Name:      kube-proxy
    Optional:  false
   config:
    Type:               ConfigMap (a volume populated by a ConfigMap)
    Name:               kube-proxy-config
    Optional:           false
  Priority Class Name:  system-node-critical
  Node-Selectors:       <none>
  Tolerations:          op=Exists
Events:
  Type    Reason            Age   From                  Message
  ----    ------            ----  ----                  -------
  Normal  SuccessfulCreate  6m5s  daemonset-controller  Created pod: kube-proxy-vp46f

CoreDNS は下記のような構成でした。

$ kubectl describe deployment coredns -n kube-system
Name:                   coredns
Namespace:              kube-system
CreationTimestamp:      Sun, 13 Apr 2025 17:55:46 +0900
Labels:                 eks.amazonaws.com/component=coredns
                        k8s-app=kube-dns
                        kubernetes.io/name=CoreDNS
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               eks.amazonaws.com/component=coredns,k8s-app=kube-dns
Replicas:               2 desired | 2 updated | 2 total | 2 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  1 max unavailable, 25% max surge
Pod Template:
  Labels:           eks.amazonaws.com/component=coredns
                    k8s-app=kube-dns
  Service Account:  coredns
  Containers:
   coredns:
    Image:       602401143452.dkr.ecr.ap-northeast-1.amazonaws.com/eks/coredns:v1.11.4-eksbuild.2
    Ports:       53/UDP, 53/TCP, 9153/TCP
    Host Ports:  0/UDP, 0/TCP, 0/TCP
    Args:
      -conf
      /etc/coredns/Corefile
    Limits:
      memory:  170Mi
    Requests:
      cpu:        100m
      memory:     70Mi
    Liveness:     http-get http://:8080/health delay=60s timeout=5s period=10s #success=1 #failure=5
    Readiness:    http-get http://:8181/ready delay=0s timeout=1s period=10s #success=1 #failure=3
    Environment:  <none>
    Mounts:
      /etc/coredns from config-volume (ro)
  Volumes:
   config-volume:
    Type:                       ConfigMap (a volume populated by a ConfigMap)
    Name:                       coredns
    Optional:                   false
  Topology Spread Constraints:  topology.kubernetes.io/zone:ScheduleAnyway when max skew 1 is exceeded for selector k8s-app=kube-dns
  Priority Class Name:          system-cluster-critical
  Node-Selectors:               <none>
  Tolerations:                  CriticalAddonsOnly op=Exists
                                node-role.kubernetes.io/control-plane:NoSchedule
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   coredns-6d78c58c9f (2/2 replicas created)
Events:
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  8m43s  deployment-controller  Scaled up replica set coredns-6d78c58c9f from 0 to 2

この状態で対応するバージョンの EKS アドオンをインストールすると、aws-node の Pod のみ更新されました。
Deployment リソースや DaemonSet リソースに対して更新が入るのみだったので、Kubernetes リソースとしては置き換わることなく、EKS アドオン管理にできるようです。

NAME                           READY   STATUS    RESTARTS   AGE
pod/aws-node-n98dg             2/2     Running   0          114s
pod/coredns-6d78c58c9f-74mdl   1/1     Running   0          15m
pod/coredns-6d78c58c9f-wwlrf   1/1     Running   0          15m
pod/kube-proxy-vp46f           1/1     Running   0          11m

NAME                                TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                  AGE
service/eks-extension-metrics-api   ClusterIP   172.20.157.34   <none>        443/TCP                  16m
service/kube-dns                    ClusterIP   172.20.0.10     <none>        53/UDP,53/TCP,9153/TCP   15m

NAME                        DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
daemonset.apps/aws-node     1         1         1       1            1           <none>          15m
daemonset.apps/kube-proxy   1         1         1       1            1           <none>          15m

NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/coredns   2/2     2            2           15m

NAME                                 DESIRED   CURRENT   READY   AGE
replicaset.apps/coredns-6d78c58c9f   2         2         2       15m

バージョン更新を行っていないのに aws-node だけ Pod が更新された点について CLUSTER_ENDPOINT 変数が追加されていることが原因のようでした。

% diff before.yaml after.yaml
10c10
< Annotations:    deprecated.daemonset.template.generation: 1
---
> Annotations:    deprecated.daemonset.template.generation: 2
55a56
>       CLUSTER_ENDPOINT:                       https://FE778B17E18637D10DDB5D28A01F6444.gr7.ap-northeast-1.eks.amazonaws.com
129,131c130,134
<   Type    Reason            Age    From                  Message
<   ----    ------            ----   ----                  -------
<   Normal  SuccessfulCreate  5m36s  daemonset-controller  Created pod: aws-node-ththm
---
>   Type    Reason            Age   From                  Message
>   ----    ------            ----  ----                  -------
>   Normal  SuccessfulCreate  11m   daemonset-controller  Created pod: aws-node-ththm
>   Normal  SuccessfulDelete  82s   daemonset-controller  Deleted pod: aws-node-ththm
>   Normal  SuccessfulCreate  82s   daemonset-controller  Created pod: aws-node-n98dg
\ No newline at end of file

kube-proxy に依存せずに API Server と通信できるようにするための変数とのことで、アドオン経由でインストールすると自動でセットされるようです。

Type: String
Default: ""
Specifies the cluster endpoint to use for connecting to the api-server without relying on kube-proxy. This is an optional configuration parameter that can improve the initialization time of the AWS VPC CNI.
NOTE! When setting CLUSTER_ENDPOINT, it is STRONGLY RECOMMENDED that you enable private endpoint access for your API server, otherwise VPC CNI requests can traverse the public NAT gateway and may result in additional charges.
https://github.com/aws/amazon-vpc-cni-k8s?tab=readme-ov-file#cluster_endpoint-v1121

この状態から、下記のように EKS アドオンの設定を変更してみます。

module "eks" {
  source  = "terraform-aws-modules/eks/aws"
  version = "~> 20.35.0"

  cluster_name                    = local.cluster_name
  cluster_version                 = "1.32"
  cluster_endpoint_public_access  = true
  cluster_endpoint_private_access = true

  vpc_id     = module.vpc.vpc_id
  subnet_ids = module.vpc.private_subnets

  enable_cluster_creator_admin_permissions = true

  eks_managed_node_groups = {
    default = {
      name = "default"

      instance_types = ["t3.small"]

      min_size     = 1
      max_size     = 3
      desired_size = 1
    }
  }

  bootstrap_self_managed_addons = false

  cluster_addons = {
    coredns = {
      version = "v1.11.4-eksbuild.2"
    }
    kube-proxy = {
      version = "v1.32.0-eksbuild.2"
    }
    vpc-cni = {
      version        = "v1.19.3-eksbuild.1"
      before_compute = true
      configuration_values = jsonencode({
        env = {
          AWS_VPC_K8S_CNI_EXTERNALSNAT = "true"
          ENABLE_PREFIX_DELEGATION     = "true"
          WARM_PREFIX_TARGET           = "1"
        }
      })
    }
  }
}

VPC CNI plugin について、設定を追加しています。

Terraform will perform the following actions:

  # module.eks.aws_eks_addon.this["vpc-cni"] will be updated in-place
  ~ resource "aws_eks_addon" "this" {
      + configuration_values        = jsonencode(
            {
              + env = {
                  + AWS_VPC_K8S_CNI_EXTERNALSNAT = "true"
                  + ENABLE_PREFIX_DELEGATION     = "true"
                  + WARM_PREFIX_TARGET           = "1"
                }
            }
        )
        id                          = "test-cluster:vpc-cni"
        tags                        = {}
        # (11 unchanged attributes hidden)

        # (1 unchanged block hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

この場合も DaemonSet への変更扱いになり、Pod のみ更新されました。

% kubectl get all -n kube-system
NAME                           READY   STATUS    RESTARTS   AGE
pod/aws-node-rsrpd             2/2     Running   0          56s
pod/coredns-6d78c58c9f-74mdl   1/1     Running   0          24m
pod/coredns-6d78c58c9f-wwlrf   1/1     Running   0          24m
pod/kube-proxy-vp46f           1/1     Running   0          20m

NAME                                TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                  AGE
service/eks-extension-metrics-api   ClusterIP   172.20.157.34   <none>        443/TCP                  25m
service/kube-dns                    ClusterIP   172.20.0.10     <none>        53/UDP,53/TCP,9153/TCP   24m

NAME                        DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
daemonset.apps/aws-node     1         1         1       1            1           <none>          24m
daemonset.apps/kube-proxy   1         1         1       1            1           <none>          24m

NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/coredns   2/2     2            2           24m

NAME                                 DESIRED   CURRENT   READY   AGE
replicaset.apps/coredns-6d78c58c9f   2         2         2       24m

既存の Kubernetes リソースをそのまま EKS アドオン管理にできるようですね!

まとめ

EKS の組み込みネットワーキングアドオンについて調べてみました。

  • マネジメントコンソールで作成すると常に作成されないので、気にする必要がない
  • Terraform で作成する際も新規作成時は bootstrapSelfManagedAddons=false としておく方が良さそう
    • 特に Auto Mode 移行を考慮すると最初から false の方が都合が良さそう
  • インストール時にしか効かないパラメータのようなので、bootstrapSelfManagedAddons=true で作成したクラスターを無理に false に変更する必要はなさそう
  • 新しく EKS アドオンをインストールすれば、EKS アドオン管理に移行可能

この記事がどなたかのお役に立てば幸いです。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.