はじめに
AWSのマネージドKubernetesサービスである Amazon Elastic Kubernetes Service(EKS) を構築してみたので記事にしました。
eksctlを使った構築方法もありますが、今回はマネジメントコンソールを使って構築しました。
クラスターを作成し、IngressでALBを使えるようにするところまで行いました。
なおEKSオートモードは使用せず、マネージドノードグループで構築しました。
事前準備
作業に使う各種コマンドを端末にインストールしておきます。
端末はWindows11を使用しています。
AWS CLI
> msiexec.exe /i https://awscli.amazonaws.com/AWSCLIV2.msi
> aws --version
aws-cli/2.32.28 Python/3.13.11 Windows/11 exe/AMD64
> aws configure
AWS Access Key ID [None]: XXXXXXXXXXXXXX
AWS Secret Access Key [None]: XXXXXXXXXXXXXXXXXXXXXXXXXXXX
Default region name [None]: ap-northeast-1
Default output format [None]: json
eksctl
ダウンロードして解凍します。
> eksctl version
0.221.0
kubectl
> curl.exe -LO "https://dl.k8s.io/release/v1.35.0/bin/windows/amd64/kubectl.exe"
> kubectl version --client
Client Version: v1.35.0
Kustomize Version: v5.7.1
Helm
ダウンロードして解凍します。
> helm version
version.BuildInfo{Version:"v4.0.4", GitCommit:"8650e1dad9e6ae38b41f60b712af9218a0d8cc11", GitTreeState:"clean", GoVersion:"go1.25.5", KubeClientVersion:"v1.34"}
EKS構築
東京リージョン(ap-northeast-1)に構築します。
構成図はこのようなイメージになります。
VPCを作成する
以下ページの要件を満たすようにVPCとサブネットを作成します。
VPCを作成で作成するリソースにてVPCなどを選択し、サブネット(パブリック/プライベートを2つずつ)やNATゲートウェイをまとめて作成しました。
VPC要件よりDNSホスト名を有効化とDNS解決を有効化にチェックを入れておきます。
作成後、サブネットにLBをデプロイするために必要なタグを付けます。
| サブネット | キー | 値 |
|---|---|---|
| パブリックサブネット | kubernetes.io/role/elb | 1 |
| プライベートサブネット | kubernetes.io/role/internal-elb | 1 |
クラスターを作成する
IAMロールの作成
クラスターを作成する前にクラスター用のIAMロールを作成します。
ロールを作成からEKS - Clusterを選択してロールを作成します。
AmazonEKSClusterPolicyのポリシーがアタッチされたロールができます。
クラスターの作成
EKSの画面からクラスターを作成します。
ここではカスタム設定を選択し、EKSオートモードは使用せずに作成します。
クラスターIAMロールでは先ほど作成したクラスター用IAMロールを選択します。

クラスターアクセスではクラスター管理者アクセスを許可、クラスター認証モードはEKS APIとします。

ネットワーキングでは先ほど作成したVPCとプライベートサブネットをそれぞれ選択します。

クラスターエンドポイントアクセスはパブリックおよびプライベートとし、アクセス可能なCIDRブロックを制限します。

オブザーバビリティの設定、アドオンの選択・構成はデフォルトのままとしました。
クラスターが作成できました。
アクティブになるまで約20分かかりました。

ノードグループを作成する
IAMロールの作成
クラスター同様、ノードグループ用のIAMロールを作成します。
ロールを作成からEC2を選択し、以下のポリシーをアタッチしたロールを作成します。
- AmazonEC2ContainerRegistryPullOnly
- AmazonEKS_CNI_Policy
- AmazonEKSWorkerNodePolicy
ノードグループの作成
作成したクラスターの画面のコンピューティングタブのノードグループからノードグループを作成します。
ノードIAMロールでは先ほど作成したノードグループ用IAMロールを選択します。
コンピューティングとスケーリングの設定、ネットワークの設定を行い、ノードグループを作成します。
ネットワークはプライベートサブネットを指定しました。

クラスターにアクセスする
クラスター、ノードグループが作成できたので、端末からアクセスしてみます。
kubeconfigの作成
AWS CLIを使ってkubeconfigを作成します。
> aws eks update-kubeconfig --region ap-northeast-1 --name eks-cluster
Added new context arn:aws:eks:ap-northeast-1:xxxxxxxxxxxx:cluster/eks-cluster to <ホームディレクトリ>\.kube\config
端末にkubeconfigが作成され、kubectlでクラスターにアクセスできるようになります。
- 確認
> kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
ip-10-1-137-165.ap-northeast-1.compute.internal Ready <none> 2m18s v1.34.2-eks-ecaa3a6 10.1.137.165 <none> Amazon Linux 2023.9.20251208 6.12.58-82.121.amzn2023.x86_64 containerd://2.1.5
デプロイテスト
以下のtest.yamlを用意し、構築したEKSクラスターにPodを作成してみます。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-dep
spec:
selector:
matchLabels:
app: test-kube
replicas: 3
template:
metadata:
labels:
app: test-kube
spec:
containers:
- name: test-pod
image: nginx:latest
ports:
- containerPort: 80
applyします。
> kubectl apply -f test.yaml
deployment.apps/nginx-dep created
> kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-dep-5db59bb568-d6jxk 1/1 Running 0 8s
nginx-dep-5db59bb568-gpljj 1/1 Running 0 8s
nginx-dep-5db59bb568-ndzcf 1/1 Running 0 8s
無事Podが作成されました!
ロードバランサ(ALB)を使う
EKSではIngressをapplyすることでALBを利用することができます。
ただし、事前にクラスターにAWS Load Balancer Controllerをインストールする必要があるので、インストールを行っていきます。
以下ページに従い、Helmを使ってインストールします。
IAMを設定する(IRSA)
以下のコマンドでAWS Load Balancer Controller用のカスタマー管理ポリシー(AWSLoadBalancerControllerIAMPolicy)を作成します。
> curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.13.3/docs/install/iam_policy.json
> aws iam create-policy \
--policy-name AWSLoadBalancerControllerIAMPolicy \
--policy-document file://iam_policy.json
作成したポリシーはマネジメントコンソールからも確認できます。

さらに、eksctlを使ってクラスターのOIDCプロバイダーを作成します。
eksctl utils associate-iam-oidc-provider --region=ap-northeast-1 --cluster=eks-cluster --approve
以下のコマンドでKubernetesのServiceAccountとIAMロールを作成して、IAMポリシーを紐づけます。
これにより、Load Balancer ControllerのPodがIAMポリシーの権限を使ってAWSのAPIを利用できるようになります。
この仕組みを IAM Roles for Service Accounts(IRSA) と呼ぶそうです。
> eksctl create iamserviceaccount \
--cluster=eks-cluster \
--namespace=kube-system \
--name=aws-load-balancer-controller \
--attach-policy-arn=arn:aws:iam::xxxxxxxxxxxx:policy/AWSLoadBalancerControllerIAMPolicy \
--override-existing-serviceaccounts \
--region ap-northeast-1 \
--approve
OIDCプロバイダーが未作成の場合、上記コマンドはエラーになります。
2026-01-04 17:02:01 [!] no IAM OIDC provider associated with cluster, try 'eksctl utils associate-iam-oidc-provider --region=ap-northeast-1 --cluster=eks-cluster'
Error: unable to create iamserviceaccount(s) without IAM OIDC provider enabled
作成されたServiceAccountはこのようになっています。
> kubectl get sa -n kube-system -o yaml aws-load-balancer-controller
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::xxxxxxxxxxxx:role/eksctl-eks-cluster-addon-iamserviceaccount-ku-Role1-RChKA35ySDtb
creationTimestamp: "2026-01-05T13:36:35Z"
labels:
app.kubernetes.io/managed-by: eksctl
name: aws-load-balancer-controller
namespace: kube-system
resourceVersion: "7460"
uid: b568eabe-8944-41e1-9060-71bf1ebf8629
AWS Load Balancer Controllerをインストールする
Helmを使ってクラスターにAWS Load Balancer Controllerをインストールします。
まずHelmリポジトリを追加します。
> helm repo add eks https://aws.github.io/eks-charts
"eks" has been added to your repositories
> helm repo update eks
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "eks" chart repository
Update Complete. ⎈Happy Helming!⎈
> helm repo list
NAME URL
eks https://aws.github.io/eks-charts
インストールします。
> helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
-n kube-system \
--set clusterName=eks-cluster \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller \
--set region=ap-northeast-1 \ ★
--set vpcId=vpc-XXXXXXXXXXXXXXXXX \ ★
--version 1.13.0
regionおよびvpcId(★)がないとaws-load-balancer-controllerのPodがCrashLoopBackOffになってしまい正常に起動しませんでした。
> kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
aws-load-balancer-controller-77c74555d-lpnwp 0/1 CrashLoopBackOff 3 (18s ago) 93s
aws-load-balancer-controller-77c74555d-tx8qj 0/1 CrashLoopBackOff 3 (19s ago) 93s
> kubectl logs -n kube-system aws-load-balancer-controller-77c74555d-lpnwp
{"level":"info","ts":"2026-01-04T08:13:20Z","msg":"version","GitVersion":"v2.13.0","GitCommit":"6e9183e8e95d655faa3e62ab6e4b92ba8fb6e8a7","BuildDate":"2025-05-06T22:30:14+0000"}
{"level":"error","ts":"2026-01-04T08:13:25Z","logger":"setup","msg":"unable to initialize AWS cloud","error":"failed to get VPC ID: failed to fetch VPC ID from instance metadata: error in fetching vpc id through ec2 metadata: get mac metadata: operation error ec2imds: GetMetadata, canceled, context deadline exceeded"}
- 確認
> kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
aws-load-balancer-controller-d86c648c6-4n2xw 1/1 Running 0 19s
aws-load-balancer-controller-d86c648c6-759vv 1/1 Running 0 19s
> kubectl get deployment -n kube-system aws-load-balancer-controller
NAME READY UP-TO-DATE AVAILABLE AGE
aws-load-balancer-controller 2/2 2 2 23s
デプロイテスト
以下のtest_lb.yamlを用意し、ALBを利用できることを確認します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-dep
spec:
selector:
matchLabels:
app: test-kube
replicas: 3
template:
metadata:
labels:
app: test-kube
spec:
containers:
- name: test-pod
image: nginx:latest
ports:
- containerPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
# ポート設定
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}]'
# 固定レスポンスアクション定義
alb.ingress.kubernetes.io/actions.response-404: >
{"type":"fixed-response","fixedResponseConfig":{"contentType":"text/plain","statusCode":"404","messageBody":"The requested resource was not found."}}
spec:
ingressClassName: alb
# デフォルトバックエンド定義
defaultBackend:
service:
name: response-404
port:
name: use-annotation
# ルーティングルール
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
namespace: default
spec:
selector:
app: test-kube
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
applyします。
> kubectl apply -f test_lb.yaml
deployment.apps/nginx-dep created
ingress.networking.k8s.io/nginx-ingress created
service/nginx-service created
> kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-dep 3/3 3 3 46s
> kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-dep-5db59bb568-66vgq 1/1 Running 0 65s
nginx-dep-5db59bb568-jllf5 1/1 Running 0 65s
nginx-dep-5db59bb568-v7d48 1/1 Running 0 65s
> kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 172.20.0.1 <none> 443/TCP 52m
nginx-service ClusterIP 172.20.142.46 <none> 80/TCP 80s
> kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
nginx-ingress alb * k8s-default-nginxing-xxxxxxxxxx-xxxxxxxxxx.ap-northeast-1.elb.amazonaws.com 80 95s
マネジメントコンソールを確認するとALBが作成されています。

http://<ALBのDNS名>にアクセスするとWelcome to nginx!が表示されました!

(削除)
EKSはそれなりに料金がかかるので不要になったら削除しましょう。
ノードグループ→クラスター→VPCやサブネット→IAMポリシー/ロールの順で削除していきます。
NATゲートウェイを作成した場合、Elastic IPアドレスの削除(解放)も忘れずに行いましょう。
まとめ
マネジメントコンソールでEKSを作成し、AWS Load Balancer ControllerをインストールしてIngressによるALBの動作確認まで行いました。
必要なリソースや仕組みを理解するためにマネジメントコンソールで1つずつ作成していきましたが、なかなか大変だと感じたので次回はTerraformで作成してみたいと思います。
また、以前OCIのマネージドKubernetesサービスであるOKEを構築しましたが、OKEと比べてEKSはIAMやLB周りが難しいと感じました。(慣れの問題かもしれませんが)
これからAWSの知識についてももっと身に着けていきたいと思います。
お読みいただきありがとうございました。
参考文献










