3時間弱でEKSに入門できるハンズオン、Introduction to Amazon EKSをやってみた #AWSSummit

3時間ちょっとでAmazon EKS入門!ぜひ休日や隙間時間に触ってみてください。なんとなくKubernetes敷居高そう・・・と思って後回しにしていたKubernetes学習も本ハンズオンで短時間で概要をざっくり掴んで入門する事が出来ます。
2020.09.22

どうも、もこ@札幌オフィスです。

現在開催中のAWS Summit Onlineで公開されている「Introduction to Amazon EKS」のハンズオンをやってみました。

なんとなくKubernetes敷居高そう・・・と思って後回しにしていたKubernetes学習も本ハンズオンで短時間で概要をざっくり掴んで入門する事が出来ます。

概要

アマゾン ウェブ サービス ジャパン株式会社 プロフェッショナルサービス本部 インフラストラクチャーアーキテクト 杉田 想土

このハンズオンでは Amazon Elastic Kubernetes Service (Amazon EKS) と eksctl を使用して、マネージドな Kubernetes クラスターを実行します。サンプル Web アプリケーションをビルドして Kuberneres クラスターにデプロイし、kubectl コマンドによる Kubernetes の操作と、Amazon EKS 上でのアプリケーションの実行を体験していただきます。

ハンズオン資料はこちらとなっています。

実際にハンズオンをやってみる

早速ハンズオンをやって行きたいと思います。

本記事ではハンズオンの雰囲気を味わって貰うため詳細な手順や説明を省いた形とさせて頂きますが、気になった方は期間中に実際にハンズオン資料を片手にやってみてください!(ハンズオン資料はKubernetesを初めて触る方でも手順通りにやれば理解出来る内容になっています。)

ステップは下記の通りになっています。

  1. AWS Cloud9による環境の作成
  2. eksctlによるクラスターの作成
  3. kubectlによるクラスターの状態確認
  4. サンプルWebアプリケーションのデプロイ
  5. クリーンアップ

AWS Cloud9による環境の作成

本ハンズオンではCloud9のCLIを利用してeksctl/kubectlコマンドをブラウザ上で実行していきます。

※AWSのCredentialがあるローカルマシンや、EC2などの上で実行しても問題ないとは思います

本ハンズオンではバージニアリージョン(us-east-1)での実行を前提として書かれていますので、本記事でもus-east-1で環境を作っていきますが、CLIにどうしても遅延が発生するため、東京リージョン(ap-northeast-1)を利用してもus-east-1部分を置換して設定すれば問題なくハンズオンを行うことが出来ます。

そうしましたら、Cloud9のサービスページに移動して、任意の名前を入力して、Next Stpeを押します。

次のステップでCloud9の環境設定を行い、「Create environment」を押してCloud9の環境を作っていきます。

2分ほどすると、Cloud9のトップページが表示されるようになります!

続いてCloud9のIAMロールの設定を行います。

AdministratorAccess 権限を付与したIAMロールを作成して、Cloud9のインスタンスに対してIAMロールを付与してあげます。

IAMロールの設定が完了しましたら、Cloud9の画面に戻り、右上の歯車から AWS Settings > CredentialsAWS managed temporary credentials を無効化して、EC2に割り当てたIAM Roleを利用するように設定します。

Cloud9下部のターミナルを利用して、念のため ~/.aws/credentials のファイルを削除して、インストールされているAWS CLIのバージョンが 1.18.17 以上であることを確認します。

$ rm -vf ${HOME}/.aws/credentials
$ aws --version
aws-cli/1.18.139 Python/3.6.12 Linux/4.14.193-113.317.amzn1.x86_64 botocore/1.17.62

次にリージョンを設定して、IAM Roleが正常に使えているのかを確認します。

$ aws configure set default.region us-east-1
$ aws sts get-caller-identity
{
    "UserId": "xxxxxxxxxxxx:i-03c62aa4f3ef8a2a5",
    "Account": "xxxxxxxxxxxx",
    "Arn": "arn:aws:sts::xxxxxxxxxxxx:assumed-role/eks-handson-admin/i-03c62aa4f3ef8a2a5"
}

EC2に割り当てられたIAM Roleを利用出来ていることを確認出来たらOKです。

eksctlによるクラスターの作成

早速eksctlとkubectlを導入していきます。

# eksctl
$ curl -L "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   153  100   153    0     0   3731      0 --:--:-- --:--:-- --:--:--  3731
100   651  100   651    0     0  10333      0 --:--:-- --:--:-- --:--:-- 10333
100 20.5M  100 20.5M    0     0  21.5M      0 --:--:-- --:--:-- --:--:-- 20.5M
$ sudo mv /tmp/eksctl /usr/local/bin
$ eksctl version
0.28.0
# kubectl
$ sudo curl -L -o /usr/local/bin/kubectl https://amazon-eks.s3.us-west-2.amazonaws.com/1.17.7/2020-07-08/bin/linux/amd64/kubectl
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 56.6M  100 56.6M    0     0  10.0M      0  0:00:05  0:00:05 --:--:-- 11.6M
$ sudo chmod +x /usr/local/bin/kubectl
$ kubectl version --short --client
Client Version: v1.17.7-eks-bffbac

導入が終わりましたら、早速クラスターを作っていきます。

$ eksctl create cluster \
>   --name=ekshandson \
>   --version 1.17 \
>   --nodes=3 --managed \
>   --region us-east-1 --zones us-east-1a,us-east-1c
[ℹ]  eksctl version 0.28.0
[ℹ]  using region us-east-1
[ℹ]  subnets for us-east-1a - public:192.168.0.0/19 private:192.168.64.0/19
[ℹ]  subnets for us-east-1c - public:192.168.32.0/19 private:192.168.96.0/19
...

クラスターの作成が終わるまで時間がかかるので、その間に別Terminalで便利ツールと設定を行います。

# jq, bash-completionインストール
$ sudo yum -y install jq bash-completion
# dockerのコマンド補完設定
$ sudo curl -L -o /etc/bash_completion.d/docker https://raw.githubusercontent.com/docker/cli/master/contrib/completion/bash/docker
# docker-compose導入/補完設定
$ sudo curl -L -o /usr/local/bin/docker-compose "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)"
$ sudo chmod +x /usr/local/bin/docker-compose
$ sudo curl -L -o /etc/bash_completion.d/docker-compose https://raw.githubusercontent.com/docker/compose/1.26.2/contrib/completion/bash/docker-compose
# kubectlとeksctlのコマンド補完設定
$ kubectl completion bash > kubectl_completion
$ sudo mv kubectl_completion /etc/bash_completion.d/kubectl
$ eksctl completion bash > eksctl_completion
$ sudo mv eksctl_completion /etc/bash_completion.d/eksctl

Kubernetes界隈ではkキーの刻印が擦り切れてから一人前(要出典)と言われているらしいので、ハンズオンでも紹介されているkubectlのaliasも設定しておきます。

$ cat <<"EOT" >> ${HOME}/.bash_profile

alias k="kubectl"
complete -o default -F __start_kubectl k
EOT

kube-ps1 / kubectx / kubens / sternも導入します。

# kube-ps1
$ git clone https://github.com/jonmosco/kube-ps1.git ~/.kube-ps1
$ cat <<"EOT" >> ~/.bash_profile

source ~/.kube-ps1/kube-ps1.sh
function get_cluster_short() {
  echo "$1" | cut -d . -f1
}
KUBE_PS1_CLUSTER_FUNCTION=get_cluster_short
KUBE_PS1_SUFFIX=') '
PS1='$(kube_ps1)'$PS1
EOT

# kubectx / kubens
$ git clone https://github.com/ahmetb/kubectx.git ~/.kubectx
$ sudo ln -sf ~/.kubectx/completion/kubens.bash /etc/bash_completion.d/kubens
$ sudo ln -sf ~/.kubectx/completion/kubectx.bash /etc/bash_completion.d/kubectx
$ cat <<"EOT" >> ~/.bash_profile

export PATH=~/.kubectx:$PATH
EOT

# stern
$ sudo curl -L -o /usr/local/bin/stern https://github.com/wercker/stern/releases/download/1.11.0/stern_linux_amd64
$ sudo chmod +x /usr/local/bin/stern

ここまで設定が終わったら、ターミナルを開き直してコマンド補完などの設定を反映します。

kubectlによるクラスターの状態確認

クラスターの作成が完了したら、早速クラスターの状態を確認していきます。

$ eksctl get cluster
NAME            REGION
ekshandson      us-east-1
$ kubectl cluster-info
Kubernetes master is running at https://F6D986B5E43112F75575806C261F0258.gr7.us-east-1.eks.amazonaws.com
CoreDNS is running at https://F6D986B5E43112F75575806C261F0258.gr7.us-east-1.eks.amazonaws.com/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
$ kubectl get node
NAME                            STATUS   ROLES    AGE     VERSION
ip-192-168-1-186.ec2.internal   Ready    <none>   7m27s   v1.17.9-eks-4c6976
ip-192-168-45-94.ec2.internal   Ready    <none>   7m29s   v1.17.9-eks-4c6976
ip-192-168-59-6.ec2.internal    Ready    <none>   7m31s   v1.17.9-eks-4c6976
$ kubectl describe node ip-192-168-1-186.ec2.internal
Name:               ip-192-168-1-186.ec2.internal
Roles:              <none>
Labels:             alpha.eksctl.io/cluster-name=ekshandson
...

EC2 3台分のインスタンスが正常にnodeとして登録されていることを確認出来ます。

続いてnamespaceを確認してみます。

$ kubectl get namespace
NAME              STATUS   AGE
default           Active   25m
kube-node-lease   Active   25m
kube-public       Active   25m
kube-system       Active   25m

初期段階で4つのnamespaceがあることを確認出来ます。

pod一覧を取得してみます。

$ kubectl get pod -A
NAMESPACE     NAME                       READY   STATUS    RESTARTS   AGE
kube-system   aws-node-2tpzd             1/1     Running   0          21m
kube-system   aws-node-f5p2q             1/1     Running   0          21m
kube-system   aws-node-pb7c2             1/1     Running   0          21m
kube-system   coredns-75b44cb5b4-52qh5   1/1     Running   0          27m
kube-system   coredns-75b44cb5b4-6zw4w   1/1     Running   0          27m
kube-system   kube-proxy-4mrsf           1/1     Running   0          21m
kube-system   kube-proxy-dj9x4           1/1     Running   0          21m
kube-system   kube-proxy-q9tkm           1/1     Running   0          21m

kube-system で複数のpodが動いていることを確認出来ます。

・aws-node は Pod にネットワーク機能を提供する Amazon VPC CNI Plugin for Kubernetes です

coredns は Kubernetes クラスター内の名前解決を提供する DNS サーバーです

kube-proxy は Kubernetes Service の機能を提供する Kubernetes のコンポーネントです

— ハンズオン資料より

続いてget podに-o wideを付けて、より詳細な情報を取得してみましょう。

$ kubectl get pod -n kube-system -o wide
NAME                       READY   STATUS    RESTARTS   AGE   IP               NODE                            NOMINATED NODE   READINESS GATES
aws-node-2tpzd             1/1     Running   0          35m   192.168.45.94    ip-192-168-45-94.ec2.internal   <none>           <none>
aws-node-f5p2q             1/1     Running   0          35m   192.168.1.186    ip-192-168-1-186.ec2.internal   <none>           <none>
aws-node-pb7c2             1/1     Running   0          35m   192.168.59.6     ip-192-168-59-6.ec2.internal    <none>           <none>
coredns-75b44cb5b4-52qh5   1/1     Running   0          41m   192.168.47.187   ip-192-168-59-6.ec2.internal    <none>           <none>
coredns-75b44cb5b4-6zw4w   1/1     Running   0          41m   192.168.53.243   ip-192-168-59-6.ec2.internal    <none>           <none>
kube-proxy-4mrsf           1/1     Running   0          35m   192.168.59.6     ip-192-168-59-6.ec2.internal    <none>           <none>
kube-proxy-dj9x4           1/1     Running   0          35m   192.168.45.94    ip-192-168-45-94.ec2.internal   <none>           <none>
kube-proxy-q9tkm           1/1     Running   0          35m   192.168.1.186    ip-192-168-1-186.ec2.internal   <none>           <none>

PodのIPアドレスと稼働しているNodeを確認することが出来ます。

kube-proxy Podの詳細を確認してみましょう。

$ kubectl describe pod -n kube-system kube-proxy-4mrsf
Name:                 kube-proxy-4mrsf
Namespace:            kube-system
Priority:             2000001000
Priority Class Name:  system-node-critical
Node:                 ip-192-168-59-6.ec2.internal/192.168.59.6
Start Time:           Mon, 21 Sep 2020 21:39:32 +0000
Labels:               controller-revision-hash=78db775dbb
                      k8s-app=kube-proxy
                      pod-template-generation=1
Annotations:          kubernetes.io/psp: eks.privileged
Status:               Running
IP:                   192.168.59.6
...
Events:
  Type    Reason     Age   From                                   Message
  ----    ------     ----  ----                                   -------
  Normal  Scheduled  38m   default-scheduler                      Successfully assigned kube-system/kube-proxy-4mrsf to ip-192-168-59-6.ec2.internal
  Normal  Pulling    38m   kubelet, ip-192-168-59-6.ec2.internal  Pulling image "602401143452.dkr.ecr.us-east-1.amazonaws.com/eks/kube-proxy:v1.17.9-eksbuild.1"
  Normal  Pulled     38m   kubelet, ip-192-168-59-6.ec2.internal  Successfully pulled image "602401143452.dkr.ecr.us-east-1.amazonaws.com/eks/kube-proxy:v1.17.9-eksbuild.1"
  Normal  Created    38m   kubelet, ip-192-168-59-6.ec2.internal  Created container kube-proxy
  Normal  Started    38m   kubelet, ip-192-168-59-6.ec2.internal  Started container kube-proxy

IPアドレス、Volumeなどの情報の他、イベントなどの情報を取得することが出来ました。

json形式で出力してjqで抽出するようなことも出来ます。

$ kubectl get pod -n kube-system kube-proxy-4mrsf -o json | jq -r '.status.conditions'                                                      
[
  {
    "lastProbeTime": null,
    "lastTransitionTime": "2020-09-21T21:39:32Z",
    "status": "True",
    "type": "Initialized"
  },
  {
    "lastProbeTime": null,
    "lastTransitionTime": "2020-09-21T21:39:51Z",
    "status": "True",
    "type": "Ready"
  },
  {
    "lastProbeTime": null,
    "lastTransitionTime": "2020-09-21T21:39:51Z",
    "status": "True",
    "type": "ContainersReady"
  },
  {
    "lastProbeTime": null,
    "lastTransitionTime": "2020-09-21T21:39:32Z",
    "status": "True",
    "type": "PodScheduled"
  }
]

サンプルWebアプリケーションのデプロイ

掲示板ライクなWebアプリケーションをクラスター上にデプロイしていきます。

Web UIを提供するfrontendアプリケーションとAPIを提供するbackendアプリケーションで出来ていて、backendアプリケーションがDynamoDBにデータを保存する形になります。

—画像はハンズオン資料より

早速AWS CLIでDynamoDBを作成します。

$ aws dynamodb create-table --table-name 'messages' \
  --attribute-definitions '[{"AttributeName":"uuid","AttributeType": "S"}]' \
  --key-schema '[{"AttributeName":"uuid","KeyType": "HASH"}]' \
  --provisioned-throughput '{"ReadCapacityUnits": 1,"WriteCapacityUnits": 1}'

続いて、ハンズオン資料に記載のリンクからソースコードをダウンロードして、展開した上でbuildしていきます。

$ wget https://eks-for-aws-summit-online.workshop.aws/sample-app.zip
$ unzip sample-app.zip
$ cd sample-app
$ docker-compose build

ビルドが完了したら、ECRリポジトリを作成していきます。

$ aws ecr create-repository --repository-name frontend
$ aws ecr create-repository --repository-name backend

続いて、docker-composeでビルドしたコンテナに対してタグを付けて、ECRにログインした上でImageをPushします。

# tagを付ける
$ frontend_repo=$(aws ecr describe-repositories --repository-names frontend --query 'repositories[0].repositoryUri' --output text)
$ backend_repo=$(aws ecr describe-repositories --repository-names backend --query 'repositories[0].repositoryUri' --output text)
$ docker tag frontend:latest ${frontend_repo}:latest
$ docker tag backend:latest ${backend_repo}:latest
# ecr login
$ ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
$ AWS_REGION=$(aws configure get default.region)
$ aws ecr get-login-password | docker login --username AWS --password-stdin https://${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com

# image push 
$ docker push ${frontend_repo}:latest
$ docker push ${backend_repo}:latest

ECRにPushし終わったら、早速デプロイの準備をしていきます。

frontendのnamespaceを作ってあげます。

$ kubectl create namespace frontend
namespace/frontend created
$ kubens frontend
Context "i-03c62aa4f3ef8a2a5@ekshandson.us-east-1.eksctl.io" modified.
Active namespace is "frontend".

続いて、マニフェストを作成していきます。

今回はこのようなマニフェストを用意しました。

frontend-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
spec:
  selector:
    matchLabels:
      app: frontend
  replicas: 2
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
      - name: frontend
        image: xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/frontend:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 5000
        env:
        - name: BACKEND_URL
          value: http://backend.backend:5000/messages

こちらをapplyしてあげます。

$ kubectl apply -f frontend-deployment.yaml -n frontend
deployment.apps/frontend created
$ kubectl get deployment -n frontend
NAME       READY   UP-TO-DATE   AVAILABLE   AGE
frontend   2/2     2            2           32s
$ kubectl get pod -n frontend
NAME                        READY   STATUS    RESTARTS   AGE
frontend-65f5c9fd48-9frw6   1/1     Running   0          67s
frontend-65f5c9fd48-m4jnz   1/1     Running   0          67s

frontendのPodが上がってきていることを確認出来ます!

続いてServiceのマニフェストを書いてapplyしてあげます。

frontend-service-lb.yaml

apiVersion: v1
kind: Service
metadata:
  name: frontend
spec:
  type: LoadBalancer
  selector:
    app: frontend
  ports:
  - protocol: TCP
    port: 80
    targetPort: 5000
$ kubectl apply -f frontend-service-lb.yaml -n frontend
service/frontend created
$ kubectl get service -n frontend
NAME       TYPE           CLUSTER-IP      EXTERNAL-IP                                                               PORT(S)        AGE
frontend   LoadBalancer   10.100.178.31   a9882a3999c894ed1a1dca04c3e5ff60-1769755766.us-east-1.elb.amazonaws.com   80:31363/TCP   10s

applyすると、CLBが作成されていることを確認出来ます。

しばらくしてからURLにアクセスすると、ロードバランサー経由でアクセス出来ていることを確認できます!

エラーが出てしまっているので、ログを確認してみましょう。

kubectl logs -n frontend <Pod名> でPod単位のログを見ることが出来ますが、sternを使うことで複数Podから出力されるログをまとめて見ることが出来ます。

$ stern frontend -n frontend
frontend-65f5c9fd48-m4jnz frontend   File "/usr/local/lib/python3.8/site-packages/urllib3/connection.py", line 159, in _new_conn
frontend-65f5c9fd48-m4jnz frontend     conn = connection.create_connection(
frontend-65f5c9fd48-m4jnz frontend   File "/usr/local/lib/python3.8/site-packages/urllib3/util/connection.py", line 61, in create_connection
frontend-65f5c9fd48-m4jnz frontend     for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):
frontend-65f5c9fd48-m4jnz frontend   File "/usr/local/lib/python3.8/socket.py", line 918, in getaddrinfo
frontend-65f5c9fd48-m4jnz frontend     for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
frontend-65f5c9fd48-m4jnz frontend socket.gaierror: [Errno -2] Name does not resolve

backendをデプロイしていないためエラーとなっています。

続けてbackendも同じような手順でデプロイしていきましょう。

ハンズオンに沿ってこのようなマニフェストを用意します。

backend-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
spec:
  selector:
    matchLabels:
      app: backend
  replicas: 2
  template:
    metadata:
      labels:
        app: backend
    spec:
      containers:
      - name: backend
        image: xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/backend:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 5000
        env:
        - name: AWS_DEFAULT_REGION
          value: us-east-1
        - name: DYNAMODB_TABLE_NAME
          value: messages

namespaceを作ってappyしていきます。

$ kubectl create namespace backend
namespace/backend created
$ kubens backend
Context "i-03c62aa4f3ef8a2a5@ekshandson.us-east-1.eksctl.io" modified.
Active namespace is "backend".
$ kubectl apply -f backend-deployment.yaml -n backend
deployment.apps/backend created
$ kubectl get pod -n backend
NAME                      READY   STATUS    RESTARTS   AGE
backend-685c96cc4-57tjk   1/1     Running   0          85s
backend-685c96cc4-r6wm2   1/1     Running   0          85s

続いて、backendのServiceを作ります。

クラスター外に公開する必要が無いので、typeはLoadBalancerではなく、ClusterIPで設定してapplyします。

backend-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: backend
spec:
  type: ClusterIP
  selector:
    app: backend
  ports:
  - protocol: TCP
    port: 5000
    targetPort: 5000
$ kubectl apply -f backend-service.yaml -n backend
service/backend created

この状態でfrontendにアクセスするとまだエラーが発生するようなので、ログを漁ってみます。

$ stern backend -n backend
...
backend-685c96cc4-57tjk backend botocore.exceptions.ClientError: An error occurred (AccessDeniedException) when calling the Scan operation: User: arn:aws:sts::xxxxxxxxxxxx:assumed-role/eksctl-ekshandson-nodegroup-ng-eb-NodeInstanceRole-F2R86NG3GYYS/i-0cccd1fa4a4fd437b is not authorized to perform: dynamodb:Scan on resource: arn:aws:dynamodb:us-east-1:xxxxxxxxxxxx:table/messages

どうやらbackendにDynamoDBの権限が無いため正常に処理出来ない状態になっているようです。

EKSでは IAM Roles for Service Accounts を利用してPodにIAMロールを付与することが出来ます。

早速OIDCプロバイダーを作成していきましょう。

$ eksctl utils associate-iam-oidc-provider \
    --cluster ekshandson \
    --approve
[ℹ]  eksctl version 0.28.0
[ℹ]  using region us-east-1
[ℹ]  will create IAM Open ID Connect provider for cluster "ekshandson" in "us-east-1"
[✔]  created IAM Open ID Connect provider for cluster "ekshandson" in "us-east-1"

AWSマネジメントコンソールを確認すると、IAMのIDプロバイダーに新たに追加されていることを確認出来ます。

続いてeksctlでServiceAccountを作ります。

今回はManaged Policyの AmazonDynamoDBFullAccess を利用しました。

$ eksctl create iamserviceaccount \
    --name dynamodb-messages-fullaccess \
    --namespace backend \
    --cluster ekshandson \
    --attach-policy-arn arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess \
    --override-existing-serviceaccounts \
    --approve

eksctlを実行すると裏でCloudFormationが実行されてIAMロールが作成されることを確認出来ます。

作成したServiceAccountを確認して、新たに作成されていることなどを確認出来ます。

$ kubectl get serviceaccount -n backend
NAME                           SECRETS   AGE
default                        1         23m
dynamodb-messages-fullaccess   1         4m20s
$ kubectl describe serviceaccount dynamodb-messages-fullaccess -n backend
Name:                dynamodb-messages-fullaccess
Namespace:           backend
Labels:              <none>
Annotations:         eks.amazonaws.com/role-arn: arn:aws:iam::xxxxxxxxxxxx:role/eksctl-ekshandson-addon-iamserviceaccount-ba-Role1-CEBU93M6GH19
Image pull secrets:  <none>
Mountable secrets:   dynamodb-messages-fullaccess-token-pkhmh
Tokens:              dynamodb-messages-fullaccess-token-pkhmh
Events:              <none>

それではbackendのマニフェストにServiceAccountを指定して、権限を利用するよう設定してあげて、applyしていきましょう。

backend-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
spec:
  selector:
    matchLabels:
      app: backend
  replicas: 2
  template:
    metadata:
      labels:
        app: backend
    spec:
      serviceAccountName: dynamodb-messages-fullaccess
      containers:
      - name: backend
        image: xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/backend:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 5000
        env:
        - name: AWS_DEFAULT_REGION
          value: us-east-1
        - name: DYNAMODB_TABLE_NAME
          value: messages
$ kubectl apply -f backend-deployment.yaml -n backend
deployment.apps/backend configured
$ kubectl get pod -n backend
NAME                       READY   STATUS        RESTARTS   AGE
backend-685c96cc4-57tjk    0/1     Terminating   0          26m
backend-7b86db9c46-lbhvw   1/1     Running       0          10s
backend-7b86db9c46-x5gwt   1/1     Running       0          12s

新しいPodができあがり、frontendにアクセスすると正常に表示されていることを確認出来ます!

クリーンアップ

EKSへ入門出来たところで、環境をクリーンアップしていきます。

eksctlで環境を削除して、DynamoDBを削除してECRを削除していく感じです。

# IAM Role削除
$ eksctl delete iamserviceaccount --cluster ekshandson --namespace backend --name dynamodb-messages-fullaccess
# namespaceごと削除
$ kubectl delete namespace frontend backend
# DynamoDB削除
$ aws dynamodb delete-table --table-name 'messages'
# ECR削除
$ aws ecr delete-repository --repository-name frontend --force
$ aws ecr delete-repository --repository-name backend --force
# EKSクラスター削除
$ eksctl delete cluster --name ekshandson

CLIでの作業が終わったら、Cloud9の環境とIAMロールも忘れずに削除して本ハンズオンは終了です。お疲れ様でした。

まとめ

本ハンズオンで3時間ちょっとでAmazon EKS/Kubernetesに入門することができました。

Kubernetes(EKS)に興味がある方はAWS Summit Onlineの開催期間中(2020/09/30まで)にハンズオンをやってみてください。

また、次のステップとして、Amazon EKS Workshop も公開されていますので、ぜひ触ってみてください!!