はじめに
- 本記事では、Kubernetes(K8s)においてポッド数の管理をするデプロイメントの具体的動作を確認していきます。
- デプロイメントを利用した高可用性構成(HA 構成)を Amazon EKS 上で試行出来るようになることを目標とします。
前提条件
Deployment の基本事項
Deployment
はポッドの稼働数を管理します。- 要求を満たすポッド数を起動し、障害などでポッド稼働数が減ってしまった場合も、追加起動する制御を行います。
- アプリケーションのバージョンアップ時には、新バージョンのポッドへ徐々に置き換えていく制御も行います。
Deployment
は単独では動作せず、ReplicaSet
と連動してポッド数の制御を行います。ReplicaSet
はDeployment
のマニフェストのreplicas
の値を受け取り、ポッド数を制御します。- ユーザーが直接
ReplicaSet
を操作することはほとんどありません。
Deployment の基本的な動きを Amazon EKS で確認する
$ eksctl create cluster \ --name [クラスター名] \ --region [リージョン名] \ --fargate
Deployment
の生成
Deployment
を生成するためのマニフェストファイルは以下のような内容で作成します:
deployment.yml
apiVersion: apps/v1 kind: Deployment metadata: name: "sample-deployment" # Deployment 名を指定 spec: selector: matchLabels: app: "sample-app" # Deployment と Pod を結びつけるラベル replicas: 3 # Pod の稼働数を指定 template: # 以下、Pod のテンプレートを記述 metadata: labels: app: "sample-app" # Deployment と Pod を結びつけるラベル spec: containers: - name: nginx-container image: nginx:1.16 ports: - containerPort: 80
Deployment
を生成するには、kubectl apply -f [マニフェストファイル名]
を実行します。- デプロイの一覧を表示するには、
kubectl get deploy
を実行します。 ReplicaSet
の一覧を確認するには、kubectl get rs
を実行します。Deployment
に紐付いたReplicaSet
が生成されていることがわかります。
Pod
の一覧を確認するには、kubectl get po -o wide
を実行します。-o wide
を付けることで、より詳細な情報を確認できます。Deployment
に紐付いたPod
が生成されていることがわかります。
deployment.yml
の適用とその後の確認
$ kubectl apply -f deployment.yml deployment.apps/sample-deployment created $ kubectl get deploy NAME READY UP-TO-DATE AVAILABLE AGE sample-deployment 3/3 3 3 13s $ kubectl get rs NAME DESIRED CURRENT READY AGE sample-deployment-5f4f4775f7 3 3 3 32s $ kubectl get po -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES sample-deployment-7b8bb4454b-28q9x 1/1 Running 0 15m 192.168.169.117 fargate-ip-192-168-169-117.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-hv7dx 1/1 Running 0 14m 192.168.136.239 fargate-ip-192-168-136-239.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-ng7m5 1/1 Running 0 13m 192.168.147.85 fargate-ip-192-168-147-85.us-east-2.compute.internal <none> <none>
- Fargate の場合、1
Pod
あたり 1 ノードが与えられるため、それぞれのPod
が別々のノードに配置されています。
スケール機能を試す
- 「スケール機能」は
replicas
の値を変更し、Pod
数を増減することで処理能力を調整する機能です。- CPU 使用率と連動して、動的に
replicas
の値を調整する機能は「オートスケール」と呼ばれます(ここでは扱いません)。
- CPU 使用率と連動して、動的に
- Amazon EKS においては、ワーカーノードの種類によって
Pod
を増やした際の挙動が変わります。 - 先ほどの
Deployment
のレプリカ数を 3 から 10 に増やして適用します。
変更後の
deployment.yml
apiVersion: apps/v1 kind: Deployment metadata: name: "sample-deployment" spec: selector: matchLabels: app: "sample-app" replicas: 10 # 3 から 10 に変更 template: metadata: labels: app: "sample-app" spec: containers: - name: nginx-container image: nginx:1.16 ports: - containerPort: 80
変更後の
Deployment
のマニフェスト適用の様子
$ kubectl apply -f deployment.yml deployment.apps/sample-deployment configured # 適用直後の様子 # -> 3 個のポッドが稼働中で、新たに 7 個のポッドが生成されていることがわかります。 $ kubectl get po -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES sample-deployment-7b8bb4454b-28q9x 1/1 Running 0 131m 192.168.169.117 fargate-ip-192-168-169-117.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-95xxc 0/1 Pending 0 9s <none> <none> e77ba0824e-a8fa0989ba344938a4830bbb7ea23e54 <none> sample-deployment-7b8bb4454b-9d9kb 0/1 Pending 0 9s <none> <none> e77ba0824e-27fb9bacb66a4adfba8933574db9890e <none> sample-deployment-7b8bb4454b-c54p5 0/1 Pending 0 9s <none> <none> 047d10071a-648eed996c094ef29a8221d286d30771 <none> sample-deployment-7b8bb4454b-hv7dx 1/1 Running 0 130m 192.168.136.239 fargate-ip-192-168-136-239.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-ng7m5 1/1 Running 0 130m 192.168.147.85 fargate-ip-192-168-147-85.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-qddmr 0/1 Pending 0 9s <none> <none> 09cd2b3a26-bae652eb3ad14375aabc9b4c8dc9af01 <none> sample-deployment-7b8bb4454b-scdvk 0/1 Pending 0 9s <none> <none> 047d10071a-e36b77e7166148b99d86358001742bfa <none> sample-deployment-7b8bb4454b-swzkt 0/1 Pending 0 9s <none> <none> 09cd2b3a26-a2230349a5d843eab3d4100f29550a85 <none> sample-deployment-7b8bb4454b-wjjb2 0/1 Pending 0 9s <none> <none> e77ba0824e-499afa9c8f7d40d087e73d5e99896d32 <none> # 適用後 30 秒ほど経ってからの様子 $ kubectl get po -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES sample-deployment-7b8bb4454b-28q9x 1/1 Running 0 132m 192.168.169.117 fargate-ip-192-168-169-117.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-95xxc 0/1 Pending 0 35s <none> <none> e77ba0824e-a8fa0989ba344938a4830bbb7ea23e54 <none> sample-deployment-7b8bb4454b-9d9kb 0/1 Pending 0 35s <none> <none> e77ba0824e-27fb9bacb66a4adfba8933574db9890e <none> sample-deployment-7b8bb4454b-c54p5 0/1 ContainerCreating 0 35s <none> fargate-ip-192-168-132-16.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-hv7dx 1/1 Running 0 131m 192.168.136.239 fargate-ip-192-168-136-239.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-ng7m5 1/1 Running 0 130m 192.168.147.85 fargate-ip-192-168-147-85.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-qddmr 0/1 Pending 0 35s <none> <none> 09cd2b3a26-bae652eb3ad14375aabc9b4c8dc9af01 <none> sample-deployment-7b8bb4454b-scdvk 0/1 Pending 0 35s <none> <none> 047d10071a-e36b77e7166148b99d86358001742bfa <none> sample-deployment-7b8bb4454b-swzkt 0/1 Pending 0 35s <none> <none> 09cd2b3a26-a2230349a5d843eab3d4100f29550a85 <none> sample-deployment-7b8bb4454b-wjjb2 0/1 Pending 0 35s <none> <none> e77ba0824e-499afa9c8f7d40d087e73d5e99896d32 <none> # 適用後、約 60 秒後の様子 $ kubectl get po -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES sample-deployment-7b8bb4454b-28q9x 1/1 Running 0 132m 192.168.169.117 fargate-ip-192-168-169-117.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-95xxc 0/1 ContainerCreating 0 58s <none> fargate-ip-192-168-117-130.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-9d9kb 1/1 Running 0 58s 192.168.126.212 fargate-ip-192-168-126-212.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-c54p5 1/1 Running 0 58s 192.168.132.16 fargate-ip-192-168-132-16.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-hv7dx 1/1 Running 0 131m 192.168.136.239 fargate-ip-192-168-136-239.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-ng7m5 1/1 Running 0 130m 192.168.147.85 fargate-ip-192-168-147-85.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-qddmr 0/1 ContainerCreating 0 58s <none> fargate-ip-192-168-173-77.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-scdvk 1/1 Running 0 58s 192.168.139.82 fargate-ip-192-168-139-82.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-swzkt 1/1 Running 0 58s 192.168.180.58 fargate-ip-192-168-180-58.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-wjjb2 1/1 Running 0 58s 192.168.111.204 fargate-ip-192-168-111-204.us-east-2.compute.internal <none> <none> # 適用完了 $ kubectl get po -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES sample-deployment-7b8bb4454b-28q9x 1/1 Running 0 132m 192.168.169.117 fargate-ip-192-168-169-117.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-95xxc 1/1 Running 0 68s 192.168.117.130 fargate-ip-192-168-117-130.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-9d9kb 1/1 Running 0 68s 192.168.126.212 fargate-ip-192-168-126-212.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-c54p5 1/1 Running 0 68s 192.168.132.16 fargate-ip-192-168-132-16.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-hv7dx 1/1 Running 0 131m 192.168.136.239 fargate-ip-192-168-136-239.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-ng7m5 1/1 Running 0 131m 192.168.147.85 fargate-ip-192-168-147-85.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-qddmr 1/1 Running 0 68s 192.168.173.77 fargate-ip-192-168-173-77.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-scdvk 1/1 Running 0 68s 192.168.139.82 fargate-ip-192-168-139-82.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-swzkt 1/1 Running 0 68s 192.168.180.58 fargate-ip-192-168-180-58.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-wjjb2 1/1 Running 0 68s 192.168.111.204 fargate-ip-192-168-111-204.us-east-2.compute.internal <none> <none>
ロールアウト機能を試す
- K8s におけるロールアウトとは、アプリケーションコンテナの更新を意味します。
- ロールアウト進行中は、リクエストの処理負荷に対処できる
Pod
数を残して停止できるPod
数(停止許容数)だけ古いPod
を停止します。 - 停止した
Pod
の数に超過許容数を加えた数だけ、かつ、新しいPod
数は replicas の値を上限としてPod
を起動します。 - 超過許容数は
Deployment
のRollingUpdateStrategy
から計算可能です。 - 以下、先ほどの
Deployment
の例で見てみます。Deployment
の詳細はkubectl describe deploy [Deployment 名]
で確認できます。- 下記の例では、
RollingUpdateStrategy
が25% max unavailable, 25% max surge
なので、「最大25%のPod
の停止を許容し、最大25%のポッドの稼働超過数を許容する」という意味です。 - replicas が 10 なので、最小
Pod
数は10 * (1 - 0.25) = 7.5
の小数点以下を切り上げた 8 となります。また、最大超過数は10 * ( 1 + 0.25) = 12.5
の小数点以下を切り上げた 13 となります。
Deployment
の詳細確認結果
$ kubectl describe deploy sample-deployment Name: sample-deployment Namespace: default CreationTimestamp: Tue, 05 May 2020 14:24:18 +0900 Labels: <none> Annotations: deployment.kubernetes.io/revision: 2 Selector: app=sample-app Replicas: 10 desired | 10 updated | 10 total | 10 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge # 停止数と稼働超過数の割合 Pod Template: Labels: app=sample-app Containers: nginx-container: Image: nginx:1.16 Port: 80/TCP Host Port: 0/TCP Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ Progressing True NewReplicaSetAvailable Available True MinimumReplicasAvailable OldReplicaSets: <none> NewReplicaSet: sample-deployment-7b8bb4454b (10/10 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 17m deployment-controller Scaled up replica set sample-deployment-7b8bb4454b to 10
- 実際にコンテナアプリケーションの更新を行い、ロールアウトの様子を確認します。
Deployment
のマニフェストを更新し、containers.image
をnginx:1.16
->nginx:1.17
に変更し、マニフェストを適用します。
変更後の
deployment.yml
(その2)
apiVersion: apps/v1 kind: Deployment metadata: name: "sample-deployment" spec: selector: matchLabels: app: "sample-app" replicas: 10 template: metadata: labels: app: "sample-app" spec: containers: - name: nginx-container image: nginx:1.17 # バージョンを 1.16 から 1.17 に変更 ports: - containerPort: 80
変更したマニフェストの適用とロールアウト中の様子
$ kubectl apply -f deployment.yml deployment.apps/sample-deployment configured # (1) 適用後 20 秒ほど経った後 # -> 更新前のノード(Runnning) は 8 個:最小 Pod 数、更新中のノードは 5 個(Pending) # Runnning と Pending は合わせて 13個:最大超過数 $ kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES sample-deployment-7875dd85cc-5xt2h 0/1 Pending 0 24s <none> <none> e77ba0824e-dd4ad95019c04aafb18024de70a39499 <none> sample-deployment-7875dd85cc-6fxgd 0/1 Pending 0 24s <none> <none> 047d10071a-0b5c93d23a6642e58d1abdbd7130801f <none> sample-deployment-7875dd85cc-7jzjf 0/1 Pending 0 24s <none> <none> 047d10071a-a428a39b62f54d7391c55adedc6a9f52 <none> sample-deployment-7875dd85cc-g9ztc 0/1 Pending 0 24s <none> <none> e77ba0824e-816c4260aecc4852943ca7c79e15f4ef <none> sample-deployment-7875dd85cc-p78fl 0/1 Pending 0 24s <none> <none> e77ba0824e-937779b60c7e4e0c9322cbbe1a4a85cf <none> sample-deployment-7b8bb4454b-28q9x 1/1 Running 0 173m 192.168.169.117 fargate-ip-192-168-169-117.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-9d9kb 1/1 Running 0 42m 192.168.126.212 fargate-ip-192-168-126-212.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-c54p5 1/1 Running 0 42m 192.168.132.16 fargate-ip-192-168-132-16.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-hv7dx 1/1 Running 0 172m 192.168.136.239 fargate-ip-192-168-136-239.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-ng7m5 1/1 Running 0 172m 192.168.147.85 fargate-ip-192-168-147-85.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-scdvk 1/1 Running 0 42m 192.168.139.82 fargate-ip-192-168-139-82.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-swzkt 1/1 Running 0 42m 192.168.180.58 fargate-ip-192-168-180-58.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-wjjb2 1/1 Running 0 42m 192.168.111.204 fargate-ip-192-168-111-204.us-east-2.compute.internal <none> <none> # (2) 適用後 約 50 秒経過 # -> 古いコンテナが Terminating になり、新しいコンテナが Runnning 状態になる。 # Runnning は依然として8個 $ kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES sample-deployment-7875dd85cc-5xt2h 0/1 ContainerCreating 0 52s <none> fargate-ip-192-168-109-32.us-east-2.compute.internal <none> <none> sample-deployment-7875dd85cc-6fxgd 1/1 Running 0 52s 192.168.134.6 fargate-ip-192-168-134-6.us-east-2.compute.internal <none> <none> sample-deployment-7875dd85cc-7jzjf 1/1 Running 0 52s 192.168.134.119 fargate-ip-192-168-134-119.us-east-2.compute.internal <none> <none> sample-deployment-7875dd85cc-8m4g2 0/1 Pending 0 19s <none> <none> 09cd2b3a26-5eabed2f62b94a20bf35e3093cddaea1 <none> sample-deployment-7875dd85cc-9vzlc 0/1 Pending 0 10s <none> <none> 047d10071a-e04c139321dd4e7ba8fd491d97ade6f3 <none> sample-deployment-7875dd85cc-g9ztc 1/1 Running 0 52s 192.168.101.63 fargate-ip-192-168-101-63.us-east-2.compute.internal <none> <none> sample-deployment-7875dd85cc-p78fl 0/1 ContainerCreating 0 52s <none> fargate-ip-192-168-124-111.us-east-2.compute.internal <none> <none> sample-deployment-7875dd85cc-vq86b 0/1 Pending 0 1s <none> <none> 09cd2b3a26-511ca593cbf048b7a66b5672290be8bd <none> sample-deployment-7b8bb4454b-28q9x 1/1 Running 0 174m 192.168.169.117 fargate-ip-192-168-169-117.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-c54p5 1/1 Running 0 42m 192.168.132.16 fargate-ip-192-168-132-16.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-hv7dx 1/1 Running 0 173m 192.168.136.239 fargate-ip-192-168-136-239.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-ng7m5 1/1 Running 0 172m 192.168.147.85 fargate-ip-192-168-147-85.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-scdvk 1/1 Terminating 0 42m 192.168.139.82 fargate-ip-192-168-139-82.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-swzkt 1/1 Running 0 42m 192.168.180.58 fargate-ip-192-168-180-58.us-east-2.compute.internal <none> <none> # (3) 適用後 約 75 秒経過 $ kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES sample-deployment-7875dd85cc-5xt2h 1/1 Running 0 74s 192.168.109.32 fargate-ip-192-168-109-32.us-east-2.compute.internal <none> <none> sample-deployment-7875dd85cc-6fxgd 1/1 Running 0 74s 192.168.134.6 fargate-ip-192-168-134-6.us-east-2.compute.internal <none> <none> sample-deployment-7875dd85cc-7jzjf 1/1 Running 0 74s 192.168.134.119 fargate-ip-192-168-134-119.us-east-2.compute.internal <none> <none> sample-deployment-7875dd85cc-8m4g2 0/1 ContainerCreating 0 41s <none> fargate-ip-192-168-175-37.us-east-2.compute.internal <none> <none> sample-deployment-7875dd85cc-9vzlc 0/1 ContainerCreating 0 32s <none> fargate-ip-192-168-149-147.us-east-2.compute.internal <none> <none> sample-deployment-7875dd85cc-fcxh4 0/1 Pending 0 20s <none> <none> e77ba0824e-6d6ab522f4314e26acda5bb1e7693d98 <none> sample-deployment-7875dd85cc-g9ztc 1/1 Running 0 74s 192.168.101.63 fargate-ip-192-168-101-63.us-east-2.compute.internal <none> <none> sample-deployment-7875dd85cc-mxvrs 0/1 Pending 0 20s <none> <none> e77ba0824e-6932284805e1460bb2204c4f9030eaa4 <none> sample-deployment-7875dd85cc-p78fl 1/1 Running 0 74s 192.168.124.111 fargate-ip-192-168-124-111.us-east-2.compute.internal <none> <none> sample-deployment-7875dd85cc-vq86b 0/1 Pending 0 23s <none> <none> 09cd2b3a26-511ca593cbf048b7a66b5672290be8bd <none> sample-deployment-7b8bb4454b-28q9x 1/1 Running 0 174m 192.168.169.117 fargate-ip-192-168-169-117.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-hv7dx 1/1 Running 0 173m 192.168.136.239 fargate-ip-192-168-136-239.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-ng7m5 1/1 Running 0 173m 192.168.147.85 fargate-ip-192-168-147-85.us-east-2.compute.internal <none> <none> # (4) 適用後 約 100 秒経過 $ kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES sample-deployment-7875dd85cc-5xt2h 1/1 Running 0 97s 192.168.109.32 fargate-ip-192-168-109-32.us-east-2.compute.internal <none> <none> sample-deployment-7875dd85cc-6fxgd 1/1 Running 0 97s 192.168.134.6 fargate-ip-192-168-134-6.us-east-2.compute.internal <none> <none> sample-deployment-7875dd85cc-7jzjf 1/1 Running 0 97s 192.168.134.119 fargate-ip-192-168-134-119.us-east-2.compute.internal <none> <none> sample-deployment-7875dd85cc-8m4g2 1/1 Running 0 64s 192.168.175.37 fargate-ip-192-168-175-37.us-east-2.compute.internal <none> <none> sample-deployment-7875dd85cc-9vzlc 1/1 Running 0 55s 192.168.149.147 fargate-ip-192-168-149-147.us-east-2.compute.internal <none> <none> sample-deployment-7875dd85cc-fcxh4 0/1 ContainerCreating 0 43s <none> fargate-ip-192-168-124-138.us-east-2.compute.internal <none> <none> sample-deployment-7875dd85cc-g9ztc 1/1 Running 0 97s 192.168.101.63 fargate-ip-192-168-101-63.us-east-2.compute.internal <none> <none> sample-deployment-7875dd85cc-mxvrs 0/1 ContainerCreating 0 43s <none> fargate-ip-192-168-126-24.us-east-2.compute.internal <none> <none> sample-deployment-7875dd85cc-p78fl 1/1 Running 0 97s 192.168.124.111 fargate-ip-192-168-124-111.us-east-2.compute.internal <none> <none> sample-deployment-7875dd85cc-vq86b 0/1 ContainerCreating 0 46s <none> fargate-ip-192-168-176-14.us-east-2.compute.internal <none> <none> sample-deployment-7b8bb4454b-28q9x 1/1 Running 0 175m 192.168.169.117 fargate-ip-192-168-169-117.us-east-2.compute.internal <none> <none> # (5) 更新完了 $ kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES sample-deployment-7875dd85cc-5xt2h 1/1 Running 0 117s 192.168.109.32 fargate-ip-192-168-109-32.us-east-2.compute.internal <none> <none> sample-deployment-7875dd85cc-6fxgd 1/1 Running 0 117s 192.168.134.6 fargate-ip-192-168-134-6.us-east-2.compute.internal <none> <none> sample-deployment-7875dd85cc-7jzjf 1/1 Running 0 117s 192.168.134.119 fargate-ip-192-168-134-119.us-east-2.compute.internal <none> <none> sample-deployment-7875dd85cc-8m4g2 1/1 Running 0 84s 192.168.175.37 fargate-ip-192-168-175-37.us-east-2.compute.internal <none> <none> sample-deployment-7875dd85cc-9vzlc 1/1 Running 0 75s 192.168.149.147 fargate-ip-192-168-149-147.us-east-2.compute.internal <none> <none> sample-deployment-7875dd85cc-fcxh4 1/1 Running 0 63s 192.168.124.138 fargate-ip-192-168-124-138.us-east-2.compute.internal <none> <none> sample-deployment-7875dd85cc-g9ztc 1/1 Running 0 117s 192.168.101.63 fargate-ip-192-168-101-63.us-east-2.compute.internal <none> <none> sample-deployment-7875dd85cc-mxvrs 1/1 Running 0 63s 192.168.126.24 fargate-ip-192-168-126-24.us-east-2.compute.internal <none> <none> sample-deployment-7875dd85cc-p78fl 1/1 Running 0 117s 192.168.124.111 fargate-ip-192-168-124-111.us-east-2.compute.internal <none> <none> sample-deployment-7875dd85cc-vq86b 1/1 Running 0 66s 192.168.176.14 fargate-ip-192-168-176-14.us-east-2.compute.internal <none> <none>
ロールバック機能を試す
- ロールアウト前の古いコンテナへ戻すためにポッドを入れ替えることをロールバックと言います。
- 以下、ロールバックのためのコマンド
kubectl rollout undo deployment [Deployment 名]
を実行してから、ロールバックが完了するまでの様子を示します。- ロールアウト時と同様に、稼働している
Pod
の数はよしなに調整されながら進行しています。
- ロールアウト時と同様に、稼働している
$ kubectl rollout undo deployment sample-deployment deployment.extensions/sample-deployment rolled back $ kubectl get po # ロールバック開始直後 NAME READY STATUS RESTARTS AGE sample-deployment-5f47777b55-6c77m 0/1 Pending 0 21s sample-deployment-5f47777b55-6dh55 1/1 Running 0 69s sample-deployment-5f47777b55-6zf86 0/1 Pending 0 14s sample-deployment-5f47777b55-b6289 1/1 Running 0 69s sample-deployment-5f47777b55-c9vfx 0/1 Pending 0 26s sample-deployment-5f47777b55-dgjnw 1/1 Running 0 69s sample-deployment-5f47777b55-f9w6r 1/1 Running 0 69s sample-deployment-5f47777b55-gtrb9 0/1 Pending 0 19s sample-deployment-5f47777b55-tmqcq 1/1 Running 0 69s sample-deployment-5f47777b55-xnplh 0/1 Pending 0 8s sample-deployment-86bd954768-2dqkt 1/1 Running 0 4m40s sample-deployment-86bd954768-gphkw 1/1 Running 0 4m40s sample-deployment-86bd954768-wbcds 1/1 Running 0 4m40s # ロールバック過渡期 NAME READY STATUS RESTARTS AGE sample-deployment-5f47777b55-6dh55 1/1 Running 0 23m sample-deployment-5f47777b55-6zf86 0/1 Terminating 0 22m sample-deployment-5f47777b55-b6289 1/1 Running 0 23m sample-deployment-5f47777b55-c9vfx 0/1 Terminating 0 23m sample-deployment-5f47777b55-dgjnw 1/1 Running 0 23m sample-deployment-5f47777b55-f9w6r 1/1 Running 0 23m sample-deployment-5f47777b55-tmqcq 1/1 Running 0 23m sample-deployment-86bd954768-8d8pj 1/1 Running 0 48s sample-deployment-86bd954768-c5hfc 0/1 Pending 0 3s sample-deployment-86bd954768-c69rs 0/1 Pending 0 5s sample-deployment-86bd954768-drjrh 0/1 Pending 0 4s sample-deployment-86bd954768-dzlsk 0/1 ContainerCreating 0 48s sample-deployment-86bd954768-jxcvc 1/1 Running 0 48s sample-deployment-86bd954768-nm5v8 0/1 ContainerCreating 0 48s sample-deployment-86bd954768-q89zq 1/1 Running 0 48s # ロールバック完了 NAME READY STATUS RESTARTS AGE sample-deployment-86bd954768-8d8pj 1/1 Running 0 116s sample-deployment-86bd954768-c5hfc 1/1 Running 0 71s sample-deployment-86bd954768-c69rs 1/1 Running 0 73s sample-deployment-86bd954768-drjrh 1/1 Running 0 72s sample-deployment-86bd954768-dzlsk 1/1 Running 0 116s sample-deployment-86bd954768-jxcvc 1/1 Running 0 116s sample-deployment-86bd954768-kklz6 1/1 Running 0 64s sample-deployment-86bd954768-nm5v8 1/1 Running 0 116s sample-deployment-86bd954768-q89zq 1/1 Running 0 116s sample-deployment-86bd954768-wnpxc 1/1 Running 0 61s
自己回復機能を試す
- 次に、
Deployment
の自己回復機能を確認します。- 単独で起動した
Pod
とDeployment
から起動したポッドの振る舞いを比較し、自己回復機能を確認します。 - ポッドは、コンテナレベルの障害に対応する自己回復機能を有していますが、
Deployment
はPod
の障害に対応する自己回復機能を有します。
- 単独で起動した
- 以下、ノード停止を想定した自己回復機能を確認するため、EKS 上の K8s クラスターを Fargate ではなく EC2 に作成しておきます。
$ eksctl create cluster \ --name [クラスター名] \ --region [リージョン名] \ --nodegroup-name standard-workers \ --node-type t2.micro \ --nodes 3 \ --nodes-min 1 \ --nodes-max 6 \ --ssh-access \ --ssh-public-key my-public-key.pub
マニフェストファイルの作成と適用
Pod
を単独で生成するためのマニフェストファイルを以下のように作成します。- この
Pod
自体の振る舞いは、「1 時間経過後に終了するシェルを実行する」ことです。
- この
pod.yml
apiVersion: v1 kind: Pod metadata: name: "sample-pod" spec: containers: - name: busybox image: busybox:1 command: ["sh", "-c", "sleep 3600; exit 0"] restartPolicy: Always
Deployment
からPod
を起動するマニフェストは以下のように作成します。
deployment.yml
apiVersion: apps/v1 kind: Deployment metadata: name: "sample-deployment" spec: selector: matchLabels: app: "sample-app" replicas: 3 template: metadata: labels: app: "sample-app" spec: containers: - name: nginx-container image: nginx:1.17 ports: - containerPort: 80
- これらを
kubectl apply
で適用して、生成されたことを確認します。- 今回は、単体の
Pod
とDeployment
によって作られたPod
が同じノードip-192-168-60-208.us-east-2.compute.internal
に作られたことに注意しておきます。
- 今回は、単体の
$ kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES sample-deployment-5f47777b55-6ln9j 1/1 Running 0 8m6s 192.168.53.40 ip-192-168-60-208.us-east-2.compute.internal <none> <none> sample-deployment-5f47777b55-q6z46 1/1 Running 0 8m6s 192.168.76.35 ip-192-168-93-142.us-east-2.compute.internal <none> <none> sample-deployment-5f47777b55-z2ptv 1/1 Running 0 8m6s 192.168.68.255 ip-192-168-93-142.us-east-2.compute.internal <none> <none> sample-pod 1/1 Running 0 6m7s 192.168.39.68 ip-192-168-60-208.us-east-2.compute.internal <none> <none>
ノードを停止させる
- 稼働中のノードを停止は、Amazon EC2 の管理画面から行います。
- 管理画面を開き、左メニューの「インスタンス」を選択します。
- 下図のように、インスタンス一覧が表示されるます。停止対象のインスタンスを探します。
- 今回の場合、「プライベート DNS」が
ip-192-168-60-208.us-east-2.compute.internal
であるものが対象です。
- 今回の場合、「プライベート DNS」が
- しばらくすると、下記のようにノードが停止します。
- その後、ノード数 3 を維持するために、新たなノードが起動します。
ノード停止後からのポッドの様子を確認する
- ノード停止後、
kubectl get pod,deploy -o wide
のコマンドでPod
とDeployment
の様子を確認します。
ノード停止後の復旧の様子を確認
# ノード停止直前 $ kubectl get pod,deploy -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/sample-deployment-5f47777b55-6ln9j 1/1 Running 0 28m 192.168.53.40 ip-192-168-60-208.us-east-2.compute.internal <none> <none> pod/sample-deployment-5f47777b55-q6z46 1/1 Running 0 28m 192.168.76.35 ip-192-168-93-142.us-east-2.compute.internal <none> <none> pod/sample-deployment-5f47777b55-z2ptv 1/1 Running 0 28m 192.168.68.255 ip-192-168-93-142.us-east-2.compute.internal <none> <none> pod/sample-pod 1/1 Running 0 26m 192.168.39.68 ip-192-168-60-208.us-east-2.compute.internal <none> <none> NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR deployment.extensions/sample-deployment 2/3 3 2 28m nginx-container nginx:1.17 app=sample-app # ノード停止後、100 秒ほど経過した後 # -> Deployment の Pod は 2 個だけが稼働状態となっている。単独で起動した Pod は消滅したまま。 $ kubectl get pod,deploy -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/sample-deployment-5f47777b55-j69vl 0/1 Pending 0 109s <none> <none> <none> <none> pod/sample-deployment-5f47777b55-q6z46 1/1 Running 0 31m 192.168.76.35 ip-192-168-93-142.us-east-2.compute.internal <none> <none> pod/sample-deployment-5f47777b55-z2ptv 1/1 Running 0 31m 192.168.68.255 ip-192-168-93-142.us-east-2.compute.internal <none> <none> NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR deployment.extensions/sample-deployment 2/3 3 2 31m nginx-container nginx:1.17 app=sample-app # ノード停止後、3 分ほど経過した後 # -> Deployment の Pod は再び 3 個が稼働状態となっている。新たなPod は、別のノードで稼働し始める。 # 単独で起動した Pod は復旧せず消滅したまま。 $ kubectl get pod,deploy -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/sample-deployment-5f47777b55-j69vl 1/1 Running 0 3m44s 192.168.44.239 ip-192-168-56-255.us-east-2.compute.internal <none> <none> pod/sample-deployment-5f47777b55-q6z46 1/1 Running 0 32m 192.168.76.35 ip-192-168-93-142.us-east-2.compute.internal <none> <none> pod/sample-deployment-5f47777b55-z2ptv 1/1 Running 0 32m 192.168.68.255 ip-192-168-93-142.us-east-2.compute.internal <none> <none> NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR deployment.extensions/sample-deployment 3/3 3 3 33m nginx-container nginx:1.17 app=sample-app
- ここで起こったことを順に図にすると以下のような流れになります。まず、
Deployment
によるPod
3 個と単独で起動したポッド 1 個が稼働している状態です。
- 次に、管理画面からノードを停止させました。この際、
ReplicaSet
は管理しているPod
1 個が喪失されたことを検知します。
ReplicaSet
の動作により、別のノードにPod
が 1 個生成され、稼働します。ReplicaSet
の管理下になかったPod
は別のノードで稼働することはなく、消滅してしまいます。
Deployment を利用した高可用性構成
- 1 つのポッドと永続ボリュームを用いて、下図のような高可用性構成(HA 構成)を作ることができます。
- ノードが喪失してしまうような障害が発生した場合、
Deployment
がPod
を移動させ、サービスを継続できます。 - ノードが計画停止する場合でも、事前に
Pod
を他のノードに移動してサービスを継続できます。
- ノードが喪失してしまうような障害が発生した場合、
- 以下、ノード障害が発生した場合でも、他のノードでポッドが再スタートし、データも無事に守られている事を確認します。
- 事前準備として、前回の記事を参考に永続ボリュームを作成しておきます。
- 今回は、EFS を利用した永続ボリュームを作成しておきます。
高可用性構成のためのマニフェストファイルの準備
- 以下のとおり、MySQL のコンテナを稼働させるためのマニフェストファイルを用意します。
- マニフェストファイルは GitLab のリポジトリでも公開しております。
strorageclass.yml
kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: efs-sc provisioner: efs.csi.aws.com
claim.yml
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: efs-claim spec: accessModes: - ReadWriteMany storageClassName: efs-sc resources: requests: storage: 5Gi
pv.yml
apiVersion: v1 kind: PersistentVolume metadata: name: efs-pv spec: capacity: storage: 5Gi volumeMode: Filesystem accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain storageClassName: efs-sc csi: driver: efs.csi.aws.com volumeHandle: [EFS のファイルシステム ID]
deployment.yml
apiVersion: apps/v1 kind: Deployment metadata: name: mysql labels: app: mysql spec: selector: matchLabels: app: mysql replicas: 1 template: metadata: labels: app: mysql spec: containers: - name: mysql image: mysql:5.7 ports: - containerPort: 3306 env: - name: MYSQL_ROOT_PASSWORD value: qwerty volumeMounts: - mountPath: /var/lib/mysql name: pvc subPath: mysql-data # EKS や GKE の永続ボリュームを使用する場合は必要 livenessProbe: exec: command: ["mysqladmin","-p$MYSQL_ROOT_PASSWORD","ping"] initialDelaySeconds: 60 timeoutSeconds: 10 volumes: - name: pvc persistentVolumeClaim: claimName: efs-claim
- EKS の永続ボリュームでは、ファイルシステムのルートに
lost+found
のディレクトリが存在するため、 MySQL コンテナの初期化処理がエラーとなってしまい、異常終了します。- そのため、
subPath
を設定し、空のディレクトリをマウントするようにします。 - 詳しくはこちら
- GKE(Google Kubernetes Engine)を利用する際にも同様の問題が発生します。
- そのため、
- MySQL の設定でパスワードをベタ書きで設定していますが、実際の本番運用においては、シークレット(Secret)リソースを用いてマニフェストファイルに機密情報をベタ書きしないようにします。
- 詳しくはこちらの記事を参照
service.yml
apiVersion: v1 kind: Service metadata: name: mysql-dpl labels: app: mysql spec: type: NodePort ports: - port: 3306 nodePort: 30306 selector: app: mysql
マニフェストファイルの適用と中身の確認
- マニフェストフェイルを
kubectl apply -f
で適用したら、コンテナの中に入って MySQL の操作を行います。- 後に、データが消えていない事を確認するため、データベースとテーブルとレコードを作成しておきます。
MySQL のコンテナに入って、レコードを作成するまでの流れ
$ kubectl exec -it mysql-5f98f6b65b-77m6b -- /bin/bash root@mysql-5f98f6b65b-77m6b:/# mysql -u root -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 199 Server version: 5.7.30 MySQL Community Server (GPL) Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | +--------------------+ 4 rows in set (0.03 sec) mysql> create database test_db; Query OK, 1 row affected (0.03 sec) mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | test_db | +--------------------+ 5 rows in set (0.00 sec) mysql> use test_db; Database changed mysql> show tables; Empty set (0.01 sec) mysql> CREATE TABLE `m_users` ( -> `id` int NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT "ID", -> `user_name` VARCHAR(100) NOT NULL COMMENT "", -> `mail_address` VARCHAR(200) NOT NULL COMMENT "", -> `password` VARCHAR(100) NOT NULL COMMENT "", -> `created` datetime DEFAULT NULL COMMENT "", -> `modified` datetime DEFAULT NULL COMMENT "" -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8; Query OK, 0 rows affected (0.14 sec) mysql> INSERT INTO m_users (user_name, mail_address, password, created, modified) -> VALUES ("Hoge Taro", "hogetaro@hoge.com", "123123", now(), now()); Query OK, 1 row affected (0.03 sec) mysql> select * from m_users; +----+-----------+------------------+----------+---------------------+---------------------+ | id | user_name | mail_address | password | created | modified | +----+-----------+------------------+----------+---------------------+---------------------+ | 1 | Hoge Taro | hogetaro@hoge.com| 123123 | 2020-05-19 02:21:55 | 2020-05-19 02:21:55 | +----+-----------+------------------+----------+---------------------+---------------------+ 1 row in set (0.00 sec) mysql> \q Bye root@mysql-5f98f6b65b-77m6b:/# exit
- 作成された
Pod
の情報を確認しておきます。- あとで、ノードが変わっていることを確認します。
作成された MySQL の Pod の情報確認
$ kubectl describe pod mysql-5f98f6b65b-77m6b Name: mysql-5f98f6b65b-77m6b Namespace: default Priority: 0 Node: ip-192-168-35-15.us-east-2.compute.internal/192.168.35.15 Start Time: Tue, 19 May 2020 10:41:06 +0900 Labels: app=mysql pod-template-hash=5f98f6b65b Annotations: kubernetes.io/psp: eks.privileged Status: Running IP: 192.168.38.116 IPs: <none> Controlled By: ReplicaSet/mysql-5f98f6b65b Containers: mysql: Container ID: docker://511b1adc2e1fdc0199210dc0697304bbbc1125ac0d709cb072489aec8ef7602c Image: mysql:5.7 Image ID: docker-pullable://mysql@sha256:5c9fd7949bc0f076429fa2c40d0e7406e095bdb5216a923257b31972a6f3ae4f Port: 3306/TCP Host Port: 0/TCP State: Running Started: Tue, 19 May 2020 10:41:18 +0900 Ready: True Restart Count: 0 Liveness: exec [mysqladmin -p$MYSQL_ROOT_PASSWORD ping] delay=60s timeout=10s period=10s #success=1 #failure=3 Environment: MYSQL_ROOT_PASSWORD: qwerty Mounts: /var/lib/mysql from pvc (rw,path="mysql-data") /var/run/secrets/kubernetes.io/serviceaccount from default-token-rsllf (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: pvc: Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace) ClaimName: efs-claim ReadOnly: false default-token-rsllf: Type: Secret (a volume populated by a Secret) SecretName: default-token-rsllf Optional: false QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 50m (x4 over 50m) default-scheduler pod has unbound immediate PersistentVolumeClaims (repeated 4 times) Normal Scheduled 49m default-scheduler Successfully assigned default/mysql-5f98f6b65b-77m6b to ip-192-168-35-15.us-east-2.compute.internal Normal Pulling 49m kubelet, ip-192-168-35-15.us-east-2.compute.internal Pulling image "mysql:5.7" Normal Pulled 49m kubelet, ip-192-168-35-15.us-east-2.compute.internal Successfully pulled image "mysql:5.7" Normal Created 49m kubelet, ip-192-168-35-15.us-east-2.compute.internal Created container mysql Normal Started 49m kubelet, ip-192-168-35-15.us-east-2.compute.internal Started container mysql
ノードの停止と経過確認、データの確認
- 先程と同様に、AWS のコンソール画面から MySQL の
Pod
が稼働しているノードを停止させます。 - 停止させたら、
while true; do date; kubectl get po -o wide; kubectl get deploy; sleep 10; done
のコマンドを実行させ、Pod
とDeployment
の情報を様子を確認します。- fish-shell を使っている場合は、
while true;date; kubectl get po -o wide; kubectl get deploy; sleep 10; end
を実行します。
- fish-shell を使っている場合は、
ノード停止後の
Pod
と Deployment
の様子
$ while true; do date; kubectl get po -o wide; kubectl get deploy; sleep 10; done # ノード停止直後 2020年 5月19日 火曜日 11時49分08秒 JST NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES mysql-5f98f6b65b-77m6b 1/1 Running 0 68m 192.168.38.116 ip-192-168-35-15.us-east-2.compute.internal <none> <none> NAME READY UP-TO-DATE AVAILABLE AGE mysql 1/1 1 1 68m # ノード停止後しばらく経つと、Deployment の AVAILABLE がゼロになります。 2020年 5月19日 火曜日 11時50分24秒 JST NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES mysql-5f98f6b65b-77m6b 1/1 Running 0 69m 192.168.38.116 ip-192-168-35-15.us-east-2.compute.internal <none> <none> NAME READY UP-TO-DATE AVAILABLE AGE mysql 0/1 1 0 69m # 更に時間が経過すると、再び Deployment が利用できるようになります。 # この際、Pod が配置されているノードが変わっていることがわかります。 2020年 5月19日 火曜日 11時51分12秒 JST NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES mysql-5f98f6b65b-kbbp5 1/1 Running 0 11s 192.168.24.156 ip-192-168-15-93.us-east-2.compute.internal <none> <none> NAME READY UP-TO-DATE AVAILABLE AGE mysql 1/1 1 1 70m
サービス復旧後の
Pod
の情報を確認
$ kubectl describe pod mysql-5f98f6b65b-kbbp5 Name: mysql-5f98f6b65b-kbbp5 Namespace: default Priority: 0 Node: ip-192-168-15-93.us-east-2.compute.internal/192.168.15.93 Start Time: Tue, 19 May 2020 11:51:02 +0900 Labels: app=mysql pod-template-hash=5f98f6b65b Annotations: kubernetes.io/psp: eks.privileged Status: Running IP: 192.168.24.156 IPs: <none> Controlled By: ReplicaSet/mysql-5f98f6b65b Containers: mysql: Container ID: docker://e9cdc23301058d5c1196f122a18de83e6a07d6e43ad242317d2fae631f8089f4 Image: mysql:5.7 Image ID: docker-pullable://mysql@sha256:5c9fd7949bc0f076429fa2c40d0e7406e095bdb5216a923257b31972a6f3ae4f Port: 3306/TCP Host Port: 0/TCP State: Running Started: Tue, 19 May 2020 11:51:12 +0900 Ready: True Restart Count: 0 Liveness: exec [mysqladmin -p$MYSQL_ROOT_PASSWORD ping] delay=60s timeout=10s period=10s #success=1 #failure=3 Environment: MYSQL_ROOT_PASSWORD: qwerty Mounts: /var/lib/mysql from pvc (rw,path="mysql-data") /var/run/secrets/kubernetes.io/serviceaccount from default-token-rsllf (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: pvc: Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace) ClaimName: efs-claim ReadOnly: false default-token-rsllf: Type: Secret (a volume populated by a Secret) SecretName: default-token-rsllf Optional: false QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 10m default-scheduler Successfully assigned default/mysql-5f98f6b65b-kbbp5 to ip-192-168-15-93.us-east-2.compute.internal Normal Pulling 10m kubelet, ip-192-168-15-93.us-east-2.compute.internal Pulling image "mysql:5.7" Normal Pulled 10m kubelet, ip-192-168-15-93.us-east-2.compute.internal Successfully pulled image "mysql:5.7" Normal Created 10m kubelet, ip-192-168-15-93.us-east-2.compute.internal Created container mysql Normal Started 10m kubelet, ip-192-168-15-93.us-east-2.compute.internal Started container mysql
- 再度、MySQL のコンテナに入り、データを確認してみます。
サービス復旧後の MySQL のデータを確認
$ kubectl exec -it mysql-5f98f6b65b-kbbp5 -- /bin/bash root@mysql-5f98f6b65b-kbbp5:/# mysql -u root -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 64 Server version: 5.7.30 MySQL Community Server (GPL) Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | test_db | +--------------------+ 5 rows in set (0.05 sec) mysql> use test_db; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> show tables; +-------------------+ | Tables_in_test_db | +-------------------+ | m_users | +-------------------+ 1 row in set (0.01 sec) mysql> select * from m_users; +----+-----------+------------------+----------+---------------------+---------------------+ | id | user_name | mail_address | password | created | modified | +----+-----------+------------------+----------+---------------------+---------------------+ | 1 | Hoge Taro | hogetaro@hoge.com| 123123 | 2020-05-19 02:21:55 | 2020-05-19 02:21:55 | +----+-----------+------------------+----------+---------------------+---------------------+ 1 row in set (0.00 sec) mysql> \q Bye root@mysql-5f98f6b65b-kbbp5:/# exit exit
- 上記のように、
Pod
が別のノードで稼働し始めても、データは喪失せず、無事残っていることが確認できました。
まとめ
- K8s の
Deployment
を利用することで、Pod
の稼働数が適切に管理され、アプリケーションの可用性が担保されることを確認しました。 - EKS において、
Deployment
と永続ボリュームを用いることでノード障害からデータを守る高可用性構成(HA 構成)が実現できることを試行してみました。- ここでは試してませんが、メンテナンスのために
Pod
を別のノードに移した場合でも同様にサービスを継続できます。
- ここでは試してませんが、メンテナンスのために
- マニフェストによって宣言的設定をすれば、K8s でよしなにオブジェクトの生成・設定をしてくれることの強力さが感じられたように思います。
参考資料
- 高良(2019)「15Stepで習得 Dockerから入るKubernetes」リックテレコム
-
Deployment
の概念の説明と HA 構成の設定の仕方について参考にしました。
-
- 単一レプリカのステートフルアプリケーションを実行する - Kubernetes
- MySQL のコンテナを稼働させる際の設定などを参考にしました。