プライベートサブネット内のEKS FargateでALB配下にコンテナをデプロイする
プライベートサブネット内のEKS Fargateで、内部ALBの背後にコンテナを実行し、どの層においてもパブリックに公開しない構成にします。
プライベートサブネット内のEKS Fargateでコンテナを実行し、Application Load Balancer(ALB)の背後で管理することで、クラスタのPodをパブリックインターネットから遮断しつつ、制御されたエントリーポイントを提供できます。

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-hostnamesVPCエンドポイントを利用する場合は、必ずDNSホスト名を有効にしてください。詳細については公式ドキュメントを参照してください。
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 Pod用のプライベートサブネットと、踏み台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-xxxxxxxxxxxxxxxxxVPCエンドポイントの追加
EKSプライベートクラスタが安全に通信できるよう、必要なVPCエンドポイントを作成します。詳細については公式ドキュメントを参照してください。
| Type | Endpoint |
|---|---|
| Interface | com.amazonaws.region-code.ecr.api |
| Interface | com.amazonaws.region-code.ecr.dkr |
| Interface | com.amazonaws.region-code.ec2 |
| Interface | com.amazonaws.region-code.elasticloadbalancing |
| Interface | com.amazonaws.region-code.sts |
| Gateway | com.amazonaws.region-code.s3 |
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インターフェース型VPCエンドポイントを作成します。
for name in com.amazonaws.<REGION>.ecr.api com.amazonaws.<REGION>.ecr.dkr com.amazonaws.region-code.ec2 com.amazonaws.<REGION>.elasticloadbalancing com.amazonaws.<REGION>.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用のゲートウェイ型VPCエンドポイントを作成します。
aws ec2 create-vpc-endpoint \ --vpc-id vpc-xxxxxxxxxxxxxxxxx \ --service-name com.amazonaws.<REGION>.s3 \ --route-table-ids rtb-xxxxxxxxxxxxxxxxxこれらのエンドポイントを追加することで、プライベートクラスタはECR、S3、Elastic Load BalancingなどのAWSサービスに安全にアクセスできるようになります。
踏み台EC2
EKSプライベートクラスタにアクセスするには、踏み台EC2インスタンスを利用できます。パブリックアクセスが無効になっている場合でも、この踏み台ホストを使えばKubernetes APIサーバーエンドポイントと安全にやり取りできます。
https://docs.aws.amazon.com/eks/latest/userguide/cluster-endpoint.html#private-access
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マネージドポリシーをアタッチします。
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インスタンスプロファイルを作成します。
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-roleSession Managerアクセスを許可するため、AmazonSSMManagedInstanceCoreポリシーをアタッチします。
aws iam attach-role-policy \ --role-name eks-fargate-bastion-ec2-role \ --policy-arn arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCoreEKS、EC2、VPCサービスをセットアップ・管理するためのより広い権限が必要な場合は、追加のポリシーをアタッチします。最小権限の原則に関するベストプラクティスについては公式ドキュメントを参照してください。
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}]"Session Managerでインスタンスに接続する
踏み台EC2インスタンスに安全にアクセスするには、AWS Session Managerを使用します。これによりSSHキーペアが不要になり、安全で監査可能なアクセスが実現します。


接続後、ec2-userアカウントに切り替えます。
sh-4.2$ sudo su - ec2-userSession Manager接続のため、インスタンスのIAMロールにAmazonSSMManagedInstanceCoreポリシーがアタッチされていることを確認してください。
AWS CLIを最新バージョンに更新する
最新のAWSサービスとの互換性を確保するため、AWS CLIを最新バージョンに更新します。
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"unzip awscliv2.zipsudo ./aws/install --bin-dir /usr/local/bin --install-dir /usr/local/aws-cli --updateインストールを確認します。
aws --versionkubectlのインストール
EKSクラスタを管理するために、踏み台インスタンスにkubectlをインストールします。
EKSクラスタのバージョンに対応するkubectlバイナリをダウンロードします。
curl -o kubectl https://s3.us-west-2.amazonaws.com/amazon-eks/1.24.7/2022-10-31/bin/linux/amd64/kubectlバイナリを実行可能にします。
chmod +x ./kubectlkubectlをPATHに追加します。
mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$PATH:$HOME/binecho 'export PATH=$PATH:$HOME/bin' >> ~/.bashrcインストールを確認します。
kubectl version --short --clienteksctlのインストール
EKSクラスタの管理を簡素化するため、eksctlをインストールします。
eksctlをダウンロードして展開します。
curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmpバイナリをPATHが通ったディレクトリに移動します。
sudo mv /tmp/eksctl /usr/local/binインストールを確認します。
eksctl versionこれで、kubectlとeksctlがインストールされ、踏み台EC2インスタンスからEKSクラスタを管理・操作できる状態になりました。
EKS
EKSクラスタの作成
--fargateオプションを指定したeksctlでEKSクラスタを作成します。このクラスタは、ワーカーノードを必要とせずにPodを管理するためにFargateを使用します。
詳細な手順については公式ドキュメントを参照してください。
クラスタの作成にはおよそ20分以上かかる場合があります。
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 svcNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEkubernetes ClusterIP 10.100.0.1 <none> 443/TCP 20m付録: クラスタアクセスのトラブルシューティング
問題1: 認証情報エラー
kubectl get svc実行時に以下のエラーが発生する場合。
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.zipsudo ./aws/install --bin-dir /usr/local/bin --install-dir /usr/local/aws-cli --updateコマンドを再試行します。
$ kubectl get svcNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEkubernetes 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 svcNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEkubernetes ClusterIP 10.100.0.1 <none> 443/TCP 20mIAMユーザーとロールの追加
クラスタへのアクセスを失わないよう、追加の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.
IAMユーザーをsystem:mastersグループに追加するには、以下のコマンドを使用します。
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内に制限するため、プライベートクラスタエンドポイントを有効にします。
プライベートクラスタエンドポイントの有効化にはおよそ10分かかる場合があります。
aws eks update-cluster-config \ --region ap-northeast-1 \ --name eks-fargate-cluster \ --resources-vpc-config endpointPublicAccess=false,endpointPrivateAccess=trueEKSコントロールプレーンのセキュリティグループが、踏み台EC2インスタンスからのポート443への受信トラフィックを許可していることを確認してください。
https://docs.aws.amazon.com/eks/latest/userguide/cluster-endpoint.html#private-access
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 svcNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEkubernetes ClusterIP 10.100.0.1 <none> 443/TCP 153mFargateプロファイル
アプリケーション用の名前空間向けにFargateプロファイルを作成します。
eksctl create fargateprofile \ --region ap-northeast-1 \ --cluster eks-fargate-cluster \ --name fargate-app-profile \ --namespace fargate-appAWS Load Balancer Controllerのインストール
Application Load Balancer(ALB)の背後でアプリケーションコンテナを実行するため、AWS Load Balancer Controllerをインストールします。
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
# If no response is returned, run the following:eksctl utils associate-iam-oidc-provider \ --region ap-northeast-1 \ --cluster eks-fargate-cluster \ --approveAWS 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.jsonIAMポリシーを作成します。
aws iam create-policy \ --policy-name AWSLoadBalancerControllerIAMPolicy \ --policy-document file://iam_policy.jsonIAMサービスアカウントを作成します。
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 \ --approveHelmとLoad Balancer Controllerアドオンのインストール
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 1v3.10.3Load Balancer Controllerアドオンをインストールします。
helm repo add eks https://aws.github.io/eks-chartshelm repo updatehelm 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
VPCエンドポイントが現在提供されていないため、コマンドにenableShield=false、enableWaf=false、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.
デプロイを確認します。
$ kubectl get deployment -n kube-system aws-load-balancer-controllerNAME READY UP-TO-DATE AVAILABLE AGEaws-load-balancer-controller 2/2 2 2 105sAWS 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詳細については公式ドキュメントを参照してください。
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.
アプリケーションのデプロイ
アプリケーションのビルド
この例では、デモ用のシンプルなAPIを作成するためにFastAPIを使用します。
アプリケーションに必要な依存関係を定義します。
anyio==3.6.2click==8.1.3fastapi==0.88.0h11==0.14.0httptools==0.5.0idna==3.4pydantic==1.10.2python-dotenv==0.21.0PyYAML==6.0sniffio==1.3.0starlette==0.22.0typing_extensions==4.4.0uvicorn==0.20.0uvloop==0.17.0watchfiles==0.18.1websockets==10.4基本的なAPIエンドポイントを作成します。
from fastapi import FastAPI
app = FastAPI()
@app.get('/')def read_root(): return {'message': 'Hello world!'}アプリケーションコンテナをビルドするためのDockerfileを作成します。
FROM python:3.10-alpine@sha256:d8a484baabf7d2337d34cdef6730413ea1feef4ba251784f9b7a8d7b642041b3COPY ./src ./RUN pip install --no-cache-dir -r requirements.txtCMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]イメージのECRへのプッシュ
アプリケーションイメージをビルドし、ECRにプッシュします。
ECRリポジトリを作成します。
aws ecr create-repository --repository-name apiリポジトリURIを取得します。
uri=$(aws ecr describe-repositories | jq -r '.repositories[] | select(.repositoryName == "api") | .repositoryUri')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イメージをビルド、タグ付け、プッシュします。
docker build .docker tag xxxxxxxxxxxx $uri:latestdocker push $uri:latestFargateへのデプロイ
Kubernetesマニフェストファイルfargate-app.yamlを作成します。
000000000000.dkr.ecr.ap-northeast-1.amazonaws.com/api:latestを実際のイメージURIに置き換えてください。
AWS Load Balancer Controller v2.4の仕様の詳細については公式ドキュメントを参照してください。
---apiVersion: v1kind: Namespacemetadata: name: fargate-app---apiVersion: apps/v1kind: Deploymentmetadata: name: fargate-app-deployment namespace: fargate-app labels: app: apispec: 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: v1kind: Servicemetadata: name: fargate-app-service namespace: fargate-app labels: app: apispec: selector: app: api ports: - protocol: TCP port: 80 targetPort: 80 type: NodePort---apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: fargate-app-ingress namespace: fargate-app annotations: alb.ingress.kubernetes.io/scheme: internal alb.ingress.kubernetes.io/target-type: ipspec: ingressClassName: alb rules: - http: paths: - path: / pathType: Prefix backend: service: name: fargate-app-service port: number: 80マニフェストファイルを適用します。
kubectl apply -f fargate-app.yamlデプロイされたリソースを確認します。
$ kubectl get all -n fargate-appNAME READY STATUS RESTARTS AGEpod/fargate-app-deployment-6db55f9b7b-4hp8z 1/1 Running 0 55s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEservice/fargate-app-service NodePort 10.100.190.97 <none> 80:31985/TCP 6m
NAME READY UP-TO-DATE AVAILABLE AGEdeployment.apps/fargate-app-deployment 1/1 1 1 6m
NAME DESIRED CURRENT READY AGEreplicaset.apps/fargate-app-deployment-6db55f9b7b 1 1 1 6mALBのプロビジョニングには10分以上かかる場合があります。
APIのテスト
ALBのDNS名を取得します。
kubectl describe ingress -n fargate-app fargate-app-ingress出力例。
Name: fargate-app-ingressLabels: <none>Namespace: fargate-appAddress: internal-k8s-fargatea-fargatea-0579eb4ce2-1731550123.ap-northeast-1.elb.amazonaws.comIngress Class: albDefault 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: ipEvents: Type Reason Age From Message ---- ------ ---- ---- ------- Normal SuccessfullyReconciled 4m17s ingress Successfully reconciledAPIエンドポイントをテストします。
curl internal-k8s-fargatea-fargatea-xxxxxxxxxx-xxxxxxxxxx.ap-northeast-1.elb.amazonaws.com期待される出力。
{"message":"Hello world!"}EKSクラスタの削除
EKSクラスタやその関連リソースが不要になった場合は、以下の手順で削除できます。
デプロイしたアプリケーションを削除し、AWS Load Balancer Controllerをアンインストールします。
kubectl delete -f fargate-app.yamlhelm uninstall aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-systemAWSLoadBalancerControllerIAMPolicyの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 $arnAWS Load Balancer Controllerに関連付けられたサービスアカウントを削除します。
eksctl delete iamserviceaccount \ --region ap-northeast-1 \ --cluster eks-fargate-cluster \ --namespace kube-system \ --name aws-load-balancer-controllerセットアップ時に作成した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-defaultAmazonEKSFargatePodExecutionRolePolicyを取得してデタッチします。
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 $arneksctlを使ってクラスタを削除します。
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リソースの削除を完了できるようになります。
まとめ
プライベートサブネットのVPC、EKS Fargateクラスタ、AWS Load Balancer Controllerを構築することで、どの層でもパブリックに公開せずに、内部ALBの背後でFastAPIコンテナを実行できるようになりました。この構成全体を成り立たせているのは、eksctl create clusterの--fargateフラグと、Ingressのalb.ingress.kubernetes.io/scheme: internalアノテーションです。Fargateはワーカーノードのキャパシティプランニングを完全に不要にし、内部ALBのスキームはPodのプライベートサブネット配置に合わせて、エントリーポイント自体をパブリックインターネットから遮断します。プライベートサブネットにkubernetes.io/role/internal-elb=1のタグを付ける作業は見落としがちですが必須の手順です。これがないと、Load Balancer Controllerは内部ALBの有効なターゲットとなるサブネットを判別できません。VPCエンドポイント、踏み台ホスト、コントローラーが整った後は、新しいサービスをデプロイする作業はマニフェストとkubectl applyだけで済み、ネットワークとIAMの基盤はすでにそれをカバーしています。
Related posts
Cognito User PoolsとOIDCでSlackサインインを実装する
Cognito user poolをOIDC経由でSlackと連携させ、"Sign in with Slack"をAmplifyでNext.jsアプリに組み込みます。
Lambda Web AdapterでFastAPIをAWS Lambdaにデプロイする
Lambda Web Adapterを使うと、FastAPIで書いたAPIバックエンドをコンテナのまま単一のLambda関数にデプロイできます。
API Gateway WebSocket:モック統合の実装
バックエンドのLambdaを一切使わず、モック統合のみでAPI Gateway WebSocket APIを構築し、あらかじめ用意されたレスポンスを返します。
CloudFront署名付きURL経由でS3にアップロードする
CloudFrontの署名付きURLを使えば、独自ドメイン経由でS3にアップロードできます。S3の直接の署名付きURLが使えない場合に有用です。
AWS EventBridge Scheduler:スケジュールに沿ってEC2を起動・停止する
Lambdaを介さずEventBridge SchedulerがEC2 APIを直接呼び出すことで、cronスケジュールに従ってEC2インスタンスを起動・停止します。
