1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめてのEKS(マネジメントコンソール編)

Posted at

はじめに

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)に構築します。
構成図はこのようなイメージになります。

eks.drawio.png

VPCを作成する

以下ページの要件を満たすようにVPCとサブネットを作成します。

VPCを作成で作成するリソースにてVPCなどを選択し、サブネット(パブリック/プライベートを2つずつ)やNATゲートウェイをまとめて作成しました。
VPC要件よりDNSホスト名を有効化DNS解決を有効化にチェックを入れておきます。

image.png

image.png

image.png

作成後、サブネットにLBをデプロイするために必要なタグを付けます。

サブネット キー
パブリックサブネット kubernetes.io/role/elb 1
プライベートサブネット kubernetes.io/role/internal-elb 1
  • パブリックサブネット
    image.png

  • プライベートサブネット
    image.png

クラスターを作成する

IAMロールの作成

クラスターを作成する前にクラスター用のIAMロールを作成します。

ロールを作成からEKS - Clusterを選択してロールを作成します。
AmazonEKSClusterPolicyのポリシーがアタッチされたロールができます。

image.png

クラスターの作成

EKSの画面からクラスターを作成します。
ここではカスタム設定を選択し、EKSオートモードは使用せずに作成します。
クラスターIAMロールでは先ほど作成したクラスター用IAMロールを選択します。
image.png

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

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

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

オブザーバビリティの設定、アドオンの選択・構成はデフォルトのままとしました。

クラスターが作成できました。
アクティブになるまで約20分かかりました。
image.png

ノードグループを作成する

IAMロールの作成

クラスター同様、ノードグループ用のIAMロールを作成します。

ロールを作成からEC2を選択し、以下のポリシーをアタッチしたロールを作成します。

  • AmazonEC2ContainerRegistryPullOnly
  • AmazonEKS_CNI_Policy
  • AmazonEKSWorkerNodePolicy

image.png

ノードグループの作成

作成したクラスターの画面のコンピューティングタブのノードグループからノードグループを作成します。
ノードIAMロールでは先ほど作成したノードグループ用IAMロールを選択します。

image.png

コンピューティングとスケーリングの設定、ネットワークの設定を行い、ノードグループを作成します。
ネットワークはプライベートサブネットを指定しました。
image.png

ノードグループが作成できました。
image.png

クラスターにアクセスする

クラスター、ノードグループが作成できたので、端末からアクセスしてみます。

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を作成してみます。

test.yaml
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

作成したポリシーはマネジメントコンソールからも確認できます。
image.png

さらに、eksctlを使ってクラスターのOIDCプロバイダーを作成します。

eksctl utils associate-iam-oidc-provider --region=ap-northeast-1 --cluster=eks-cluster --approve

image.png

以下のコマンドで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を利用できることを確認します。

test_lb.yaml
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が作成されています。
image.png

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

(削除)

EKSはそれなりに料金がかかるので不要になったら削除しましょう。
ノードグループ→クラスター→VPCやサブネット→IAMポリシー/ロールの順で削除していきます。
NATゲートウェイを作成した場合、Elastic IPアドレスの削除(解放)も忘れずに行いましょう。

まとめ

マネジメントコンソールでEKSを作成し、AWS Load Balancer ControllerをインストールしてIngressによるALBの動作確認まで行いました。
必要なリソースや仕組みを理解するためにマネジメントコンソールで1つずつ作成していきましたが、なかなか大変だと感じたので次回はTerraformで作成してみたいと思います。

また、以前OCIのマネージドKubernetesサービスであるOKEを構築しましたが、OKEと比べてEKSはIAMやLB周りが難しいと感じました。(慣れの問題かもしれませんが)
これからAWSの知識についてももっと身に着けていきたいと思います。

お読みいただきありがとうございました。

参考文献

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?