https://catalog.us-east-1.prod.workshops.aws/workshops/f5abb693-2d87-43b5-a439-77454f28e2e7/ja-JP/040-deploy-sample-app/60-irsa

まとめ

  • Service はアプリを公開(インターネットやクラスターの他アプリ向け)するために使用する
  • Deployment は B/G デプロイなどの作業用に Pod をひとまとめにしたもの。Podのラッパーぽい認識。普通は直接 Pod をデプロイせず、 Deployment を Apply することで Pod を作成

作業ログ

  • Cloud9 環境作成
  • C9のデフォルトロールではなく、IAM Role 権限を割り当て

ツール導入

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

sudo curl -L -o /usr/local/bin/kubectl https://amazon-eks.s3.us-west-2.amazonaws.com/1.21.2/2021-07-05/bin/linux/amd64/kubectl
sudo chmod +x /usr/local/bin/kubectl

クラスター作成

AWS_REGION=$(aws configure get default.region)
eksctl create cluster \
  --name=ekshandson \
  --version 1.24 \
  --nodes=3 --managed \
  --region ${AWS_REGION} --zones ${AWS_REGION}a,${AWS_REGION}c

ツール導入

sudo yum -y install jq bash-completion

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

kubecnx

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

作成されたリソースの確認

クラスターの確認

eksctl get cluster
NAME                            REGION          EKSCTL CREATED
attractive-sculpture-1672376633 ap-northeast-1  True
ekshandson                      ap-northeast-1  True
test                            ap-northeast-1  False

ノードの確認

kubectl get node

ワーカーノードのみ確認可能

kubectl get nodes --all-namespaces
NAME                                                STATUS   ROLES    AGE     VERSION
ip-192-168-33-151.ap-northeast-1.compute.internal   Ready    <none>   3h19m   v1.23.13-eks-fb459a0
ip-192-168-91-191.ap-northeast-1.compute.internal   Ready    <none>   3h19m   v1.23.13-eks-fb459a0

マスターノードも確認可能

kubectl describe node ip-192-168-33-151.ap-northeast-1.compute.internal

詳細情報が確認可能

  • ラベル
  • CPUなどのリソース情報
  • 稼働 Pod
  • ネットワークアドレス情報

名前空間の確認

kubectl get namespace

NAME              STATUS   AGE
default           Active   3h30m
ingress-nginx     Active   178m
kube-node-lease   Active   3h30m
kube-public       Active   3h30m
kube-system       Active   3h30m

全名前空間を横断検索

kubectl get pod -A

NAMESPACE       NAME                                        READY   STATUS      RESTARTS   AGE
default         frontend-f7d9c57d4-8rt4b                    1/1     Running     0          3h1m
default         frontend-f7d9c57d4-h8tqx                    1/1     Running     0          3h1m
default         frontend-f7d9c57d4-lpv56                    1/1     Running     0          3h1m
default         redis-master-857d99cc8-gqrjk                1/1     Running     0          3h1m
default         redis-replica-566d4f87dc-2tbs9              1/1     Running     0          3h1m
default         redis-replica-566d4f87dc-nszz5              1/1     Running     0          3h1m
ingress-nginx   ingress-nginx-admission-create-7hn2w        0/1     Completed   0          3h
ingress-nginx   ingress-nginx-admission-patch-l4fhh         0/1     Completed   0          3h
ingress-nginx   ingress-nginx-controller-6f7bd4bcfb-hx689   1/1     Running     0          3h
kube-system     aws-node-jmv97                              1/1     Running     0          3h17m
kube-system     aws-node-wskqj                              1/1     Running     0          3h17m
kube-system     coredns-69cfddc4b4-bfhsq                    1/1     Running     0          3h32m
kube-system     coredns-69cfddc4b4-q26z8                    1/1     Running     0          3h32m
kube-system     kube-proxy-hg2f5                            1/1     Running     0          3h25m
kube-system     kube-proxy-z5nx8                            1/1     Running     0          3h25m

-0 wideで詳細情報を取得できる。 describe との違いは?→ describe はイベント情報も取得できる。

kubectl get pod -n kube-system -o wide

sampel app deploy

https://catalog.us-east-1.prod.workshops.aws/workshops/f5abb693-2d87-43b5-a439-77454f28e2e7/ja-JP/040-deploy-sample-app

DDB作成

Docker Image Build

cd ~/environment/
wget https://static.us-east-1.prod.workshops.aws/public/51075a38-e4dc-4703-93f1-5d4bda1e2508/static/sample-app.zip
unzip sample-app.zip
ls -la
total 4
drwxr-xr-x 4 ec2-user ec2-user  63 Mar 24  2020 .
drwxr-xr-x 4 ec2-user ec2-user  74 Dec 30 09:03 ..
drwxr-xr-x 2 ec2-user ec2-user  79 Mar 24  2020 backend
-rw-r--r-- 1 ec2-user ec2-user 370 Mar 24  2020 docker-compose.yml
drwxr-xr-x 3 ec2-user ec2-user  96 Mar 19  2020 frontend

docker-compose でビルドするっぽい。2コンテナを同時ビルドするからっぽい?

  • frontend
    • Dockerfile みるに、python3-alpine に自前のスクリプトを入れ込んで実行するだけのプログラムぽい
      • app.py は flask によるアプリケーションサーバー
  • backend
    • Dockerfile みるに、python3-alpine に自前のスクリプトを入れ込んで実行するだけのプログラムぽい
      • app.py は flask によるアプリケーションサーバー

Client —> (8080:5000) frontend —>(tcp:5000) backend —>DDB

以下で同時に 2 image がビルドされたことがわかる

docker images

EKS が pull するための、 ECR を作成

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


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 へログイン
AWS_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://${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com

アプリのデプロイを行う (重要)

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

名前空間の作成

kubectl create namespace frontend
kubens frontend

Deploymentの作成 (AS や B/G デプロイで使えるデプロイ時の単位)

kubectl apply -f frontend-deployment.yaml -n frontend
  • このように、Kubernetes 上でのアプリケーションのデプロイ作業は、マニフェストの作成と、作成したマニフェストの apply という操作が基本になります。
  • Deployment を使用すると、自動で Pod が生成される

サービスにより、外部(インターネット、クラスターの他 APp)へのアクセスを提供

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

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
  • spec.type で LoadBalancer を指定しています
  • spec.selector の部分で指定されたラベル (app=frontend) を持つ Pod がこの Service からの割り振り対象となります

作成したものを確認

kubectl get service -n frontend
NAME       TYPE           CLUSTER-IP       EXTERNAL-IP                                                                    PORT(S)        AGE
frontend   LoadBalancer   10.100.119.160   hogehogehoge-1292028135.ap-northeast-1.elb.amazonaws.com   80:32751/TCP   102s

![[Pasted image 20221230183249.png]]

Dive Deep

kubectl get pod -n frontend
NAME                        READY   STATUS    RESTARTS   AGE
frontend-58bd47c4d6-blr2j   1/1     Running   0          12m
frontend-58bd47c4d6-svs5l   1/1     Running   0          12m

どっちかの Pod にアクセスする

ログを見る場合は logs (describe ではない)

k logs -n frontend frontend-58bd47c4d6-svs5l     
 * Serving Flask app 'app'
 * Debug mode: on

requests.exceptions.ConnectionError: HTTPConnectionPool(host='backend.backend', port=5000): Max retries exceeded with url: /messages (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7fe0878a8a60>: Failed to establish a new connection: [Errno -2] Name does not resolve'))

こんな感じで名前解決失敗しているログがある

wget https://github.com/stern/stern/releases/download/v1.22.0/stern_1.22.0_linux_amd64.tar.gz

tar xvf stern_1.22.0_linux_amd64.tar.gz
sudo mv stern /usr/local/bin/stern
sudo chmod +x /usr/local/bin/stern


stern frontend -n frontend

なんと k8s 1.24 で以下が削除されたので、そのままだと stern 使えない

client.authentication.k8s.io/v1alpha1

backend 作成

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

Pod に IAM 権限を付与する

oidc provider 作成

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

IAM Policy と IAM Role を作成

Service Account を作成

AWS_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::${AWS_ACCOUNT_ID}:policy/dynamodb-messages-fullaccess \
    --override-existing-serviceaccounts \
    --approve

backend-deployment.yaml を編集 以下を追加する

serviceAccountName: dynamodb-messages-fullaccess

無事完了