EKS + ALB Ingress ControllerでEKS環境を構築する

はじめに

こんにちは、kanazawaです。
今回はALB Ingress Controllerを利用したEKS環境の構築をやってみます。

EKSでWebアプリを外部公開する際、ALBを手動で作成・設定するのは手間がかかります。
ALB Ingress Controllerを使うと、Kubernetesのマニフェストを適用するだけでALBが自動的に作成・設定されるため、インフラ管理の手間を大幅に削減できます。

本記事では、「eksctl」コマンドを利用してEKS on Fargateクラスターを構築し、ALB Ingress Controllerを導入してnginxを外部公開するまでの手順を紹介します。
検証目的の構成のため、本番環境へ適用する際は別途セキュリティや可用性の考慮が必要です。

1. 構成の説明

構成図

本記事では以下の構成でEKS環境を構築します。

構成概要

リソース名 説明
VPC 手動作成。
サブネット 手動作成。パブリック×2、プライベート×2
IGW 手動作成
NATゲートウェイ 手動作成
EC2 手動作成。操作用の踏み台サーバー。eksctl・kubectl・AWS CLIをインストールして使用
EKS on Fargate eksctlで構築。Fargateプロファイルを使用してPodをプライベートサブネットに配置
ALB ALB Ingress Controllerが自動作成。パブリックサブネットに配置
  • VPC・サブネット・IGW・NAT GWはeksctlでVPCを自動作成する際に合わせて作成可能ですが、本記事ではEC2を操作用の踏み台サーバーとして同じVPC内に配置します。
  • そのため、VPC・サブネット・IGW・NAT GWは事前に手動で作成しています。

eksctlについて

  • eksctlはEKSクラスターの構築・管理に特化したCLIツールです。
  • 内部的にはCloudFormationスタックでリソースを管理しており、eksctl delete clusterコマンド一つでクラスターに関連するリソースをまとめて削除できます。
  • yamlファイルでクラスター構成を定義できるため、構成をコードとして管理できます。

2. 事前準備

作成済みリソース

以下のリソースは事前に作成済みです。

リソース 備考
VPC
パブリックサブネット×2
プライベートサブネット×2
ルートテーブル
IGW
NAT GW
EC2用セキュリティグループ SSH(22番)操作者IPのみ許可
EC2 OSはAmazon Linux 2023、AdministratorAccessポリシーをアタッチ

ツールのインストール

EC2にSSH接続し、以下のツールをインストールします。

AWS CLI

  • AmazonLinux2023には標準でインストールされているので省略します。
# aws --version
aws-cli/2.33.15 Python/3.9.25 Linux/6.18.36-69.138.amzn2023.x86_64 source/x86_64.amzn.2023

eksctl

[root@ip-10-0-10-36 ~]# ARCH=amd64
[root@ip-10-0-10-36 ~]# PLATFORM=$(uname -s)_$ARCH
[root@ip-10-0-10-36 ~]# curl -sLO "https://github.com/eksctl-io/eksctl/releases/latest/download/eksctl_$PLATFORM.tar.gz"
[root@ip-10-0-10-36 ~]# curl -sL "https://github.com/eksctl-io/eksctl/releases/latest/download/eksctl_checksums.txt" | grep $PLATFORM | sha256sum --check
eksctl_Linux_amd64.tar.gz: OK
[root@ip-10-0-10-36 ~]# tar -xzf eksctl_$PLATFORM.tar.gz -C /tmp && rm eksctl_$PLATFORM.tar.gz
rm: remove regular file 'eksctl_Linux_amd64.tar.gz'? y
[root@ip-10-0-10-36 ~]# install -m 0755 /tmp/eksctl /usr/local/bin && rm /tmp/eksctl
rm: remove regular file '/tmp/eksctl'? y
[root@ip-10-0-10-36 ~]# eksctl version
0.229.0

kubectl

[root@ip-10-0-10-36 ~]# curl -O https://s3.us-west-2.amazonaws.com/amazon-eks/1.35.3/2026-04-08/bin/linux/amd64/kubectl
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 57232k 100 57232k   0     0 22547k     0   0:00:02  0:00:02 --:--:-- 22550k
[root@ip-10-0-10-36 ~]# curl -O https://s3.us-west-2.amazonaws.com/amazon-eks/1.35.3/2026-04-08/bin/linux/amd64/kubectl.sha256
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    73 100    73   0     0   226     0  --:--:-- --:--:-- --:--:--   226
[root@ip-10-0-10-36 ~]# sha256sum -c kubectl.sha256
kubectl: OK
[root@ip-10-0-10-36 ~]# chmod +x ./kubectl
[root@ip-10-0-10-36 ~]# mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$HOME/bin:$PATH
[root@ip-10-0-10-36 ~]# kubectl version --client
Client Version: v1.35.3-eks-bbe087e
Kustomize Version: v5.7.1

3. EKSクラスター構築

クラスター設定ファイルの作成

eksctlはyamlファイルでクラスター構成を定義できます。
以下の内容でcluster.yamlを作成します。

apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: kanazawa-cluster-test
  region: ap-northeast-1
  version: "1.35"

vpc:
  id: <vpc-id>
  subnets:
    public:
      ap-northeast-1a:
        id: <public-subnet-id-1a>
      ap-northeast-1c:
        id: <public-subnet-id-1c>
    private:
      ap-northeast-1a:
        id: <private-subnet-id-1a>
      ap-northeast-1c:
        id: <private-subnet-id-1c>

fargateProfiles:
  - name: default
    selectors:
      - namespace: default
      - namespace: kube-system

各IDは実際に作成したリソースのIDに置き換えてください。

項目 説明
metadata.name クラスター名
metadata.version Kubernetesのバージョン
vpc.id 事前に作成したVPCのID
vpc.subnets.public 事前に作成したパブリックサブネットのID(ALBが配置される)
vpc.subnets.private 事前に作成したプライベートサブネットのID(Fargate Podが配置される)
fargateProfiles Fargateで動かすPodのnamespaceを指定。kube-systemはALB Ingress Controllerのために必要

クラスターの作成

以下のコマンドでクラスターを作成します。
完了まで15〜20分程度かかります。

eksctl create cluster -f <yamlファイル名>

完了すると以下のように表示されます。

[root@ip-10-0-10-36 ~]# eksctl create cluster -f ~/work/cluster.yaml
~~~中略~~~
2026-07-14 08:26:46 [✔]  EKS cluster "kanazawa-cluster-test" in "ap-northeast-1" region is ready

作成されたリソースの確認

eksctlで作成されたリソースをAWSコンソール画面から確認してみます。
CloudFormationで「eksctl-<クラスター名>-cluster」という名前のスタックからリソースが確認できます。

kubeconfigの更新

クラスター作成後、kubectlでクラスターを操作できるようにkubeconfigを更新します。

[root@ip-10-0-10-36 ~]# aws eks update-kubeconfig --region ap-northeast-1 --name <クラスター名>
Updated context arn:aws:eks:ap-northeast-1:<アカウントID>:cluster/<クラスター名> in /root/.kube/config

動作確認

クラスターに接続できることを確認します。

[root@ip-10-0-10-36 ~]# kubectl get nodes
NAME                                                     STATUS   ROLES    AGE     VERSION
fargate-ip-10-0-30-144.ap-northeast-1.compute.internal   Ready    <none>   7m47s   v1.35.6-eks-434a228
fargate-ip-10-0-30-58.ap-northeast-1.compute.internal    Ready    <none>   7m50s   v1.35.6-eks-434a228
fargate-ip-10-0-40-126.ap-northeast-1.compute.internal   Ready    <none>   9m2s    v1.35.6-eks-434a228
fargate-ip-10-0-40-209.ap-northeast-1.compute.internal   Ready    <none>   9m1s    v1.35.6-eks-434a228

FargateノードがReady状態になっていれば、クラスターの構築は完了です。
ここで4つのノードが表示されていますが、これはFargateの仕組みによるものです。
FargateではPodが1つ起動するとノードも1つ割り当てられます。EC2のように複数のPodが同じノードで動くのではなく、Pod専用のノードが都度起動します。
今回は「kube-system」namespaceにcoreDNSが2Pod、kube-proxyが2Pod(AZ×2)起動しているため、合計4ノードになっています。

4. ALB Ingress Controllerの導入

AWS Load Balancer Controller(ALB Ingress Controller)は、KubernetesのIngressリソースを検知してALBを自動的に作成・設定することができます。
本章では公式ドキュメントの手順に沿ってインストールします。

Helmのインストール

AWS Load Balancer ControllerはHelmを使ってインストールします。
Helmはkubernetes用のパッケージマネージャーで、複雑なKubernetesアプリケーションを簡単にインストール・管理できます。

Helmのインストールは公式ドキュメントの手順を参考にします。

[root@ip-10-0-10-36 ~]# curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-4
[root@ip-10-0-10-36 ~]# chmod 700 get_helm.sh
[root@ip-10-0-10-36 ~]# ./get_helm.sh
[WARNING] Could not find git. It is required for plugin installation.
Downloading https://get.helm.sh/helm-v4.2.3-linux-amd64.tar.gz
Verifying checksum... Done.
Preparing to install helm into /usr/local/bin
helm installed into /usr/local/bin/helm
[root@ip-10-0-10-36 ~]# helm version
version.BuildInfo{Version:"v4.2.3", GitCommit:"43e8b7feece8beb0fcba47059ec9b522fd929a64", GitTreeState:"clean", GoVersion:"go1.26.5", KubeClientVersion:"v1.36"}

OIDCプロバイダーの設定

AWS Load Balancer ControllerがAWSのリソース(ALBなど)を操作するにはIAM権限が必要です。
KubernetesのPodにIAM権限を付与する仕組みとしてIRSAがあります。IRSAを使うには、まずEKSクラスターにOIDCプロバイダーを関連付ける必要があります。

OIDCプロバイダーとは、KubernetesのサービスアカウントとAWS IAMロールを紐付けるための認証基盤です。これを設定することで、特定のPodに対してのみ必要なIAM権限を付与できます。

以下のコマンドでOIDCプロバイダーを作成します。

[root@ip-10-0-10-36 ~]# eksctl utils associate-iam-oidc-provider \
    --region ap-northeast-1 \
    --cluster kanazawa-cluster-test \
    --approve

実行すると以下のように表示されます。

2026-07-14 09:37:46 [ℹ]  will create IAM Open ID Connect provider for cluster "kanazawa-cluster-test" in "ap-northeast-1"
2026-07-14 09:37:47 [✔]  created IAM Open ID Connect provider for cluster "kanazawa-cluster-test" in "ap-northeast-1"

コンソール画面でも確認ができます。

サブネットへのタグ付け

AWS Load Balancer Controllerは、ALBを配置するサブネットをタグで自動検出します。
eksctlでVPCを自動作成した場合はタグが自動で付与されますが、今回は手動でVPCを作成しているため、手動でタグを付与する必要があります。

AWSコンソールのVPC → サブネットから以下のタグを追加してください。

パブリックサブネット×2

キー
kubernetes.io/role/elb 1
kubernetes.io/cluster/<クラスター名> shared

プライベートサブネット×2

キー
kubernetes.io/role/internal-elb 1
kubernetes.io/cluster/<クラスター名> shared

IAMポリシーの作成

AWS Load Balancer ControllerがALBを操作するために必要なIAMポリシーを作成します。
ポリシーの内容はAWSが公式に提供しているものを使用します。

[root@ip-10-0-10-36 ~]# curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.14.1/docs/install/iam_policy.json
[root@ip-10-0-10-36 ~]# aws iam create-policy \
    --policy-name AWSLoadBalancerControllerIAMPolicy \
    --policy-document file://iam_policy.json

IAMロール・サービスアカウントの作成

作成したIAMポリシーをアタッチしたIAMロールと、それに紐付くKubernetesサービスアカウントを作成します。
サービスアカウントとは、PodがKubernetesやAWSのAPIを呼び出す際に使用するアカウントです。

[root@ip-10-0-10-36 ~]# eksctl create iamserviceaccount \
    --cluster=<クラスター名> \
    --namespace=kube-system \
    --name=aws-load-balancer-controller \
    --attach-policy-arn=arn:aws:iam::<アカウントID>:policy/AWSLoadBalancerControllerIAMPolicy \
    --override-existing-serviceaccounts \
    --region ap-northeast-1 \
    --approve

先ほど作成したポリシーがロールにアタッチされていることが確認できました。

AWS Load Balancer ControllerをHelmでインストール

HelmにAWSのリポジトリを追加し、AWS Load Balancer Controllerをインストールします。

[root@ip-10-0-10-36 ~]# helm repo add eks https://aws.github.io/eks-charts
"eks" has been added to your repositories
[root@ip-10-0-10-36 ~]# 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!⎈
[root@ip-10-0-10-36 ~]# helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
    -n kube-system \
    --set clusterName=<クラスター名> \
    --set serviceAccount.create=false \
    --set serviceAccount.name=aws-load-balancer-controller \
    --set region=ap-northeast-1 \
    --set vpcId=<VPC ID>

以下のように表示されていれば正常にインストールされています。

NAME: aws-load-balancer-controller
LAST DEPLOYED: Tue Jul 14 10:17:50 2026
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
TEST SUITE: None
NOTES:
AWS Load Balancer controller installed!

動作確認

AWS Load Balancer ControllerのPodが正常に起動していることを確認します。

[root@ip-10-0-10-36 ~]# 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           2m25s

READY2/2になっていれば、AWS Load Balancer Controllerの導入は完了です。

5. nginxのデプロイ

本章ではnginxの公式イメージを使用してDeployment・Service・Ingressを作成し、ALB経由で外部公開します。

マニフェストファイルの作成

作成するファイルの役割は以下の通りです。

ファイル 役割
deployment.yaml Deployment: nginxのコンテナをどう動かすかを定義。何個起動するか、どのイメージを使うかなどを指定
service.yaml Service: DeploymentのPodへのアクセス窓口。IngressからPodへトラフィックを届けるために必要
ingress.yaml Ingress: 外部からのHTTPアクセスをどのServiceに転送するかを定義。AWS Load Balancer Controllerがこのリソースを検知してALBを自動作成

トラフィックの流れは「ALB → Ingress → Service → Pod」の順になります。

3つのファイルを作成します。

~/work/deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: default
spec:
  replicas: 2          # Podを2つ起動
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx     # ServiceやIngressと紐付けるためのラベル
    spec:
      containers:
        - name: nginx
          image: nginx:latest
          ports:
            - containerPort: 80  # コンテナが受け付けるポート

~/work/service.yaml

apiVersion: v1
kind: Service
metadata:
  name: nginx
  namespace: default
spec:
  selector:
    app: nginx       # ラベルが一致するPodにトラフィックを転送
  ports:
    - protocol: TCP
      port: 80       # Serviceが受け付けるポート
      targetPort: 80 # 転送先のPodのポート

~/work/ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx
  namespace: default
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing         # パブリックALBを作成
    alb.ingress.kubernetes.io/target-type: ip                 # FargateではIPモードが必須
    alb.ingress.kubernetes.io/inbound-cidrs: x.x.x.x/32      # アクセスを許可するIP
spec:
  ingressClassName: alb  # ALBを使用
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx  # トラフィックの転送先Service
                port:
                  number: 80

デプロイ

以下のコマンドで各マニフェストを適用します。

[root@ip-10-0-10-36 ~]# kubectl apply -f ~/work/deployment.yaml
deployment.apps/nginx created
[root@ip-10-0-10-36 ~]# kubectl apply -f ~/work/service.yaml
service/nginx created
[root@ip-10-0-10-36 ~]# kubectl apply -f ~/work/ingress.yaml
ingress.networking.k8s.io/nginx created

動作確認

ALBのDNS名を確認します。Ingressが作成されるとAWS Load Balancer ControllerがALBを自動作成します。

[root@ip-10-0-10-36 ~]# kubectl get ingress -n default
NAME    CLASS   HOSTS   ADDRESS                                                                 PORTS   AGE
nginx   alb     *       <alb-dns-name>.ap-northeast-1.elb.amazonaws.com                        80      5m13s

ADDRESSにALBのDNS名が表示されたら、ブラウザでアクセスしてnginxのデフォルトページが表示されることを確認します。

http://<alb-dns-name>.ap-northeast-1.elb.amazonaws.com

nginxのデフォルトページが表示されれば、デプロイは完了です。

6. まとめ

本記事では、eksctlを使ってEKS on Fargate環境を構築し、AWS Load Balancer Controllerを導入してnginxをALB経由で外部公開するまでの手順を紹介しました。
AWS Load Balancer Controllerを使うことで、IngressリソースをapplyするだけでALBが自動的に作成されます。
また、ALBの設定をyamlファイルで管理できるため、設定の変更や再現が容易です。

7. 補足

検証目的で環境構築した場合など、環境が不要になった場合は以下のコマンドでクラスターに関連するリソースをまとめて削除できます。
AWS Load Balancer Controllerが作成したALBはeksctlの管理外のため、先にIngressを削除してALBを削除してからeksctl delete clusterコマンドを実行します。

kubectl delete -f ~/<作業フォルダ>/ingress.yaml
eksctl delete cluster -f ~/<作業フォルダ>/cluster.yaml

また、手動で作成したリソースは、eksctl delete clusterでは削除されないため、NATゲートウェイなどの削除忘れに注意してください。