EKS on Fargate と EKS Auto Mode を MWAA から試してみた #PERSOL CAREER Advent Calender2025

はじめに

doda DevBizOps Group Advent Calendar 2025 の 18 日目を担当します、田中です。

今期よりバッチ基盤として MWAA(Managed Workflows for Apache Airflow) × EKS を扱う機会があったため、キャッチアップを兼ねて一からシステム構築しました。 また、既存業務システムでは EKS on Fargate を利用していますが、2024 年末に登場した EKS Auto Mode の活用も検討しています。今回の検証では Fargate と Auto Mode の両環境を構築しています。

実際に構築してみると、ネットワークや IAM 権限まわりを中心に多くの“躓きポイント”がありました。今回は、その学びを中心に、Fargate と Auto Mode の違いにも触れながら紹介していきます。

Fargate と Auto Mode の違い

すでに多くの記事で紹介されていますので詳細は割愛しますが、よりマネージドに Kubernetes を使いたい場合は Auto Mode が有力になる、という点が特徴です。

EKS Auto Mode を検討している背景

EKS on Fargate を運用する中で、以下の課題がありました。

1. DaemonSet が使えず、監視コンテナの起動が複雑になる

サイドカーで Datadog などを起動する必要があり、サイドカー起動 → 本体起動の順序調整が必要になるため、バッチ処理時間にも影響が出ます。

2. EKS Pod Identity が使えない

DaemonSet 不可のため Pod Identity が利用できず、IRSA に依存します。 その結果、クラスタ単位でのロール変更が必要となり、柔軟性に欠けます。

3. 起動のたびに ENI が作成され、コストが増える

Fargate は Pod ごとに ENI をアタッチするため、AWS Config のイベントが大量に発生します。イベントを記録する設定にしているとコスト増につながります。

4. アドオン管理が必要

CoreDNS や Metrics Server については公式のアドオンを利用できますが、使用するコンテナ数の調整やアドオンバージョンの更新など、運用上の設定は自分たちで管理する必要があります。

これらに対し Auto Mode であれば、以下のメリットがあります。

  • DaemonSet によるコンテナ起動ができる
  • ENI のアタッチは node に対して行われるのでアタッチの頻度が少なくなる
  • EKS アドオン管理が不要
  • Spot インスタンスを活用できる

MWAA × EKS の構成

今回構築したアーキテクチャは以下のとおりです。

MWAA は CDK(AWS Cloud Development Kit)で作成しました。 全量だと長くなるため、MWAA の環境設定のみ記載します。

...
new CfnEnvironment(this, 'MwaaEnvironment', {
  name: mwaaEnvironmentName,
  airflowVersion: '2.10.3',
  environmentClass: 'mw1.small',
  executionRoleArn: mwaaExecutionRole.roleArn,
  sourceBucketArn: props.mwaaBucket.bucketArn,
  dagS3Path: 'dags',
  loggingConfiguration: {
    schedulerLogs: { enabled: true, logLevel: 'INFO' },
    taskLogs: { enabled: true, logLevel: 'INFO' },
    webserverLogs: { enabled: true, logLevel: 'INFO' },
    workerLogs: { enabled: true, logLevel: 'INFO' },
    dagProcessingLogs: { enabled: true, logLevel: 'INFO' },
  },
  networkConfiguration: {
    securityGroupIds: [mwaaSg.securityGroupId],
    subnetIds: vpc.privateSubnets.map(subnet => subnet.subnetId),
  },
  webserverAccessMode: 'PUBLIC_ONLY',
  requirementsS3Path: 'requirements/requirements.txt',
  pluginsS3Path: 'plugins/',
  kmsKey: mwaaKmsKey.keyArn,
});
...

EKS クラスタは eksctl で作成しました。

# EKS on Fargate
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: my-cluster
  region: ap-northeast-1
  version: '1.34'

vpc:
  id: vpc-0af2e3f8f1a10879b
  cidr: 10.0.0.0/16
  subnets:
    private:
      ap-northeast-1a:
        id: subnet-00566b47d4873afdc
      ap-northeast-1c:
        id: subnet-0c4d67e31f73e9d65
  clusterEndpoints:
    privateAccess: true
    publicAccess: true
  publicAccessCIDRs:
    - xxx.xxx.xxx.xx/xx
  controlPlaneSecurityGroupIDs:
    - sg-00dd084bdfcba1dbf

iam:
  serviceRoleARN: arn:aws:iam::xxx:role/eks-cluster-role
  fargatePodExecutionRoleARN: arn:aws:iam::xxx:role/pod-execution-role
  withOIDC: true

accessConfig:
  authenticationMode: API
  accessEntries:
    - principalARN: arn:aws:iam::xxx:role/account-admin-role
      accessPolicies:
        - policyARN: arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy
          accessScope:
            type: cluster
    - principalARN: arn:aws:iam::xxx:role/MwaaStack-MwaaExecRoleC7B66667-3DiTKxrh7qrZ
      type: STANDARD
      kubernetesUsername: mwaa-service

addons:
  - name: coredns
    version: v1.12.1-eksbuild.2
    configurationValues: '{"replicaCount":1}'
    resolveConflicts: overwrite

fargateProfiles:
  - name: systems-profile
    podExecutionRoleARN: arn:aws:iam::xxx:role/pod-execution-role
    selectors:
      - namespace: default
      - namespace: kube-system
    subnets:
      - subnet-00566b47d4873afdc
      - subnet-0c4d67e31f73e9d65

  - name: batch-profile
    podExecutionRoleARN: arn:aws:iam::xxx:role/pod-execution-role
    selectors:
      - namespace: mwaa
    subnets:
      - subnet-00566b47d4873afdc
      - subnet-0c4d67e31f73e9d65
# EKS Auto Mode
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: my-cluster
  region: ap-northeast-1
  version: '1.34'

vpc:
  id: vpc-0af2e3f8f1a10879b
  cidr: 10.0.0.0/16
  subnets:
    private:
      ap-northeast-1a:
        id: subnet-00566b47d4873afdc
      ap-northeast-1c:
        id: subnet-0c4d67e31f73e9d65
  clusterEndpoints:
    privateAccess: true
    publicAccess: true
  publicAccessCIDRs:
    - xxx.xxx.xxx.xx/xx
  controlPlaneSecurityGroupIDs:
    - sg-00dd084bdfcba1dbf

iam:
  serviceRoleARN: arn:aws:iam::xxx:role/eks-auto-cluster-role
  withOIDC: true

accessConfig:
  authenticationMode: API

  accessEntries:
    - principalARN: arn:aws:iam::xxx:role/account-admin-role
      accessPolicies:
        - policyARN: arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy
          accessScope:
            type: cluster
    - principalARN: arn:aws:iam::xxx:role/MwaaStack-MwaaExecRoleC7B66667-3DiTKxrh7qrZ
      type: STANDARD
      kubernetesUsername: mwaa-service
autoModeConfig:
  enabled: true

構築時の躓きポイント

今回一番時間を使ったのはネットワークと IAM 権限周りでした。

1. MWAA の構築時間が長い

MWAA は内部で多くの AWS リソースを作成するため、新規構築、構築の際に数十分から一時間とかなり時間がかかります。 席を外して戻ってきたら失敗していたことが何度もありました。

2. MWAA から Airflow UI に接続できない(※一部未解決)

これが最も時間を使ったポイントです。 MWAA の Web サーバーは次の 2 モードがあります。

  • Public Access
  • Private Access

セキュリティを意識して Private を選択したのですが、Airflow UI にログインしようとするとタイムアウトが発生してしまいました。 以下 2 つの方法を試しましたが、解決には至りませんでした。

Private Access は諦め、Public Access に切り替えたところ正常動作しました。

3. MWAA 用ロール(IAM 権限)の設定が不足している

MWAA は ECS / SQS / CloudWatch Logs など裏側で多くの AWS サービスを利用します。 しかし、CloudFormation のエラーだけでは不足している権限が分かりづらいという問題があります。 AWSSupport-TroubleshootMWAAEnvironmentCreation を使うと「どの権限が不足しているか」が分かり、非常に助かりました。

4. MWAA から EKS Auto Mode へタスクを実行できない

Auto Mode では以下の IAM 権限設定が必要となり、調査に時間を使いました。

Fargate と Auto Mode を試しに比較してみた

実際にバッチ(Spring Batch)を実行し、イベントログを確認してみました。

Fargate の動き

mwaa          2m52s       Normal    Scheduled                 pod/hello-job-pod-18bdfaok                                     Successfully assigned mwaa/hello-job-pod-18bdfaok to fargate-ip-10-0-145-118.ap-northeast-1.compute.internal
...
default       2m53s       Normal    Starting                  node/fargate-ip-10-0-145-118.ap-northeast-1.compute.internal   Starting kubelet.
...
default       2m52s       Normal    NodeReady                 node/fargate-ip-10-0-145-118.ap-northeast-1.compute.internal   Node fargate-ip-10-0-145-118.ap-northeast-1.compute.internal status is now: NodeReady
...
mwaa          2m51s       Normal    Pulling                   pod/hello-job-pod-18bdfaok                                     Pulling image "xxx.dkr.ecr.ap-northeast-1.amazonaws.com/batch:latest"
...
mwaa          2m42s       Normal    Pulled                    pod/hello-job-pod-18bdfaok                                     Successfully pulled image "xxx.dkr.ecr.ap-northeast-1.amazonaws.com/batch:latest" in 8.525s (8.525s including waiting). Image size: 201319222 bytes.
mwaa          2m42s       Normal    Started                   pod/hello-job-pod-18bdfaok                                     Started container base
mwaa          2m42s       Normal    Created                   pod/hello-job-pod-18bdfaok                                     Created container: base
  1. Pod の割り当て
  2. Fargate ノード起動
  3. ノード Ready
  4. イメージ Pull
  5. コンテナ開始

Fargate ノードに Pod を割り当てていることが確認できました。

Auto Mode の動き

mwaa        3m30s       Warning   FailedScheduling                 pod/hello-job-pod-d5vmunz6        0/1 nodes are available: 1 node(s) had untolerated taint {CriticalAddonsOnly: }. no new claims to deallocate, preemption: 0/1 nodes are available: 1 Preemption is not helpful for scheduling.
...
mwaa        3m29s       Normal    Nominated                        pod/hello-job-pod-d5vmunz6        Pod should schedule on: nodeclaim/general-purpose-n2b6j
...
default     3m14s       Normal    Registered                       nodeclaim/general-purpose-n2b6j   Status condition transitioned, Type: Registered, Status: Unknown -> True, Reason: Registered
...
default     3m14s       Normal    Starting                         node/i-0825c434526e01d3b          Starting kubelet.
...
default     3m13s       Normal    NodeReady                        node/i-0825c434526e01d3b          Node i-0825c434526e01d3b status is now: NodeReady
...
mwaa        3m12s       Normal    Scheduled                        pod/hello-job-pod-d5vmunz6        Successfully assigned mwaa/hello-job-pod-d5vmunz6 to i-0825c434526e01d3b
...
mwaa        2m49s       Normal    Pulling                          pod/hello-job-pod-d5vmunz6        Pulling image "xxx.dkr.ecr.ap-northeast-1.amazonaws.com/batch:latest"
mwaa        2m45s       Normal    Pulled                           pod/hello-job-pod-d5vmunz6        Successfully pulled image "xxx.dkr.ecr.ap-northeast-1.amazonaws.com/batch:latest" in 3.885s (3.885s including waiting). Image size: 201319222 bytes.
mwaa        2m45s       Normal    Created                          pod/hello-job-pod-d5vmunz6        Created container: base
mwaa        2m45s       Normal    Started                          pod/hello-job-pod-d5vmunz6        Started container base
default     109s        Warning   InstanceTerminating              node/i-0825c434526e01d3b          Instance is terminating
...
default     58s         Normal    RemovingNode                     node/i-0825c434526e01d3b          Node i-0825c434526e01d3b event: Removing Node i-0825c434526e01d3b from Controller
  1. Pod を置けるノードがないため、FailedScheduling が発生
  2. Karpenter が NodeClaim を作成し、必要なスペックの EC2 を起動
  3. EC2 が Kubernetes ノードとして Registered → Ready
  4. Pod がノードに Scheduled → Pulling → Started
  5. ジョブが完了すると、その EC2 ノードは不要になるため自動で Terminate

EKS Audo Mode では必要な時だけ EC2 ノードを作成し、使い終わったら削除するという動きが確認できました。 また、使用しなくなったノードは 1 分弱で削除されることを知りました。

実行時間の差

シンプルなバッチでの比較では大きな差は出ませんでした。
※ 多数並行ジョブ実行時や、NodePool のスケール挙動などを含めた検証では差が出ると思われますが、今回はコストと時間の都合でここまでとしました。

まとめ

MWAA × EKS(Fargate / Auto Mode)の構築を通じて、想像以上にネットワーク・IAM 周りで多くの学びがありました。 特に EKS Auto Mode はまだ情報が少ないため、本記事が構築の参考になれば幸いです。 今後は Private Access での MWAA UI アクセスや、Auto Mode × 大量バッチでの性能比較など、さらに踏み込んだ検証にも挑戦していきたいです。

 

*

田中 貴弘 Tanaka Takahiro

プロダクト開発統括部 システムアーキテクト部 マイクロサービスグループ エンジニア

2023年4月にパーソルキャリアへ中途入社。dodaサイト開発チームを経て、2023年10月にdodaサイトのマイクロサービスPJTに参画。

※2025年12月現在の情報です。