Amazon EKS on Amazon Fargate を試す

はじめに

  • 以前の記事で AWS EKS (Elastic Kubernetes Service) ワーカーノードを EC2 上に作成しました。
  • EC2 のインスタンス上で実行されるワーカーノードを作成した場合、その EC2 インスタンスのリソースタイプをどうするか、スケールアウトをどうするかを考える必要があります。
  • 2019 年 12 月に「Amazon EKS on AWS Fargate」が利用可能となり、Fargate 上でも EKS が利用できる選択肢が増えました。
  • しかしながら、Fargate を利用できるメリットと同時に、EC2 で利用する場合との差異や制限事項を理解して利用する必要があります。
  • ここで、EKS on Fargate と通常の EKS との違いを見ていきながら、EKS on Fargate を試用してみます。

Fargate とは

f:id:linkode-okazaki:20200501191422p:plain

  • 公式ページ
  • Fargate は AWS 上で仮想マシンの管理なしにコンテナをデプロイできるサービスです。
    • 「サーバーレスコンテナ実行基盤」と称されます。
    • EC2 では仮想マシンが提供されますが、Fargate ではコンテナが提供されます。
    • インスタンスの選択やクラスター容量のスケーリングなしに、適切なリソースが割り当てられます。
  • タスク(コンテナの実行単位)に割り当てた vCPU とメモリの量に応じて秒単位での課金されます。
  • Amazon Elastic Container Service (ECS) の基本的な仕組み、APIAWS との連携が引き続き利用できます。

EKS on Fargate とは

  • 2019 年 12 月に利用可能となった、EKS の新たな実行体系です。
  • それまでは、EKS のワーカーノード EC2 上に作成するしかありませんでした。
  • EC2 を利用する場合と比較した場合の違いは以下のとおりです。
    • ノードの管理が不要になる
    • リソースタイプの指定が不要になる
    • EC2 のスケーリングを考えなくて良い
  • 上記の通り便利になる一方で、以下のような制約もあります。
    • GPU コンピューティングリソースは利用できません。
      • Fargate に用意されている VM のオプションには、GPU を利用できる設定はありません。
    • K8s の DaemonSet, HostPort, HostNetwork は非対応です。
      • Fargate では、ポッドとノードの関係が一対一である(のように見える)ため、クラスタ内の全ノードで同じポッドを実行するためのコントローラの DaemonSet はコンセプトが合いません。
      • HostPort と HostNetwork は、いずれも外部からポッドに直接アクセスできるようにするためのものですが、Fargate 上のポッドへのアクセスについては、後述する「Fargate プロファイル」の selectors で設定するため、HostPort や HostNetwork による設定はできません。
    • Fargate で実行されている各ポッドは、プロビジョニング後に、10 GB のコンテナイメージレイヤーストレージを受け取りますが、一時的なものであるため、ポッドが停止すると、ストレージは削除されます。
      • ステートフルなアプリケーションの場合は、S3 や DynamoDB などのサービスの利用を検討する必要があります。
    • 現時点では、Fargate で実行されているポッドにはパブリック IP アドレスが割り当てられません。
      • そもそも、EKS では、ポッドなどのワークロードはプライベートサブネットに配置して、Ingress や LoadBalancer を利用して外部からのアクセスを着信させることが推奨されています。
    • ELB や NLB がサポートされておらず、ポッドから見て外(ホスト、他の VPC、インターネット)と繋ぐ場合に制限がかかる
      • よって、外部に公開されたアプリケーションを提供する場合は、ALB を利用する必要があります(別記事で詳述します)。

EKS on Fargate を試しに使ってみる

条件の確認

  • EKS on Fargate は 2020 年 4 月 30 日現在、以下のリージョンでのみ利用可能です:
リージョン名 リージョン
米国東部 (オハイオ) us-east-2
米国東部(バージニア北部) us-east-1
アジアパシフィック (東京) ap-northeast-1
欧州 (アイルランド) eu-west-1
  • 既存の EKS クラスターの場合は、Kubernetes バージョン 1.14 以上 およびプラットフォームバージョン eks.5 以上であることを確認してください。
  • 以下の手順に沿ってコマンドライン上から操作する場合は、AWS CLI: 1.16.296 以降であることと、 eksctl: 0.11.0 以降であることを確認してください。

大まかな流れ

  • 導入に際しての大まかな流れは以下のとおりです。

  • EKS クラスター (=コントロールプレーン) を Fargate 利用前提で作成する

  • 「Fargate プロファイル」を作成する
  • kubectl コマンドを使って Kubernetes 上でポッドを起動する
  • ポッドの起動の要求に応じて自動的に Fargate が起動して、Fargate 上でポッドが実行される

Fargate 利用前提のEKS クラスターの作成

  • 以下のコマンドで EKS クラスターを作成します。
    • EC2 上に作成するときとの違いは、オプション--fargate をつけることと、ノードに関する設定を行わないことです。
$ eksctl create cluster \
  --name [クラスター名] \
  --region [リージョン名] \
  --fargate

Fargate プロファイルを作成する

  • Fargate プロファイルとは、EKS で Fargate を利用するための設定情報で、以下のようなコンポーネントが含まれています。
    • Fargate を利用するための権限とネットワークの設定
      • podExecutionRoleArn:ポッド実行ロールを指定します。
        • クラスターが AWS Fargate でポッドを作成する際、ポッドがユーザーに代わって AWS API を呼び出す必要があるため、それに利用するロールを指定します。
      • subnets:このプロファイルを使用するポッドを起動するサブネットの ID を指定します。
    • ポッドを Fargate 上で実行させる際の振り分け条件の設定
      • 以下のような指定方法を採る「ポッドセレクター」を利用します。
        • Kubernetes名前空間を指定する
          • 指定した名前空間に属するポッドは全て Fargate 上での実行対象とする
        • Kubernetes名前空間とラベルを指定する
          • 指定した名前空間に属するポッドのうち、ラベルに指定したキー・値が設定されているもののみを Fargate 上での実行対象とする
      • selecters.namespace名前空間を(必ず設定)、selecters.labels でキー・値を設定します。
{
    "fargateProfileName": "",
    "clusterName": "",
    "podExecutionRoleArn": "",
    "subnets": [
        ""
    ],
    "selectors": [
        {
            "namespace": "",
            "labels": {
                "KeyName": ""
            }
        }
    ],
    "clientRequestToken": "",
    "tags": {
        "KeyName": ""
    }
}
  • 先ほどのコマンドで EKS クラスターを作成した場合、デフォルトで「fp-default」という Fargate プロファイルが作成されており、以下のコマンドで内容を確認することが出来ます。
$ eksctl get fargateprofile --cluster [クラスター名] -o yaml
- name: fp-default
  podExecutionRoleARN: arn:aws:iam::123456789012:role/eksctl-[クラスター名]-cluster-FargatePodExecutionRole-XXXXXXXXXXXXX
  selectors:
  - namespace: default
  - namespace: kube-system
  subnets:
  - subnet-12345678901234567
  - subnet-123456789abcdefgh
  - subnet-99999999999999999
  • 新たに Fargate プロファイルを作成する場合は、以下のコマンドを利用します。
    • --labelsの指定は必須ではありません。
$ eksctl create fargateprofile --cluster [クラスター名] --name [プロファイル名] --namespace [名前空間名] --labels [キー]=[値]

ポッドを起動する

  • 以下のコマンドでノードを確認します。
    • 2 つ存在されていることがわかります。
$ kubectl get nodes
NAME                                                   STATUS   ROLES    AGE    VERSION
fargate-ip-192-168-103-57.us-east-2.compute.internal   Ready    <none>   144m   v1.15.10-eks-094994
fargate-ip-192-168-103-93.us-east-2.compute.internal   Ready    <none>   144m   v1.15.10-eks-094994
  • 次に、ポッドを起動します。nginx を起動するだけのデプロイメントを作成します。
$ kubectl create deployment sample-app --image=nginx
deployment.apps/sample-app created
  • ポッドの状態を確認し、起動したことを確認します。
$ kubectl get pods
NAME                          READY   STATUS    RESTARTS   AGE
sample-app-74f4666b57-p2w95   1/1     Running   0          44s
  • 再び、ノードを確認すると、3 つ目が増えていることがわかります。
    • これは、ポッドの実行要求によりオンデマンドで Fargate が起動され、Fargate 上でポッドが実行されたということを意味します。
$ kubectl get nodes
NAME                                                   STATUS   ROLES    AGE    VERSION
fargate-ip-192-168-103-57.us-east-2.compute.internal   Ready    <none>   149m   v1.15.10-eks-094994
fargate-ip-192-168-103-93.us-east-2.compute.internal   Ready    <none>   149m   v1.15.10-eks-094994
fargate-ip-192-168-163-63.us-east-2.compute.internal   Ready    <none>   26s    v1.15.10-eks-094994
  • ポッドを終了するとノードも消滅します。
$ kubectl delete deployment sapmle-app
deployment.extensions "sapmle-app" deleted
$ kubectl get pods
No resources found in default namespace.
$ kubectl get nodes
NAME                                                   STATUS   ROLES    AGE    VERSION
fargate-ip-192-168-103-57.us-east-2.compute.internal   Ready    <none>   156m   v1.15.10-eks-094994
fargate-ip-192-168-103-93.us-east-2.compute.internal   Ready    <none>   155m   v1.15.10-eks-094994
  • 以上のように、EC2 のワーカーノードと異なり、必要な時にのみノードが立ち上がるのが Fargate の特徴です。

まとめ

  • EKS の実行形態として Fargate の選択肢が増えたことにより、コンテナアプリケーションの運用コストは更に下がることが期待されます。
  • ただし、現時点では制約事項も多くあり、既存の EC2 で起動しているクラスタを移行させるのは慎重になるべきと思われます。
  • 新たなアプリケーションの場合は、強力な選択肢になります。
  • ALB を利用した外部へのアプリケーションの公開方法については、別の記事で紹介します。

参考