EKS Fargate を使用して ALB の背後にあるプライベートサブネットでコンテナを実行する方法

EKS Fargate を使用して ALB の背後にあるプライベートサブネットでコンテナを実行する方法

岩佐 孝浩
岩佐 孝浩
21 min read
ALB EKS Fargate

はじめに

この投稿では、プライベートサブネット内で EKS Fargate を使用してコンテナを実行し、Application Load Balancer (ALB) の背後で安全に管理する方法を解説します。Virtual Private Cloud (VPC) の設定、サブネットの作成、AWS 上でのサンプルアプリケーションのデプロイ手順について説明します。

前提条件

このチュートリアルを進めるには、以下のツールをインストールしていることを確認してください。

VPC のセットアップ

VPC の作成

以下のコマンドを使用して、専用 VPC を作成します。

aws ec2 create-vpc \
  --cidr-block 192.168.0.0/16 \
  --tag-specifications "ResourceType=vpc,Tags=[{Key=Name,Value=eks-fargate-vpc}]"

aws ec2 modify-vpc-attribute \
  --vpc-id vpc-xxxxxxxxxxxxxxxxx \
  --enable-dns-hostnames

If you use custom DNS domain names defined in a private hosted zone in Amazon Route 53, or use private DNS with interface VPC endpoints (AWS PrivateLink), you must set both the enableDnsHostnames and enableDnsSupport attributes to true.

サブネットの追加

Fargate ポッド用プライベートサブネット踏み台 EC2 インスタンス用パブリックサブネット を作成します。

aws ec2 create-subnet \
  --vpc-id vpc-xxxxxxxxxxxxxxxxx \
  --availability-zone ap-northeast-1a \
  --cidr-block 192.168.0.0/20 \
  --tag-specifications "ResourceType=subnet,Tags=[{Key=Name,Value=eks-fargate-private-subnet-1a}]"

aws ec2 create-subnet \
  --vpc-id vpc-xxxxxxxxxxxxxxxxx \
  --availability-zone ap-northeast-1c \
  --cidr-block 192.168.16.0/20 \
  --tag-specifications "ResourceType=subnet,Tags=[{Key=Name,Value=eks-fargate-private-subnet-1c}]"

aws ec2 create-subnet \
  --vpc-id vpc-xxxxxxxxxxxxxxxxx \
  --availability-zone ap-northeast-1a \
  --cidr-block 192.168.32.0/20 \
  --tag-specifications "ResourceType=subnet,Tags=[{Key=Name,Value=eks-fargate-public-subnet-1a}]"

インターネットゲートウェイの追加

パブリックサブネット 内のリソースにインターネットアクセスを提供するには、インターネットゲートウェイ を作成して VPC にアタッチします。

aws ec2 create-internet-gateway \
  --tag-specifications "ResourceType=internet-gateway,Tags=[{Key=Name,Value=igw-eks-fargate}]"

aws ec2 attach-internet-gateway \
  --internet-gateway-id igw-xxxxxxxxxxxxxxxxx \
  --vpc-id vpc-xxxxxxxxxxxxxxxxx

次に、ルートテーブル を作成してインターネットゲートウェイに関連付けます。

aws ec2 create-route-table \
  --vpc-id vpc-xxxxxxxxxxxxxxxxx \
  --tag-specifications "ResourceType=route-table,Tags=[{Key=Name,Value=rtb-eks-fargate-public}]"

aws ec2 create-route \
  --route-table-id rtb-xxxxxxxx \
  --destination-cidr-block 0.0.0.0/0 \
  --gateway-id igw-xxxxxxxxxxxxxxxxx

aws ec2 associate-route-table \
  --route-table-id rtb-xxxxxxxx \
  --subnet-id subnet-xxxxxxxxxxxxxxxxx

このセットアップにより、パブリックサブネット内のリソースがインターネットに接続できるようになります。

VPC エンドポイントの追加

EKS プライベートクラスター との安全な通信を実現するため、必要な VPC エンドポイント を作成します。コマンド内の region-code は使用する AWS リージョンに置き換えてください。

詳細については AWS ドキュメント をご参照ください。

必要な VPC エンドポイント

タイプエンドポイント
Interfacecom.amazonaws.region-code.ecr.api
Interfacecom.amazonaws.region-code.ecr.dkr
Interfacecom.amazonaws.region-code.ec2
Interfacecom.amazonaws.region-code.elasticloadbalancing
Interfacecom.amazonaws.region-code.sts
Gatewaycom.amazonaws.region-code.s3

例: ap-northeast-1 リージョン

VPC エンドポイント用セキュリティグループを作成します。

aws ec2 create-security-group \
  --description "VPC endpoints" \
  --group-name eks-fargate-vpc-endpoints-sg \
  --vpc-id vpc-xxxxxxxxxxxxxxxxx \
  --tag-specifications "ResourceType=security-group,Tags=[{Key=Name,Value=eks-fargate-vpc-endpoints-sg}]"

aws ec2 authorize-security-group-ingress \
  --group-id sg-xxxxxxxxxxxxxxxxx \
  --protocol tcp \
  --port 443 \
  --cidr 192.168.0.0/16

Interface VPC エンドポイント を作成します。

for name in com.amazonaws.ap-northeast-1.ecr.api com.amazonaws.ap-northeast-1.ecr.dkr com.amazonaws.region-code.ec2 com.amazonaws.ap-northeast-1.elasticloadbalancing com.amazonaws.ap-northeast-1.sts; do \
aws ec2 create-vpc-endpoint \
  --vpc-id vpc-xxxxxxxxxxxxxxxxx \
  --vpc-endpoint-type Interface \
  --service-name $name \
  --security-group-ids sg-xxxxxxxxxxxxxxxxx \
  --subnet-ids subnet-xxxxxxxxxxxxxxxxx subnet-xxxxxxxxxxxxxxxxx;
done;

S3 用の Gateway VPC エンドポイント を作成します。

aws ec2 create-vpc-endpoint \
  --vpc-id vpc-xxxxxxxxxxxxxxxxx \
  --service-name com.amazonaws.ap-northeast-1.s3 \
  --route-table-ids rtb-xxxxxxxxxxxxxxxxx

これらのエンドポイントを追加することで、プライベートクラスターは ECR、S3、Elastic Load Balancing などの AWS サービスに安全にアクセスできるようになります。

踏み台 EC2

EKS プライベートクラスター にアクセスするには、踏み台 EC2 インスタンス を利用できます。この踏み台ホストは、Kubernetes API サーバーエンドポイントへの安全なアクセスを提供します。

If you have disabled public access for your cluster’s Kubernetes API server endpoint, you can only access the API server from within your VPC or a connected network.

インスタンス IAM ロールの作成

踏み台インスタンスが安全に操作できるようにするには、IAM ロール を作成し、Session Manager アクセス用の AmazonSSMManagedInstanceCore 管理ポリシーをアタッチします。

手順 1: IAM ロールを作成

echo '{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "ec2.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}' > policy.json

aws iam create-role \
  --role-name eks-fargate-bastion-ec2-role \
  --assume-role-policy-document file://./policy.json

手順 2: インスタンスプロファイルを作成

aws iam create-instance-profile \
  --instance-profile-name eks-fargate-bastion-ec2-instance-profile

aws iam add-role-to-instance-profile \
  --instance-profile-name eks-fargate-bastion-ec2-instance-profile \
  --role-name eks-fargate-bastion-ec2-role

手順 3: ポリシーをロールにアタッチ

Session Manager アクセスを許可するために AmazonSSMManagedInstanceCore ポリシーをアタッチします。

aws iam attach-role-policy \
  --role-name eks-fargate-bastion-ec2-role \
  --policy-arn arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore

EKS、EC2、および VPC サービスを設定および管理するための幅広い権限が必要な場合は、追加のポリシーをアタッチします。最小特権のベストプラクティスについては AWS サービス認可リファレンス をご参照ください。

echo '{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "cloudformation:CreateStack",
                "cloudformation:DeleteStack",
                "cloudformation:DescribeStacks",
                "cloudformation:DescribeStackEvents",
                "cloudformation:ListStacks",
                "ec2:*",
                "eks:*",
                "iam:AttachRolePolicy",
                "iam:CreateOpenIDConnectProvider",
                "iam:CreateRole",
                "iam:DetachRolePolicy",
                "iam:DeleteOpenIDConnectProvider",
                "iam:GetOpenIDConnectProvider",
                "iam:GetRole",
                "iam:ListPolicies",
                "iam:PassRole",
                "iam:PutRolePolicy",
                "iam:TagOpenIDConnectProvider"
            ],
            "Resource": "*"
        }
    ]
}' > policy.json

aws iam put-role-policy \
  --role-name eks-fargate-bastion-ec2-role \
  --policy-name eks-cluster \
  --policy-document file://./policy.json

踏み台 EC2 インスタンスの起動

IAM ロールが構成されたら、EC2 インスタンスを起動します。有効な AMI ID を使用してください。最新の AMI 詳細については 公式ドキュメント をご参照ください。

instanceProfileRole=$( \
aws iam list-instance-profiles-for-role \
  --role-name eks-fargate-bastion-ec2-role \
| jq -r '.InstanceProfiles[0].Arn')

aws ec2 run-instances \
  --image-id ami-0bba69335379e17f8 \
  --instance-type t2.micro \
  --iam-instance-profile "Arn=$instanceProfileRole" \
  --subnet-id subnet-xxxxxxxxxxxxxxxxx \
  --associate-public-ip-address \
  --tag-specifications "ResourceType=instance,Tags=[{Key=Name,Value=eks-fargate-bastion-ec2}]"

これで、踏み台 EC2 インスタンスがプライベート EKS クラスターに安全にアクセスできるようになります。

Session Manager を使用したインスタンスへの接続

踏み台 EC2 インスタンス に安全にアクセスするには、AWS Session Manager を使用します。これにより、SSH キーペアの必要性がなくなり、安全で監査可能なアクセスが可能になります。

接続後、以下のコマンドを使用して ec2-user アカウントに切り替えます。

sh-4.2$ sudo su - ec2-user

AWS CLI の最新バージョンへの更新

最新の AWS サービスとの互換性を確保するために、AWS CLI を最新バージョンに更新します。

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install --bin-dir /usr/local/bin --install-dir /usr/local/aws-cli --update

インストールを確認します。

aws --version

kubectl のインストール

EKS クラスターを管理するには、踏み台インスタンスに kubectl をインストールします。以下の手順に従ってください。

1. EKS クラスターのバージョンに対応する kubectl バイナリをダウンロード

curl -o kubectl https://s3.us-west-2.amazonaws.com/amazon-eks/1.24.7/2022-10-31/bin/linux/amd64/kubectl

2. バイナリを実行可能に設定

chmod +x ./kubectl

3. kubectl を PATH に追加

mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$PATH:$HOME/bin
echo 'export PATH=$PATH:$HOME/bin' >> ~/.bashrc

4. インストールを確認

kubectl version --short --client

eksctl のインストール

eksctl をインストールして EKS クラスターの管理を簡略化します。

1. eksctl をダウンロードして展開

curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp

2. バイナリを PATH 内の場所に移動

sudo mv /tmp/eksctl /usr/local/bin

3. インストールを確認

eksctl version

これで、踏み台 EC2 インスタンスに kubectleksctl がインストールされ、EKS クラスターを管理する準備が整いました。

EKS

EKS クラスターの作成

eksctl を使用して EKS クラスター を作成します。--fargate オプションを指定することで、このクラスターは Fargate を使用してポッドを管理し、ワーカーノードを必要としません。

詳細な手順については AWS ドキュメント をご参照ください。

eksctl create cluster \
  --name eks-fargate-cluster \
  --region ap-northeast-1 \
  --version 1.24 \
  --vpc-private-subnets subnet-xxxxxxxxxxxxxxxxx,subnet-xxxxxxxxxxxxxxxxx \
  --without-nodegroup \
  --fargate

作成後、以下のコマンドを使用してクラスターを確認します。

$ kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.100.0.1   <none>        443/TCP   20m

クラスターアクセスのトラブルシューティング

問題 1: 資格情報エラー

以下のエラーが発生した場合:

Unable to connect to the server: getting credentials: decoding stdout: no kind "ExecCredential" is registered for version "client.authentication.k8s.io/v1alpha1" in scheme "pkg/client/auth/exec/exec.go:62"

AWS CLI を最新バージョンに更新してください。

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install --bin-dir /usr/local/bin --install-dir /usr/local/aws-cli --update

再試行してください。

$ kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.100.0.1   <none>        443/TCP   20m

問題 2: 接続拒否

以下のエラーが発生した場合:

The connection to the server localhost:8080 was refused - did you specify the right host or port?

次のコマンドを使用して Kubernetes 設定ファイル (~/.kube/config) を更新します。

aws eks update-kubeconfig \
  --region ap-northeast-1 \
  --name eks-fargate-cluster

再試行してください。

$ kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.100.0.1   <none>        443/TCP   20m

IAM ユーザーおよびロールの追加

クラスターへのアクセスを失わないように、追加の IAM ユーザーまたはロール にアクセス権を付与します。デフォルトでは、クラスターを作成した IAM エンティティのみが管理者権限を持っています。

詳細なベストプラクティスについては 公式ドキュメント をご参照ください。

The IAM user or role that created the cluster is the only IAM entity that has access to the cluster. Grant permissions to other IAM users or roles so they can access your cluster.

system:masters グループに IAM ユーザーを追加するには、以下のコマンドを使用します。

eksctl create iamidentitymapping \
  --cluster eks-fargate-cluster \
  --region ap-northeast-1 \
  --arn arn:aws:iam::000000000000:user/xxxxxx \
  --group system:masters \
  --no-duplicate-arns

これにより、追加のユーザーまたはロールが EKS クラスターに管理者としてアクセスできるようになります。

プライベートクラスターエンドポイントの有効化

プライベートクラスターエンドポイント を有効化し、Kubernetes API へのアクセスを VPC 内に制限します。

aws eks update-cluster-config \
  --region ap-northeast-1 \
  --name eks-fargate-cluster \
  --resources-vpc-config endpointPublicAccess=false,endpointPrivateAccess=true

HTTPS 用のインバウンドルールの追加

Amazon EKS コントロールプレーンセキュリティグループが、ポート 443 上の踏み台 EC2 インスタンスからのトラフィックを許可していることを確認します。

You must ensure that your Amazon EKS control plane security group contains rules to allow ingress traffic on port 443 from your bastion host.

sgId=$(aws eks describe-cluster --name eks-fargate-cluster | jq -r .cluster.resourcesVpcConfig.clusterSecurityGroupId)
aws ec2 authorize-security-group-ingress \
  --group-id $sgId \
  --protocol tcp \
  --port 443 \
  --cidr 192.168.0.0/16

接続の確認

踏み台 EC2 インスタンスと EKS クラスター間の接続をテストします。

$ kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.100.0.1   <none>        443/TCP   153m

Fargate プロファイル

アプリケーションの名前空間用に Fargate プロファイル を作成します。

eksctl create fargateprofile \
  --region ap-northeast-1 \
  --cluster eks-fargate-cluster  \
  --name fargate-app-profile \
  --namespace fargate-app

AWS Load Balancer Controller のインストール

AWS Load Balancer Controller をインストールして、Application Load Balancer (ALB) の背後でアプリケーションコンテナを実行します。

IAM OIDC プロバイダーの作成

クラスター用の IAM OIDC プロバイダーが存在しない場合は、以下の手順で作成します。

oidc_id=$(aws eks describe-cluster --name eks-fargate-cluster --query "cluster.identity.oidc.issuer" --output text | cut -d '/' -f 5)
aws iam list-open-id-connect-providers | grep $oidc_id

# レスポンスが返されない場合、以下を実行します。
eksctl utils associate-iam-oidc-provider \
  --region ap-northeast-1 \
  --cluster eks-fargate-cluster \
  --approve

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

1. AWS Load Balancer Controller 用ポリシーファイルをダウンロード
curl -o iam_policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.4.4/docs/install/iam_policy.json
2. IAM ポリシーを作成
aws iam create-policy \
  --policy-name AWSLoadBalancerControllerIAMPolicy \
  --policy-document file://iam_policy.json
3. IAM サービスアカウントを作成
eksctl create iamserviceaccount \
  --region ap-northeast-1 \
  --cluster=eks-fargate-cluster \
  --namespace=kube-system \
  --name=aws-load-balancer-controller \
  --role-name "AmazonEKSLoadBalancerControllerRole" \
  --attach-policy-arn=arn:aws:iam::111122223333:policy/AWSLoadBalancerControllerIAMPolicy \
  --approve

Helm と Load Balancer Controller Add-on のインストール

1. Helm v3 をインストール
$ curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 > get_helm.sh
$ chmod 700 get_helm.sh
$ ./get_helm.sh
$ helm version --short | cut -d + -f 1
v3.10.3
2. Load Balancer Controller Add-on をインストール
helm repo add eks https://aws.github.io/eks-charts
helm repo update
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
  -n kube-system \
  --set region=ap-northeast-1 \
  --set vpcId=vpc-xxxxxxxxxxxxxxxxx \
  --set image.repository=602401143452.dkr.ecr.ap-northeast-1.amazonaws.com/amazon/aws-load-balancer-controller \
  --set clusterName=eks-fargate-cluster \
  --set serviceAccount.create=false \
  --set serviceAccount.name=aws-load-balancer-controller \
  --set enableShield=false \
  --set enableWaf=false \
  --set enableWafv2=false

When deploying it, you should use command line flags to set enable-shield, enable-waf, and enable-wafv2 to false. Certificate discovery with hostnames from Ingress objects isn’t supported. This is because the controller needs to reach AWS Certificate Manager, which doesn’t have a VPC interface endpoint.

3. デプロイを確認
$ 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           105s

これで、AWS Load Balancer Controller がインストールされ、アプリケーションコンテナを Application Load Balancer の背後で安全に実行できる準備が整いました。

サブネットのタグ付け

プライベートサブネット をタグ付けして、内部ロードバランサーで使用することを示します。これにより、Kubernetes と AWS Load Balancer Controller がサブネットを正しく識別できるようになります。

aws ec2 create-tags \
  --resources subnet-xxxxxxxxxxxxxxxxx subnet-xxxxxxxxxxxxxxxxx \
  --tags Key=kubernetes.io/role/internal-elb,Value=1

詳細については AWS ドキュメント をご参照ください。

Must be tagged in the following format. This is so that Kubernetes and the AWS load balancer controller know that the subnets can be used for internal load balancers.

サンプルアプリケーションのデプロイ

FastAPI サンプルアプリケーション

この投稿では、FastAPI を使用して、デモ用のシンプルな API を作成します。

ディレクトリ構造

ファイルを以下のように整理します。

/
├── src
│   ├── __init__.py
│   ├── main.py
│   └── requirements.txt
└── Dockerfile

requirements.txt

アプリケーションに必要な依存関係を定義します。

anyio==3.6.2
click==8.1.3
fastapi==0.88.0
h11==0.14.0
httptools==0.5.0
idna==3.4
pydantic==1.10.2
python-dotenv==0.21.0
PyYAML==6.0
sniffio==1.3.0
starlette==0.22.0
typing_extensions==4.4.0
uvicorn==0.20.0
uvloop==0.17.0
watchfiles==0.18.1
websockets==10.4

main.py

基本的な API エンドポイントを作成します。

from fastapi import FastAPI

app = FastAPI()


@app.get('/')
def read_root():
    return {'message': 'Hello world!'}

Dockerfile

アプリケーションコンテナをビルドするための Dockerfile を定義します。

FROM python:3.10-alpine@sha256:d8a484baabf7d2337d34cdef6730413ea1feef4ba251784f9b7a8d7b642041b3
COPY ./src ./
RUN pip install --no-cache-dir -r requirements.txt
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]

ECR にイメージをプッシュ

アプリケーションイメージを Amazon ECR にビルドしてプッシュします。

1. ECR リポジトリを作成

aws ecr create-repository --repository-name api

2. リポジトリ URI を取得

uri=$(aws ecr describe-repositories | jq -r '.repositories[] | select(.repositoryName == "api") | .repositoryUri')

3. Docker を ECR に認証

aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 000000000000.dkr.ecr.ap-northeast-1.amazonaws.com

4. イメージをビルド、タグ付け、プッシュ

docker build .
docker tag xxxxxxxxxxxx $uri:latest
docker push $uri:latest

Fargate にデプロイ

1. Kubernetes マニフェストファイル fargate-app.yaml を作成

000000000000.dkr.ecr.ap-northeast-1.amazonaws.com/api:latest を実際のイメージ URI に置き換えます。

---
apiVersion: v1
kind: Namespace
metadata:
  name: fargate-app
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: fargate-app-deployment
  namespace: fargate-app
  labels:
    app: api
spec:
  replicas: 1
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                - key: kubernetes.io/arch
                  operator: In
                  values:
                    - amd64
      containers:
        - name: api
          image: 000000000000.dkr.ecr.ap-northeast-1.amazonaws.com/api:latest
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 80
      nodeSelector:
        kubernetes.io/os: linux
---
apiVersion: v1
kind: Service
metadata:
  name: fargate-app-service
  namespace: fargate-app
  labels:
    app: api
spec:
  selector:
    app: api
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: NodePort
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: fargate-app-ingress
  namespace: fargate-app
  annotations:
    alb.ingress.kubernetes.io/scheme: internal
    alb.ingress.kubernetes.io/target-type: ip
spec:
  ingressClassName: alb
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: fargate-app-service
                port:
                  number: 80

AWS Load Balancer Controller v2.4 の詳細な仕様については、公式ドキュメント をご参照ください。

2. マニフェストファイルを適用

kubectl apply -f fargate-app.yaml

3. デプロイされたリソースを確認

$ kubectl get all -n fargate-app
NAME                                          READY   STATUS    RESTARTS   AGE
pod/fargate-app-deployment-6db55f9b7b-4hp8z   1/1     Running   0          55s

NAME                          TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
service/fargate-app-service   NodePort   10.100.190.97   <none>        80:31985/TCP   6m

NAME                                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/fargate-app-deployment   1/1     1            1           6m

NAME                                                DESIRED   CURRENT   READY   AGE
replicaset.apps/fargate-app-deployment-6db55f9b7b   1         1         1       6m

API のテスト

1. ALB の DNS 名 を取得

kubectl describe ingress -n fargate-app fargate-app-ingress

出力例:

Name:             fargate-app-ingress
Labels:           <none>
Namespace:        fargate-app
Address:          internal-k8s-fargatea-fargatea-0579eb4ce2-1731550123.ap-northeast-1.elb.amazonaws.com
Ingress Class:    alb
Default backend:  <default>
Rules:
  Host        Path  Backends
  ----        ----  --------
  *
              /   fargate-app-service:80 (192.168.4.97:80)
Annotations:  alb.ingress.kubernetes.io/scheme: internal
              alb.ingress.kubernetes.io/target-type: ip
Events:
  Type    Reason                  Age    From     Message
  ----    ------                  ----   ----     -------
  Normal  SuccessfullyReconciled  4m17s  ingress  Successfully reconciled

2. API エンドポイントをテスト

curl internal-k8s-fargatea-fargatea-xxxxxxxxxx-xxxxxxxxxx.ap-northeast-1.elb.amazonaws.com
{"message":"Hello world!"}

これで、サンプル FastAPI アプリケーションが 内部 Application Load Balancer を通じてデプロイされ、アクセス可能になりました。

クラスターの削除

EKS クラスターや関連リソースが不要になった場合は、以下の手順で削除できます。VPC エンドポイント や他のプロビジョニングされたリソースに関連するコストに注意してください。

クラスター削除の手順

1. アプリケーションリソースを削除

デプロイ済みアプリケーションと AWS Load Balancer Controller をアンインストールします。

kubectl delete -f fargate-app.yaml
helm uninstall aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system

2. IAM ポリシーをデタッチ

AWSLoadBalancerControllerIAMPolicy の ARN を取得してデタッチします。

arn=$(aws iam list-policies --scope Local \
| jq -r '.Policies[] | select(.PolicyName == "AWSLoadBalancerControllerIAMPolicy").Arn')

aws iam detach-role-policy \
  --role-name AmazonEKSLoadBalancerControllerRole \
  --policy-arn $arn

3. IAM サービスアカウントを削除

AWS Load Balancer Controller に関連付けられたサービスアカウントを削除します。

eksctl delete iamserviceaccount \
  --region ap-northeast-1 \
  --cluster eks-fargate-cluster \
  --namespace kube-system \
  --name aws-load-balancer-controller

4. Fargate プロファイルを削除

作成した Fargate プロファイルを削除します。

aws eks delete-fargate-profile \
  --cluster-name eks-fargate-cluster \
  --fargate-profile-name fargate-app-profile

aws eks delete-fargate-profile \
  --cluster-name eks-fargate-cluster \
  --fargate-profile-name fp-default

5. Pod Execution Role ポリシーをデタッチ

AmazonEKSFargatePodExecutionRolePolicy を取得してデタッチします。

arn=$(aws iam list-policies --scope AWS \
| jq -r '.Policies[] | select(.PolicyName == "AmazonEKSFargatePodExecutionRolePolicy").Arn')

aws iam detach-role-policy \
  --role-name eksctl-eks-fargate-cluster-FargatePodExecutionRole-xxxxxxxxxxxxx \
  --policy-arn $arn

6. EKS クラスターを削除

eksctl を使用してクラスターを削除します。

eksctl delete cluster \
  --region ap-northeast-1 \
  --name eks-fargate-cluster

削除に関するトラブルシューティング

AWS Load Balancer Controller の Ingress の削除で問題が発生した場合は、こちら を参照して Finalizer を手動で削除してください。

kubectl patch ingress fargate-app-ingress -n fargate-app -p '{"metadata":{"finalizers":[]}}' --type=merge

このコマンドにより、Kubernetes が Ingress リソースを削除できるようになります。

まとめ

このブログ記事では、EKS Fargate を使用してプライベートサブネット内にコンテナをデプロイし、Application Load Balancer (ALB) の背後で安全に管理する方法を詳しく説明しました。VPC インフラストラクチャ のセットアップから、サンプルの FastAPI アプリケーション のデプロイ、AWS Load Balancer Controller の活用まで、スケーラブルで安全な Kubernetes 環境を構築するための手順を解説しています。

このセットアップでは、AWS マネージド Kubernetes を最大限に活用しつつ、運用負担を最小限に抑え、クラウドセキュリティのベストプラクティスに準拠した環境を実現できます。

Happy Coding! 🚀

岩佐 孝浩

岩佐 孝浩

Software Developer at KAKEHASHI Inc.
AWS を活用したクラウドネイティブ・アプリケーションの要件定義・設計・開発に従事。 株式会社カケハシで、処方箋データ収集の新たな基盤の構築に携わっています。 Japan AWS Top Engineers 2020-2023