1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AWS EKS 〜 demo

Last updated at Posted at 2020-10-29

1.CLOUD9 環境の作成#

1-1.CLOUD9 環境の作成##

本ハンズオンは、全て、「バージニア北部」で実行していきます。

「Cloud9」を開き、次の要件で作成していきます。

Step 1 Name environment

Name:任意の名前を指定。

Step 2 Configure settings

基本は次の通り、全てデフォルトです。

Environment type:Create a new EC2 instance for environment (direct access)
Instance type:t2.micro (1 GiB RAM + 1 vCPU)
Platform:Amazon Linux
Network (VPC):任意の VPC を指定して、Publicサブネットを指定してください。

Step 3 Review

「Create environment」ボタンをクリック。

1-2.IAM ロールの作成とEC2への割り当て##

以下のIAMポリシーを付与したIAMロールを作成し、EC2にアタッチします。

AdministratorAccess

1-3.一時的なクレデンシャルの無効化##

Cloud9では、IAMユーザーの一時的なクレデンシャルを自動的に設定する機能がありますが、
この一時的なクレデンシャルは IAMなどの一部のアクションに制限があるため、
この一時的なクレデンシャルは無効化して EC2インスタンスに割り当てたIAMロールが使用されるようにします。

右上の歯車の形のアイコンを開き、「AWS Settings」メニューを開き、「AWS managed temporary credentials」を無効化します。
スクリーンショット 2020-10-26 21.46.57.png

1-4.AWS CLI の初期設定##

leomaro7:~/environment $ rm -vf ${HOME}/.aws/credentials
leomaro7:~/environment $ aws --version
aws-cli/1.18.162 Python/3.6.12 Linux/4.14.193-113.317.amzn1.x86_64 botocore/1.19.2
leomaro7:~/environment $ AWS_REGION="us-east-1"
leomaro7:~/environment $ aws configure set default.region ${AWS_REGION}
leomaro7:~/environment $ aws configure get default.region
us-east-1
leomaro7:~/environment $ aws sts get-caller-identity
{
    "UserId": "",
    "Account": "",
    "Arn": ""
}

2.クラスターの作成#

2-1.eksctlのインストール##

eksctl:Kubernetes クラスター自体の作成に使用するコマンド

leomaro7:~/environment $ curl -L "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
leomaro7:~/environment $ sudo mv /tmp/eksctl /usr/local/bin
leomaro7:~/environment $ eksctl version
0.30.0

eksctl - The official CLI for Amazon EKS

2-2.kubectlのインストール##

kubectl:作成した Kubernetes クラスターの操作に使用するコマンド

leomaro7:~/environment $ 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
leomaro7:~/environment $ sudo chmod +x /usr/local/bin/kubectl
leomaro7:~/environment $ kubectl version --short --client
Client Version: v1.17.7-eks-bffbac

2-3.クラスターの作成##

AWS_REGION=$(aws configure get default.region)
eksctl create cluster \
  --name=ekshandson \
  --version 1.17 \
  --nodes=3 --managed \
  --region ${AWS_REGION} --zones ${AWS_REGION}a,${AWS_REGION}c
  • 設定オプションを引数で渡す方法以外にも、設定を YAML に記述し、引数でその YAML 指定することも可能。
  • 既存の VPC を指定してクラスターを作成することも可能。今回は 新規に VPC が作成される。
  • eksctl は CloudFormation を使って コントロールプレーンのVPC や EKS クラスター、ワーカーノードの Auto Scaling Group などの AWS リソースが作成される。(実際にCloudFormationを開き、作成されたリソースを確認してみるのがよいと思われる。)

※クラスターに失敗する場合のトラブルシュート

  • Availability Zone のリソース不足
  • AWS CLI のバージョンが古い
  • IAMロールが割り当てられていない

2-4.便利なツールの導入と、コマンド補完の設定##

jq と bash-completion###

jq:json データを処理する便利なコマンド
bash-completion:bash シェル上でコマンドの補完をしてくれる

sudo yum -y install jq bash-completion

docker、docker-compose と コマンド補完###

sudo curl -L -o /etc/bash_completion.d/docker https://raw.githubusercontent.com/docker/cli/master/contrib/completion/bash/docker
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 のコマンド補完###

kubectl completion bash > kubectl_completion
sudo mv kubectl_completion /etc/bash_completion.d/kubectl

eksctl のコマンド補完###

eksctl completion bash > eksctl_completion
sudo mv eksctl_completion /etc/bash_completion.d/eksctl

k(エイリアス)###

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

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

kube-ps1###

kube-ps1:現在の kubectl のコンテキストや Namespace をプロンプトに表示してくれる。

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###

kubectx と kubens:kubectx と kubens kubectl のコンテキストや Namespace の切替を容易にしてくれる

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###

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

~/.bash_profile に追記した設定を有効化するために、現在のターミナルのタブを閉じて新しいターミナルのタブを開く。

3.クラスターの確認#

3-1.クラスターの確認##

現在存在するクラスターとクラスターの基本情報を表示。

leomaro7:~/environment $ eksctl get cluster
NAME            REGION
ekshandson      us-east-1

leomaro7:~/environment $ kubectl cluster-info
Kubernetes master is running at https://25FF2316ECD9ED0E8D621ED7DCFD6263.gr7.us-east-1.eks.amazonaws.com
CoreDNS is running at https://25FF2316ECD9ED0E8D621ED7DCFD6263.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'.

3-2.ノードの確認##

クラスターに所属しているノードとノードのキャパシティや稼働しているPodを確認。

leomaro7:~/environment $ kubectl get node
NAME                            STATUS   ROLES    AGE   VERSION
ip-192-168-4-184.ec2.internal   Ready    <none>   13m   v1.17.11-eks-cfdc40
ip-192-168-56-48.ec2.internal   Ready    <none>   13m   v1.17.11-eks-cfdc40
ip-192-168-6-63.ec2.internal    Ready    <none>   13m   v1.17.11-eks-cfdc40

leomaro7:~/environment $ kubectl describe node ip-192-168-4-184.ec2.internal

3-3.NAMESPACEの確認##

Namespace:Pod や Service といった Kubernetes リソースをグルーピングするもの。

Namespace を確認

leomaro7:~/environment $ kubectl get namespace
NAME              STATUS   AGE
default           Active   24m
kube-node-lease   Active   24m
kube-public       Active   24m
kube-system       Active   24m

Pod:Kubernetes におけるデプロイの最小単位で、Pod の中では 1 つ以上のコンテナが稼働する。

↓はnamespace:defaultの中身をのPod(勿論まだない。)

leomaro7:~/environment $ kubectl get pod -n default
No resources found in default namespace.

kubensを利用して、デフォルトのNamespaceをkube-system に変更。

leomaro7:~/environment $ kubens kube-system
Context "i-0fa58438b91ce5f53@ekshandson.us-east-1.eksctl.io" modified.
Active namespace is "kube-system".

kube-systemでは、↓のようなPodが動作している。

leomaro7:~/environment $ kubectl get pod -n kube-system
NAME                       READY   STATUS    RESTARTS   AGE
aws-node-2p7s2             1/1     Running   0          26m
aws-node-cmmkc             1/1     Running   0          26m
aws-node-vbp6f             1/1     Running   0          26m
coredns-75b44cb5b4-cktx9   1/1     Running   0          31m
coredns-75b44cb5b4-lq58q   1/1     Running   0          31m
kube-proxy-c6td9           1/1     Running   0          26m
kube-proxy-jxwc6           1/1     Running   0          26m

全ての Namespace を対象として情報を取得する場青は -Aオプション を使う。

leomaro7:~/environment $ kubectl get pod -A
NAMESPACE     NAME                       READY   STATUS    RESTARTS   AGE
kube-system   aws-node-2p7s2             1/1     Running   0          27m
kube-system   aws-node-cmmkc             1/1     Running   0          27m
kube-system   aws-node-vbp6f             1/1     Running   0          27m
kube-system   coredns-75b44cb5b4-cktx9   1/1     Running   0          32m
kube-system   coredns-75b44cb5b4-lq58q   1/1     Running   0          32m
kube-system   kube-proxy-c6td9           1/1     Running   0          27m
kube-system   kube-proxy-jxwc6           1/1     Running   0          27m
kube-system   kube-proxy-z454c           1/1     Running   0          27m

4.サンプルアプリケーションのデプロイ#

4-1.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}'

4-2.Dockerイメージの作成##

ディレクトリを移動している場合は、~/environment/ ディレクトリに戻っておく。

cd ~/environment/

サンプルアプリケーションをDLし、解凍。

wget https://eks-for-aws-summit-online.workshop.aws/sample-app.zip
unzip sample-app.zip

docker-compose で ビルド。

cd sample-app
docker-compose build

ビルドされたことを確認する。

docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
backend             latest              412ec271d5e7        11 seconds ago      107MB
frontend            latest              fa4eba7cd29c        20 seconds ago      57.7MB
python              3-alpine            dc68588b1801        6 days ago          44.3MB

4-3.ECR へのイメージの登録##

ECRリポジトリを作成。

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

リポジトリの URL を取得して変数に格納しておく。

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)

先ほどビルドしたイメージに、ECR のリポジトリの URL 名で別名をつけます。

docker tag frontend:latest ${frontend_repo}:latest
docker tag backend:latest ${backend_repo}:latest

別名をつけたイメージを確認。

docker images
REPOSITORY                                              TAG                 IMAGE ID            CREATED             SIZE
4.dkr.ecr.us-east-1.amazonaws.com/backend    latest              412ec271d5e7        2 minutes ago       107MB
4.dkr.ecr.us-east-1.amazonaws.com/frontend   latest              fa4eba7cd29c        2 minutes ago       57.7MB

ECR にログイン。

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

イメージを ECR に push。

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

4.アプリのデプロイ##

作業用ディレクトリの作成。

mkdir -p ~/environment/manifests/
cd ~/environment/manifests/

アプリケーション1用の Namespace を作成。デフォルトの Namespace も変更。

kubectl create namespace frontend
kubens frontend

Deployment の作成

frontend_repo=$(aws ecr describe-repositories --repository-names frontend --query 'repositories[0].repositoryUri' --output text)
cat <<EOF > 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: ${frontend_repo}:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 5000
        env:
        - name: BACKEND_URL
          value: http://backend.backend:5000/messages
EOF
kubectl apply -f frontend-deployment.yaml -n frontend

作成されたデプロイメントを確認。

※Deployment リソースを作成したことで、Deployment リソースの定義内容にしたがって、自動的に Pod が作成される。
(正確には、Deployment リソースによって ReplicaSet リソースが作成され、ReplicaSet リソースによって Pod が作成される。)

kubectl get deployment -n frontend
NAME       READY   UP-TO-DATE   AVAILABLE   AGE
frontend   2/2     2            2           13s

Podを確認。

kubectl get pod -n frontend
NAME                        READY   STATUS    RESTARTS   AGE
frontend-84ccd456fb-l6kjl   1/1     Running   0          53s
frontend-84ccd456fb-wdhwr   1/1     Running   0          53s

Service の作成。

Service:Deployment によって起動された Pod 群にアクセスするために、名前解決と負荷分散の機能を提供する。

cat <<EOF > frontend-service-lb.yaml
apiVersion: v1
kind: Service
metadata:
  name: frontend
spec:
  type: LoadBalancer
  selector:
    app: frontend
  ports:
  - protocol: TCP
    port: 80
    targetPort: 5000
EOF
kubectl apply -f frontend-service-lb.yaml -n frontend

作成した Service を確認。

kubectl get service -n frontend
NAME       TYPE           CLUSTER-IP       EXTERNAL-IP                                                               PORT(S)        AGE
frontend   LoadBalancer   10.100.219.241   dd7c90ab25e44a939b065e566aa5432-1872056256.us-east-1.elb.amazonaws.com   80:30374/TCP   10s

EXTERNAL-IP にアクセスして表示されるか確認する。(名前解決ができるまで数分かかる)

アプリケーション2用の Namespace を作成。デフォルトの Namespace も変更。

kubectl create namespace backend
kubens backend

Deployment の作成。

AWS_REGION=$(aws configure get default.region)
backend_repo=$(aws ecr describe-repositories --repository-names backend --query 'repositories[0].repositoryUri' --output text)
cat <<EOF > 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: ${backend_repo}:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 5000
        env:
        - name: AWS_DEFAULT_REGION
          value: ${AWS_REGION}
        - name: DYNAMODB_TABLE_NAME
          value: messages
EOF
kubectl apply -f backend-deployment.yaml -n backend

Podを確認。

kubectl get pod -n backend
NAME                       READY   STATUS    RESTARTS   AGE
backend-7544ddcd98-7lxcx   1/1     Running   0          12s
backend-7544ddcd98-bn5jq   1/1     Running   0          12s

Service の作成。

cat <<EOF > backend-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: backend
spec:
  type: ClusterIP
  selector:
    app: backend
  ports:
  - protocol: TCP
    port: 5000
    targetPort: 5000
EOF
kubectl apply -f backend-service.yaml -n backend

作成した Service を確認。

kubectl get service -n backend
NAME      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
backend   ClusterIP   10.100.60.141   <none>        5000/TCP   13s

EXTERNAL-IP にもう一度アクセスしてみる。

5.IAM ROLES FOR SERVICE ACCOUNTS#

IAM Roles for Service Accounts と呼ばれる EKS の機能を使用して アプリケーション2の Pod に IAM ロールを付与し、DynamoDB へのアクセスを許可させる。

OIDC ID プロバイダーを作成し、クラスターに関連付けます。

eksctl utils associate-iam-oidc-provider \
    --cluster ekshandson \
    --approve

DynamoDB の messages テーブルへのフルアクセスを許可する IAM ポリシーを作成。

cat <<EOF > dynamodb-messages-fullaccess-policy.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ListAndDescribe",
            "Effect": "Allow",
            "Action": [
                "dynamodb:List*",
                "dynamodb:DescribeReservedCapacity*",
                "dynamodb:DescribeLimits",
                "dynamodb:DescribeTimeToLive"
            ],
            "Resource": "*"
        },
        {
            "Sid": "SpecificTable",
            "Effect": "Allow",
            "Action": [
                "dynamodb:BatchGet*",
                "dynamodb:DescribeStream",
                "dynamodb:DescribeTable",
                "dynamodb:Get*",
                "dynamodb:Query",
                "dynamodb:Scan",
                "dynamodb:BatchWrite*",
                "dynamodb:CreateTable",
                "dynamodb:Delete*",
                "dynamodb:Update*",
                "dynamodb:PutItem"
            ],
            "Resource": "arn:aws:dynamodb:*:*:table/messages"
        }
    ]
}
EOF
aws iam create-policy \
    --policy-name dynamodb-messages-fullaccess \
    --policy-document file://dynamodb-messages-fullaccess-policy.json

アプリケーション2の実行に使用するための ServiceAccount と IAM ロールを作成し、関連付ける。

ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
eksctl create iamserviceaccount \
    --name dynamodb-messages-fullaccess \
    --namespace backend \
    --cluster ekshandson \
    --attach-policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/dynamodb-messages-fullaccess \
    --override-existing-serviceaccounts \
    --approve

作成された ServiceAccount を確認。

kubectl get serviceaccount -n backend
default                        1         24m
dynamodb-messages-fullaccess   1         35s

アプリケーション2の Deployment の定義を修正し、作成した ServiceAccount で Pod を実行させる。

Cloud9 で backend-deployment.yaml をダブルクリックで開き、serviceAccountName の指定を次のとおり追加して保存。

    spec:
+     serviceAccountName: dynamodb-messages-fullaccess
      containers:
kubectl apply -f backend-deployment.yaml -n backend

自動的に新しい Pod が起動されるので、確認。

kubectl get pod -n backend
NAME                       READY   STATUS    RESTARTS   AGE
backend-647595dd78-jjmml   1/1     Running   0          70s
backend-647595dd78-w7f6t   1/1     Running   0          72s

EXTERNAL-IP にもう一度アクセスしてみると正しく表示される、はず。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?