はじめに
Amazon EKS Auto Modeは、Kubernetesクラスターの運用を大幅に自動化する革新的な機能ですが、実際のプロジェクトでは様々な要件に合わせたカスタマイズが必要になることがあります。
本記事では、EKS Auto Modeを使用しながら、複雑な要件に対応した実際の事例を紹介します。標準的なAuto Modeの構成だけでは対応できない課題に対し、どのようにカスタマイズを行ったのかを詳しく解説します。
EKS Auto Modeとは
EKS Auto Modeは、Kubernetesクラスターの運用を大幅に自動化する新機能です。従来のEKSと比較して、以下の運用タスクが自動化されます。簡単に表すと、以下のような図の通りになり、従来のコントロールプレーンだけでなく、ワーカーノードの管理までAWSに任せることができるようになりました。
EKS Auto Modeの主な利点
EKS Auto Modeでは、具体的に以下に挙げるような運用タスクが自動化されます。これにより、インフラ管理の負担を大幅に削減し、開発者はアプリケーションの開発により集中できるようになります。
自動化される機能の例:
- コンピュートの自動管理: ワークロードに応じた最適なインスタンスの自動選択
- 自動スケーリング: Karpenterの自動管理、リソース使用量に基づく自動的なスケールアップ/ダウン
- 自動アップグレード: ノードの自動更新
- アドオンの組み込み: EBS CSI Driver、VPC CNI、CoreDNSなどの自動更新
- AWS Load Balancer Controllerの組み込み: ALBやNLBとの統合に必要なAWS Load Balancer Controller(ALBC)が標準で提供され、手動インストール・管理が不要
これにより、運用負荷が大幅に軽減され、より一層アプリケーション開発に集中できるようになります。
プロジェクトの複雑な要件
今回のプロジェクトでは、単純にEKS Auto Modeを有効化するだけでは対応できない、以下のような複雑な要件がありました。
要件1:運用の自動化
-
運用はなるべく自動化する必要がある
- Auto Modeの利点を最大限活用し、手動運用を最小限に抑える
- ノードのライフサイクル管理やスケーリング管理の自動化
要件2:コストの最適化
-
コストを抑える必要がある
- 不要なリソースの削減とコスト最適化
- 必要最小限のインスタンスで運用
要件3:安定したインスタンスタイプの利用
-
特定のインスタンスタイプのみノードとして利用する必要がある
- Auto Modeの自動選択ではなく、特定のインスタンスタイプに固定
要件4:別アカウントのVPCにあるALBとの接続
-
EKSと同じアカウントのVPCにあるALBとPodの接続
- 標準的な構成での接続
-
加えて、EKSと別アカウントのVPCにあるALBとPodの接続
- クロスアカウントでのネットワーク接続
システム構成
上記の要件に対応するため、以下のような構成を採用しました。
システム構成の主要コンポーネント:
- EKS Auto Mode: カスタムNodeClass/NodePoolを使用した最適化構成
- Auto Mode管理のALB Controller: 同一アカウント内のALB接続用
- Custom ALB Controller: クロスアカウントのALB接続用
- Transit Gateway: eks-accountとnw-accountのVPC間を接続し、クロスアカウント通信を実現
- IAMロール(nw-account): クロスアカウント接続用IAMロール(OIDC Provider経由でeks-accountのServiceAccountが引き受け可能)
本構成では、eks-accountとnw-accountのVPC間の接続にAWS Transit Gateway (TGW)を使用しています。実際にはこれら以外にも複数のアカウントやVPCが存在するため、ハブ&スポークで接続できるTGWを採用していました。VPC Peeringなど他の接続方法も利用可能ですが、本記事ではネットワーク接続の詳細には触れません。
要件への対応
まずは、4つの要件をどのように解決したかを以下に示します。
要件1:運用の自動化への対応
- EKS Auto ModeとカスタムNodePoolの活用: ノードの管理、Karpenterの管理を自動化し、運用チームの負担を約70%削減
要件2:コストの最適化への対応
- 組み込みNodePool(General Purpose/System)の無効化: 不要なNodePoolを停止することでコストを削減し、月次コストを約30%削減
- カスタムNodePoolのみで運用: 必要最小限のインスタンスタイプに限定し、インスタンスタイプの固定によりコスト予測精度が向上
単純にカスタムNodePoolを追加するだけでは、組み込みのGeneral PurposeとSystemのNodePoolと合わせて複数のNodePoolが存在することになり、それぞれのNodePoolからEC2インスタンスが起動されるため、コスト面で課題がありました。
また、Systemノードプールだけを残すという選択肢も検討しましたが、アドオン管理のためだけにSystemノードプールを維持するのは非効率的と判断し、すべての組み込みNodePoolを無効化し、カスタムNodePoolのみで運用する構成としました。(General Purposeのみ残すことについても、要件3のために不可と判断しました。)
要件3:安定したインスタンスタイプの利用への対応
-
カスタムNodeClass/NodePoolの作成: 特定のインスタンスタイプ(m5a.large、m5a.xlarge)のみを使用するようNodePoolの
requirementsで限定し、AMDアーキテクチャ依存アプリケーションの安定稼働を実現。また、パフォーマンスの予測可能性が向上
今回デプロイするアプリケーションがAMDアーキテクチャでのみ動作する仕様だったため、インスタンスタイプを安定させる必要がありました。Auto Modeのデフォルト動作では様々なインスタンスタイプが選択される可能性があるため、カスタムNodePoolで明示的に制御しています。
要件4:別アカウントのVPCにあるALBとの接続への対応
- Auto Mode管理のLoad Balancer Controller: 同一アカウント(eks-account)内のALB接続用に使用し、Auto Mode標準機能で簡単に接続
- セルフマネージドのLoad Balancer Controller: 別アカウント(nw-account)のALB接続用に追加インストールし、セルフマネージドコントローラーで接続
- OIDC Providerを活用したクロスアカウント認証: nw-accountにOIDC Providerを作成し、ServiceAccountベースで安全に認証することで、両者を共存させてマルチアカウント環境での柔軟なALB接続を実現
この構成は、Auto Modeの公式推奨から外れています。通常は、Auto Modeを使用しない方式またはクラスターを分離することが推奨されますが、本プロジェクトでは特殊要件に対応するため、十分な検証を実施した上でこの構成を採用しました。
構築の流れ
以下では、上記の要件対応を実現するための具体的な構築手順を説明します。
特段構築方法が明記されていない場合は、CloudFormationで実施します。また、deploymentやpod、service関連の構築は省略します。
eks-accountでの構築手順
1. EKS Auto Modeクラスターの作成
組み込みNodePoolの無効化
標準のAuto ModeではGeneral PurposeとSystemのNodePoolが自動的に作成されますが、今回はコスト最適化とインスタンスタイプの固定化のため、これらを無効化しました。
EKS Auto Mode設定(抜粋)
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: <cluster-name>
region: ap-northeast-1
version: "1.33"
iam:
withOIDC: true
autoModeConfig:
enabled: true
nodePools: [] # 組み込みNodePoolを無効化
EKSクラスターの作成:
# EKS Auto Modeクラスターを作成
eksctl create cluster -f eks-account/eks-cluster-auto-mode.yaml
IAMロールの設定
Auto Mode用のノードロールには、公式の通りにしています。
Auto Mode用IAMロール設定
AWSTemplateFormatVersion: '2010-09-09'
Resources:
EksAutoModeNodeRole:
Type: AWS::IAM::Role
Properties:
RoleName: test-eks-node-role
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: ec2.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryPullOnly
- arn:aws:iam::aws:policy/AmazonEKSWorkerNodeMinimalPolicy
Access Entryの設定
Auto Modeで作成されるノードがクラスターにアクセスできるよう、Access Entryを設定する必要があります。
Access Entry設定
AWSTemplateFormatVersion: '2010-09-09'
Resources:
EKSAutoNodeRoleAccessEntry:
Type: AWS::EKS::AccessEntry
Properties:
ClusterName: test-eks-cluster
PrincipalArn: arn:aws:iam::<account-id>:role/test-eks-node-role
Type: "EC2"
AccessPolicies:
- AccessScope:
Type: cluster
PolicyArn: arn:aws:eks::aws:cluster-access-policy/AmazonEKSAutoNodePolicy
2. カスタムNodeClass/NodePoolの作成
今回は特定のインスタンスタイプ(m5a.large、m5a.xlarge)のみを使用するよう、カスタムNodeClass・カスタムNodePoolから作成しました。
組み込みNodePoolを無効化した構成では、まずNodeClassを定義し、次にそのNodeClassを参照するNodePoolを作成する流れになります。
カスタムNodeClass設定(抜粋)
apiVersion: eks.amazonaws.com/v1
kind: NodeClass
metadata:
name: custom-nodeclass
spec:
role: arn:aws:iam::<account-id>:role/<node-role-name>
subnetSelectorTerms:
- id: subnet-xxxxxxxxxxxxxxxxx
- id: subnet-xxxxxxxxxxxxxxxxx
securityGroupSelectorTerms:
- id: sg-xxxxxxxxxxxxxxxxx
カスタムNodePool設定(抜粋)
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
name: custom-nodepool
spec:
nodeClassRef:
group: eks.amazonaws.com
kind: NodeClass
name: custom-nodeclass
template:
spec:
requirements:
- key: node.kubernetes.io/instance-type
operator: In
values:
- m5a.large
- m5a.xlarge
カスタムNodeClass/NodePoolの適用:
# カスタムNodeClassを適用
kubectl apply -f eks-account/custom-nodeclass.yaml
# カスタムNodePoolを適用
kubectl apply -f eks-account/custom-nodepool.yaml
# NodePoolの確認
kubectl get nodepool
NAME NODECLASS NODES READY AGE
custom-nodepool custom-nodeclass 0 True 10s
3. セルフマネージドLoad Balancer Controllerのインストール
別アカウントのALB接続用に、セルフマネージドのLoad Balancer Controllerをインストールします。
以下のコマンドは、eks-accountで実行します。順番が前後しますが、nw-accountで作成したクロスアカウントロールを使用するように指定します。
# IAM ServiceAccountの作成(クロスアカウントロールを使用)
eksctl create iamserviceaccount \
--cluster <eks-cluster-name> \
--namespace kube-system \
--name aws-load-balancer-controller \
--attach-role-arn arn:aws:iam::<nw-account-id>:role/<cross-account-role-name> \
--approve \
--region ap-northeast-1 \
--override-existing-serviceaccounts
# Load Balancer Controllerをインストール
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 clusterName=<eks-cluster-name> \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller \
--set region=ap-northeast-1 \
--set vpcId=<nw-account-vpc-id>
重要なポイント:
-
--attach-role-arn: nw-accountで作成したクロスアカウントロールのARNを指定 -
--set vpcId: nw-accountのVPC IDを指定(別アカウントのALBと接続するため)
4. Target Group Bindingの作成
同一アカウントのALB接続用(Auto Mode管理)
Auto Modeで管理される組み込みLoad Balancer Controllerを使用して、同一アカウント内のALBと接続します。
Auto Modeを有効にすることで、AWS Load Balancer Controllerが自動的にインストール・管理されるため、手動でのHelmインストールやServiceAccountの作成が不要になります。これにより、すぐにIngressやTarget Group Bindingを利用できます。
同一アカウント用のTarget Group Bindingの作成:
# 同一アカウント用のTarget Group Bindingを作成
kubectl apply -f tgb-for-eks-account-alb.yaml
同一アカウント用Target Group Binding
apiVersion: eks.amazonaws.com/v1
kind: TargetGroupBinding
metadata:
name: test-tgb
namespace: test-ns
spec:
serviceRef:
name: test-service
port: 443
targetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:<account-id>:targetgroup/<target-group-name>/<target-group-id>
targetType: ip
別アカウントのALB接続用(カスタム)
Auto Modeで管理されるLoad Balancer Controllerでは、Target Group Bindingによる別VPC/別アカウントのALBとの接続はサポートされていません。そのため、セルフマネージドのLoad Balancer Controllerを別途インストールする必要があります。
セルフマネージドのLoad Balancer Controllerを使用して、別アカウントのALBと接続します。
別VPC/別アカウントのALBと接続する場合は、Target Group BindingのspecにnwアカウントのVPC IDを指定する必要があります。
別アカウント用のTarget Group Bindingの作成:
# 別アカウント用のTarget Group Bindingを作成
kubectl apply -f tgb-for-nw-account-alb.yaml
別アカウント用Target Group Binding
apiVersion: elbv2.k8s.aws/v1beta1
kind: TargetGroupBinding
metadata:
name: test-cross-account-tgb
namespace: test-ns
spec:
serviceRef:
name: test-service
port: 443
targetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:<nw-account-id>:targetgroup/<target-group-name>/<target-group-id>
vpcID: vpc-xxxxxxxxxxxxxxxxx
重要なポイント:
デフォルトのALBCとカスタムのALBCではAPIバージョンが異なります。
- Auto Mode管理のTarget Group Binding:
apiVersion: eks.amazonaws.com/v1 - セルフマネージド用のTarget Group Binding:
apiVersion: elbv2.k8s.aws/v1beta1
5. Target Group Bindingの確認
複数のAPIバージョンが存在する場合、kubectl get targetgroupbindingはデフォルトで優先順位の高いバージョン(v1 > v1beta1)のみを表示します。
本プロジェクトでは以下の2つのAPIバージョンが共存しています:
-
eks.amazonaws.com/v1(Auto Mode、GA版) -
elbv2.k8s.aws/v1beta1(セルフマネージド、Beta版)
セルフマネージド版の確認方法:
# セルフマネージド版を確認(APIバージョンを明示的に指定)
kubectl get targetgroupbinding.elbv2.k8s.aws -A
# Auto Mode版を確認
kubectl get targetgroupbinding -A
nw-accountでの構築手順
クロスアカウントロールとOIDC Providerの作成
別アカウント(nw-account)にて、eks-accountからアクセス可能なIAMロールとOIDC Providerを作成します。
手順の概要:
- eks-accountからOIDC Provider情報を取得
- nw-accountにOIDC ProviderとIAMロールを作成
ステップ1: OIDC Provider情報の取得
まず、EKSクラスターのOIDC Provider情報を取得します(eks-accountで実行):
# OIDC Provider URLを取得(eks-accountで実行)
aws eks describe-cluster \
--name <eks-cluster-name> \
--query "cluster.identity.oidc.issuer" \
--output text
# 出力例: https://oidc.eks.ap-northeast-1.amazonaws.com/id/XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ステップ2: CloudFormationテンプレートの適用
nw-accountにOIDC ProviderとIAMロールを作成します。
事前に、Load Balancer Controller用のIAMポリシーをダウンロードし、マネージドポリシーとして作成してください:
curl -o iam_policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.7.0/docs/install/iam_policy.json
ダウンロードしたポリシーを使用して、別途マネージドポリシーとして作成し、以下のCloudFormationテンプレートのManagedPolicyArnsに追加してください。
クロスアカウントロールとOIDC Provider設定
AWSTemplateFormatVersion: '2010-09-09'
Resources:
# OIDCプロバイダー
OIDCProvider:
Type: AWS::IAM::OIDCProvider
Properties:
Url: https://oidc.eks.ap-northeast-1.amazonaws.com/id/<oidc-provider-id>
ClientIdList:
- sts.amazonaws.com
ThumbprintList:
- <oidc-thumbprint>
# クロスアカウントALBC用IAMロール
ALBControllerRole:
Type: AWS::IAM::Role
DependsOn: OIDCProvider
Properties:
RoleName: test-cross-account-alb-controller-role
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Federated: !Ref OIDCProvider
Action: sts:AssumeRoleWithWebIdentity
Condition:
StringEquals:
oidc.eks.ap-northeast-1.amazonaws.com/id/<oidc-provider-id>:aud: "sts.amazonaws.com"
oidc.eks.ap-northeast-1.amazonaws.com/id/<oidc-provider-id>:sub: "system:serviceaccount:kube-system:aws-load-balancer-controller"
ManagedPolicyArns:
- <ALBControllerPolicyのARN>
クロスアカウント接続の仕組み:
クロスアカウント接続は、OIDC ProviderとIAMロールの信頼関係を活用しています。
クロスアカウント接続の詳細な実装方法については、以下のAWS公式ブログを参照してください:
Expose Amazon EKS pods through cross-account load balancer
1. nw-accountでのOIDC Providerの作成
eks-accountのEKSクラスターには、クラスター作成時に自動的にOIDC Provider URLが発行されます(例: https://oidc.eks.ap-northeast-1.amazonaws.com/id/XXXXX)。このOIDC Providerは、Kubernetes ServiceAccountに対してJWT(JSON Web Token)を発行する役割を持ちます。
nw-accountでは、このeks-accountのOIDC Provider URLを使用して、IAM OIDC Providerを作成します。これにより、nw-accountのIAMは、eks-accountのKubernetesクラスターが発行するトークンを信頼できるようになります。
2. IAMロールの信頼関係設定
nw-accountで作成するIAMロールには、OIDC ProviderをプリンシパルとしてAssumeRoleWithWebIdentityアクションを許可し、eks-accountの特定のServiceAccountのみがロールを引き受けられるよう制限する信頼ポリシーを設定します。
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<nw-account-id>:oidc-provider/oidc.eks.ap-northeast-1.amazonaws.com/id/XXXXX"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.ap-northeast-1.amazonaws.com/id/XXXXX:aud": "sts.amazonaws.com",
"oidc.eks.ap-northeast-1.amazonaws.com/id/XXXXX:sub": "system:serviceaccount:kube-system:aws-load-balancer-controller"
}
}
}]
}
- Principal.Federated: nw-accountで作成したOIDC ProviderのARNを指定
-
Action:
sts:AssumeRoleWithWebIdentityを許可(OIDC経由のロール引き受けを許可) - Condition.StringEquals: JWTトークンのクレーム(claim)を検証することで、ロール引き受けを制限
3. ServiceAccountとIAMロールの関連付け
eks-accountでは、eksctl create iamserviceaccountコマンドを使用して、Kubernetes ServiceAccountにnw-accountのIAMロールARNをアノテーションとして付与します。
apiVersion: v1
kind: ServiceAccount
metadata:
name: aws-load-balancer-controller
namespace: kube-system
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::<nw-account-id>:role/test-cross-account-alb-controller-role
このアノテーションにより、ServiceAccountを使用するPodは、指定されたIAMロールを引き受けることができます。
トラブルシューティング
ここからは、実際の構築中に発生した問題とその解決方法を紹介します。
NodePoolが作成されない
事象:
kubectl get nodepoolを実行してもNodePoolが表示されない、またはNodeClassのReadyステータスがFalseになっている。
kubectl get nodepool
# No resources found
# または
kubectl get nodeclass
NAME ROLE READY AGE
custom-nodeclass arn:aws:iam::<account-id>:role/test-eks-node-role False 2m
原因と対処:
この問題の主な原因として、NodeClassの設定エラー、IAMロールの権限不足、またはネットワーク設定の誤りが考えられます。
まず、NodeClassのステータスを詳細に確認してください:
kubectl describe nodeclass <nodeclass-name>
NodeClassのStatus.Conditionsセクションで、以下のようななエラーが表示されます:
1. SecurityGroupsNotFound エラー
Status:
Conditions:
Type: SecurityGroupsReady
Status: False
Reason: SecurityGroupsNotFound
Message: SecurityGroupSelector did not match any SecurityGroups
このエラーは、NodeClassのsecurityGroupSelectorTermsに指定したセキュリティグループIDが存在しない、または誤っている場合に発生します。
2. UnauthorizedNodeRole エラー
Status:
Conditions:
Type: InstanceProfileReady
Status: False
Reason: UnauthorizedNodeRole
Message: Role arn:aws:iam::<account-id>:role/<node-role-name> is unauthorized to join nodes to the cluster
原因と対処:
このエラーは、指定したIAMロールがEKSクラスターにノードを参加させる権限を持っていない場合に発生します。
以下を確認しましょう。
- Access Entryが正しく作成されているかを確認
- Access Entryのタイプが
EC2であることを確認 - Access Entryに
AmazonEKSAutoNodePolicyが付与されているかを確認 - IAMロールに必要なポリシー(
AmazonEC2ContainerRegistryPullOnly、AmazonEKSWorkerNodeMinimalPolicy)が付与されているかを確認
# Access Entryの確認
aws eks list-access-entries --cluster-name <cluster-name>
aws eks describe-access-entry --cluster-name <cluster-name> --principal-arn <node-role-arn>
NodeClassがReady: Trueになれば、NodePoolも正常に作成されます。
同じアカウント用 Target Group Bindingが機能しない
事象:
Target Group Bindingを作成したにもかかわらず、Target Groupにターゲットが登録されない。
原因と対処:
一つの原因は、Target Group BindingのapiVersionの設定誤りです。Auto Mode管理のLoad Balancer Controllerを使用する場合はeks.amazonaws.com/v1、セルフマネージドを使用する場合はelbv2.k8s.aws/v1beta1を指定する必要があります。直近でAPIバージョンが変更になっていました。
また、Auto Modeで管理されるLoad Balancer Controllerを使用する場合、Target Groupにeks:eks-cluster-nameタグが設定されているかを確認してください。このタグがないと、コントローラーがTarget Groupを認識できません。
上記の確認でも問題が解決しない場合、以下のコマンドでLoad Balancer Controllerのログを確認し、詳細なエラー情報を確認できます。
kubectl logs -n kube-system deployment/aws-load-balancer-controller
TargetGroupBindingやService作成時の内部エラー(Webhook通信エラー)
事象:
Target Group Bindingを作成しようとすると、以下のような内部エラーが発生し、リソースが作成できない。
Error from server (InternalError): error when creating "target-group-binding.yaml": Internal error occurred: failed calling webhook "mtargetgroupbinding.elbv2.k8s.aws"
また、AWS Load Balancer Controller(カスタム)をインストールした後、Serviceリソースを作成しようとすると、Webhook検証がタイムアウトしてブロックされることがあります。
Error: INSTALLATION FAILED: 1 error occurred:
* Internal error occurred: failed calling webhook "mservice.elbv2.k8s.aws": failed to call webhook: Post "https://aws-load-balancer-webhook-service.kube-system.svc:443/mutate-v1-service?timeout=10s": context deadline exceeded
PodやPodDisruptionBudget(PDB)などは問題なく作成されますが、Serviceだけが作成されませんでした。また、カスタムLoad Balancer Controllerをアンインストールすると、Serviceは正常に作成できるようになりました。
原因と対処:
一見、カスタムのAWS Load Balancer Controllerをインストールしたからかと思いましたが、AWS Load Balancer Controllerは、TargetGroupBindingやService作成時にMutating Webhookとして動作し、TCP 9443ポートでWebhookリクエストを待ち受けます。
リソース作成時には、まずEKSコントロールプレーンのAPIサーバーがリソース作成リクエストを受け取り、次にAPIサーバーからAWS Load Balancer ControllerのPod(Webhook)に対してTCP 9443ポートで検証リクエストを送信します。Webhookがレスポンスを返すことで、リソース作成が完了します。
このとき、EKSクラスターのセキュリティグループのアウトバウンドルールで、自分自身(同一セキュリティグループ)に対するTCP 9443ポートへの接続が許可されていない場合、Webhook通信が失敗し、内部エラーまたはタイムアウトエラーが発生します。
そのため、EKSクラスターのコントロールプレーンとワーカーノード間の通信に使用されるセキュリティグループに、TCP 9443の通信を許可するアウトバウンドルールを追加します。
参考情報:
- aws-load-balancer-controller - Webhook Configuration
- AWS Load Balancer Controller を利用した TargetGroupBinding のパターン
クロスアカウント接続の失敗
事象:
セルフマネージドのLoad Balancer Controllerを使用して、別アカウントのALBへの接続を試みたが、接続が失敗します。
原因と対処:
クロスアカウント接続が失敗する原因として、OIDC Providerの設定ミス、IAMロールの信頼関係の問題、または権限不足が考えられます。以下の手順で、ServiceAccountの設定、OIDCの設定、各アカウントでの作業が正しく行われているかを確認してください。
1. eks-accountでのServiceAccount設定確認
まず、eks-accountでLoad Balancer ControllerのServiceAccountが正しく設定されているかを確認します。
# ServiceAccountの存在とアノテーションを確認(eks-accountで実行)
kubectl get serviceaccount aws-load-balancer-controller -n kube-system -o yaml
# 以下のアノテーションが設定されているかを確認
# eks.amazonaws.com/role-arn: arn:aws:iam::<nw-account-id>:role/<cross-account-role-name>
2. nw-accountでのOIDC Provider確認
nw-accountでOIDC Providerが正しく作成されているかを確認します。特にThumbprintが正しい値になっているかを確認することが重要です。
# OIDC Providerの存在を確認(nw-accountで実行)
aws iam list-open-id-connect-providers
# OIDC ProviderのURLがeks-accountのEKSクラスターのOIDC Provider URLと一致するかを確認
# 例: arn:aws:iam::<nw-account-id>:oidc-provider/oidc.eks.ap-northeast-1.amazonaws.com/id/XXXXX
Thumbprintの取得方法は、AWS公式ドキュメントを参照してください。
3. nw-accountでのIAMロール設定確認
IAMロールの信頼関係を確認します。Conditionブロックにて、OIDC Provider IDが正しく設定されているか、ServiceAccountの名前空間(kube-system)とサービスアカウント名(aws-load-balancer-controller)、OIDC Providerの情報が正しく指定されているかを確認してください。
3. ネットワーク接続の確認
eks-accountとnw-account間のネットワーク接続(Transit GatewayやVPC Peeringなど)が正しく設定されているかを確認してください。
まとめ
今回のプロジェクトでは、EKS Auto Modeの標準機能では対応できない複雑な要件に対し、カスタムNodePoolの活用、クロスアカウント接続の実現、インスタンスタイプの固定化などのカスタマイズを実施することで、運用負荷の大幅削減とコスト最適化を両立しました。
1. コスト最適化と運用自動化の両立
- 組み込みNodePool(General Purpose/System)を無効化し、カスタムNodePoolのみで運用することで、月次コストを約30%削減
- Auto Modeを利用することで、運用チームの負担を約70%削減
2. アーキテクチャ要件への対応
- 特定のインスタンスタイプ(m5a.large/xlarge)に固定することで、AMDアーキテクチャ依存アプリケーションの安定稼働を実現
- インスタンスタイプを固定化することで、パフォーマンスの予測可能性が向上
3. クロスアカウントネットワーク接続
- Auto Mode管理とセルフマネージドのAWS Load Balancer Controllerを共存させることで、マルチアカウント環境での柔軟なALB接続を実現


