「AWS無料相談会」をオンラインで開催中

EKS on Fargateを試してみた

こんにちは。関口です。
最近アベノマスクが家に届きました。

今回は、EKS on Fargateを試してみた内容を記したいと思います。

事前準備

以下のインストールが必要です。

クラスターを作成

$ export AWS_PROFILE=プロファイル名

$ eksctl create cluster 
--name fargate-tutorial-cluster 
--version 1.15 
--region ap-northeast-1 
--fargate 
--alb-ingress-access

作成されるまで暫し時間がかかります。
作成完了後、クラスタが正常に起動したことを確認します。

$ kubectl get nodes
NAME                                                         STATUS   ROLES    AGE   VERSION
fargate-ip-192-168-163-213.ap-northeast-1.compute.internal   Ready    <none>   14m   v1.15.10-eks-094994
fargate-ip-192-168-174-244.ap-northeast-1.compute.internal   Ready    <none>   14m   v1.15.10-eks-094994

ALB Ingress Controllerを作成

アプリに外部からアクセスできるようにするため、ALB Ingress Controllerをセットアップします。

まずは、Fargateのpodに対するIAM権限を設定します。
クラスタにoidc providerを紐付けてからALBのIAM権限を付与します。

$ eksctl utils associate-iam-oidc-provider --region=ap-northeast-1 --cluster=fargate-tutorial-cluster --approve
$ curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.4/docs/examples/iam-policy.json
$ policyArn=$(aws iam create-policy 
  --policy-name ALBIngressControllerIAMPolicy 
  --policy-document file://iam-policy.json | jq -r .Policy.Arn)
$ eksctl create iamserviceaccount --name alb-ingress-controller 
  --namespace kube-system 
  --cluster fargate-tutorial-cluster 
  --attach-policy-arn ${policyArn}  
  --approve --override-existing-serviceaccounts

成功すれば、以下のような情報が取得できます。

$ kubectl get sa -n kube-system alb-ingress-controller -o jsonpath="{.metadata.annotations['eks.amazonaws.com/role-arn']}"
arn:aws:iam::xxxxxxxxx:role/eksctl-fargate-tutorial-cluster-addon-iamser-Role1-UR4O1R9GAG0W

rbac-rolealb-ingress-controllerをdeployしていきます。
まずはrbac-roleをdeployします。

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.4/docs/examples/rbac-role.yaml

最後に、alb-ingress-controllerをdeployします。
マニフェストファイルを取得して、以下のように編集します。

$ wget https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.4/docs/examples/alb-ingress-controller.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/name: alb-ingress-controller
  name: alb-ingress-controller
  namespace: kube-system
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: alb-ingress-controller
  template:
    metadata:
      labels:
        app.kubernetes.io/name: alb-ingress-controller
    spec:
      containers:
        - name: alb-ingress-controller
          image: docker.io/amazon/aws-alb-ingress-controller:v1.1.4
          args:
            - --ingress-class=alb
            - --cluster-name=xxxx # クラスタ名
            - --aws-region=ap-northeast-1
            - --aws-vpc-id=vpc-xxxx # eksctlで作成されたVPCのid
          resources: {}
      serviceAccountName: alb-ingress-controller

VpcIdはawsコンソールもしくは以下のコマンドから確認できます。

$ eksctl get cluster --region ap-northeast-1 --name fargate-tutorial-cluster -o yaml

マニフェストファイル修正後、デプロイをします。

$ kubectl apply -f alb-ingress-controller.yaml

アプリを作成

今回はHello worldを返すシンプルなGoのWebアプリを用意しました。
同様のサンプルはgithubに用意しました。
https://github.com/jpskgc/eks-fargate-sample

まず、Docker imageを保存するためのレポジトリを作成します。
OutputのrepositoryUriをメモしておいてください。

$ aws ecr create-repository --repository-name fargate-tutorial

次にDocker Imageをビルドします。
先ほどのrepositoryUriを記入します。

$ docker build -t fargate-tutorial:1 .
$ docker tag fargate-tutorial:1 xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/fargate-tutorial:1

最後にDocker ImageをECRにpushします。
まず、AWS CLIでECRにログインします。

$ aws ecr get-login --region ap-northeast-1 --no-include-email

Outputをコピーしてそのままターミナルに貼り付けて実行すると、ログインに成功します。
ログイン成功後、pushします。

$ docker push xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/fargate-tutorial:1

アプリをデプロイ

最初に、新しいFargate profileを作成します。

eksctl create fargateprofile --namespace backend --cluster fargate-tutorial-cluster --region ap-northeast-1

次に、アプリをALBからアクセスするためのnamespace,service,deployment,ingressマニフェストを記述+deployします。

---
apiVersion: v1
kind: Namespace
metadata:
  name: backend
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: backend
  namespace: backend
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/scheme: internet-facing
spec:
  rules:
    - http:
        paths:
          - path: /
            backend:
              serviceName: backend
              servicePort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
  namespace: backend
  labels:
    app: backend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: backend
  strategy: {}
  template:
    metadata:
      labels:
        app: backend
    spec:
      containers:
        - name: backend
          image: #docker image
          ports:
            - containerPort: 8080
          resources: {}
---
kind: Service
apiVersion: v1
metadata:
  name: backend
  namespace: backend
spec:
  selector:
    app: backend
  type: NodePort
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
$ kubectl apply -f eks-fargate-sample/kubernetes/

以下のコマンドでingressのステータスをチェックします。

$ kubectl describe ing -n backend backend

ELBのヘルスチェックが通るまで数分待ってから、Outputのアドレスにアクセスすると、無事にHello worldが返されました。

$ curl http://e577236e-backend-backend-d465-578708176.ap-northeast-1.elb.amazonaws.com

Hello world

リソースの削除

$ eksctl delete cluster --region=ap-northeast-1 --name fargate-tutorial-cluster
$ kubectl delete -f namespace.yaml

上記のコマンドでもvpc,サブネット,インターネットゲートウェイの削除に失敗する場合は、別途手動で削除してください。

参考

EKS on FargateでALBからアプリにアクセスする
How to run Serverless Kubernetes: AWS EKS on Fargate
EKS on Fargateでguestbookアプリをデプロイする