k8sクラスタのノードの一つが、ハードウェア障害などでダウンした場合の振る舞いについて検証した記録です。
検証システムの構成
Kubenetes v1.10 クラスタをVagrantで構築したメモのVagrantで構築したk8sクラスタを利用して、障害時の振る舞いについて、調べてみました。
マスターノードであるk8s1にもNodePortが動作していますから、このk8s1をロードバランサーに見立て、HTTPクライアントからk8s1のTCP31514をアクセスして、k8s2とk8s3のNginxのウェブサーバーをアクセスします。 そして、 k8s2 仮想サーバーの模擬障害としてシャットダウンした場合のクライアント視点での動作、ポッドのマイグレーションについて検証します。
正常稼働の状態
初期状態として、すべてが正常に稼働している状態の動作を確認しておきます。
この画面の表示は、上から順に、以下3種類のコマンドの結果です。
- kubectl get node
- kubectl get deployment
- kubectl get pod -o wide
Mon Apr 16 13:30:03 UTC 2018
NAME STATUS ROLES AGE VERSION
k8s1 Ready master 1d v1.10.1
k8s2 Ready node 1d v1.10.1
k8s3 Ready node 1d v1.10.1
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-webserver 6 6 6 6 1m
NAME READY STATUS RESTARTS AGE IP NODE
nginx-webserver-69878cbf8d-9cf64 1/1 Running 0 1m 10.244.2.43 k8s3
nginx-webserver-69878cbf8d-9vhr9 1/1 Running 0 1m 10.244.2.45 k8s3
nginx-webserver-69878cbf8d-jpw25 1/1 Running 0 1m 10.244.1.49 k8s2
nginx-webserver-69878cbf8d-kjgcf 1/1 Running 0 1m 10.244.2.44 k8s3
nginx-webserver-69878cbf8d-lbbqh 1/1 Running 0 1m 10.244.1.50 k8s2
nginx-webserver-69878cbf8d-xrqpr 1/1 Running 0 1m 10.244.1.48 k8s2
クライアントのアクセス状況
クライアントからのアクセスは、すべてHTTP 200 OK
が返されます。
ノード障害発生後のノード停止検知
サーバーのハードウェア障害停止を想定して、vagrant k8s2 halt
を実行してシャットダウンします。
約30秒後に、次の様にコマンドの結果が変化します。
- kubectl get node は、k8s2のNodeのステータスが変わり、Ready から NodeReady へ変わります。
- kubectl get deployment は、AVAILABLE(存在数)が 6から3へ減ります。
- kubectl get pod は、変化がありません。
Mon Apr 16 13:30:46 UTC 2018
NAME STATUS ROLES AGE VERSION
k8s1 Ready master 1d v1.10.1
k8s2 NotReady node 1d v1.10.1
k8s3 Ready node 1d v1.10.1
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-webserver 6 6 6 3 2m
NAME READY STATUS RESTARTS AGE IP NODE
nginx-webserver-69878cbf8d-9cf64 1/1 Running 0 2m 10.244.2.43 k8s3
nginx-webserver-69878cbf8d-9vhr9 1/1 Running 0 2m 10.244.2.45 k8s3
nginx-webserver-69878cbf8d-jpw25 1/1 Running 0 2m 10.244.1.49 k8s2
nginx-webserver-69878cbf8d-kjgcf 1/1 Running 0 2m 10.244.2.44 k8s3
nginx-webserver-69878cbf8d-lbbqh 1/1 Running 0 2m 10.244.1.50 k8s2
nginx-webserver-69878cbf8d-xrqpr 1/1 Running 0 2m 10.244.1.48 k8s2
HTTPクライアントのアクセス状況
ノードの障害が発生して、約30秒間は、リクエストが割り振られるために、HTTPクライアントで、エラーが発生します。しかし、Nodeの停止を検知すると、リクエストの分配が止まり、HTTPクライアントのエラーは無くなります。
- サーバーが停止してから約30秒間は、HTTPアクセスのタイムアウトが発生します この時のタイムアウト時間は3秒です。
- 30秒経過後、ノードのステータスが、Ready から NotReady に変化すると、k8s2 へ割り振られなくなり、すべて
HTTP 200 OK
が返される様になります。
ノード障害発生後のポッド・マイグレーション開始
ノードの障害停止から、約5分後に、ポッドのマイグレーションが開始されます。 DESIRED 6 の値と AVAILABLE 3 の値が同じになる様に、残存するワーカーノード k8s3 上でポッドを起動します。 停止したk8s2のポッドのSTATUSは、不明(Unknown)として表示される様になります。
Mon Apr 16 13:35:09 UTC 2018
NAME STATUS ROLES AGE VERSION
k8s1 Ready master 1d v1.10.1
k8s2 NotReady node 1d v1.10.1
k8s3 Ready node 1d v1.10.1
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-webserver 6 6 6 6 6m
NAME READY STATUS RESTARTS AGE IP NODE
nginx-webserver-69878cbf8d-4qgck 1/1 Running 0 12s 10.244.2.46 k8s3
nginx-webserver-69878cbf8d-9cf64 1/1 Running 0 6m 10.244.2.43 k8s3
nginx-webserver-69878cbf8d-9vhr9 1/1 Running 0 6m 10.244.2.45 k8s3
nginx-webserver-69878cbf8d-jm6c2 1/1 Running 0 12s 10.244.2.47 k8s3
nginx-webserver-69878cbf8d-jpw25 1/1 Unknown 0 6m 10.244.1.49 k8s2
nginx-webserver-69878cbf8d-kjgcf 1/1 Running 0 6m 10.244.2.44 k8s3
nginx-webserver-69878cbf8d-lbbqh 1/1 Unknown 0 6m 10.244.1.50 k8s2
nginx-webserver-69878cbf8d-x4946 1/1 Running 0 12s 10.244.2.48 k8s3
nginx-webserver-69878cbf8d-xrqpr 1/1 Unknown 0 6m 10.244.1.48 k8s2
HTTPクライアントのアクセス状況
HTTPクライアントでは、エラーは発生しません。 すべて HTTP 200 OK
の結果が返ります。
障害ノードの復旧後の動作
障害停止したk8s2が、復旧してオンラインに戻った状態からの動作を想定して振る舞いを確認します。 k8s2のブートが完了して、約20秒後に、ノードのSTATUSが Readyに戻り、ポッドのSTATUSがUnknownのものを終了させます。 その後は、ポッドは、k8s3で稼働を続けk8s2へ再スケジュールされる事はありません。 k8s3へ偏ったポッドをk8s2にも均等に配置される様に、リスケジュールしたい場合は、アプリケーションのポッドをロールアウトする事で、均等に配置される様になります。
Mon Apr 16 13:38:52 UTC 2018
NAME STATUS ROLES AGE VERSION
k8s1 Ready master 1d v1.10.1
k8s2 Ready node 1d v1.10.1
k8s3 Ready node 1d v1.10.1
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-webserver 6 6 6 6 10m
NAME READY STATUS RESTARTS AGE IP NODE
nginx-webserver-69878cbf8d-4qgck 1/1 Running 0 3m 10.244.2.46 k8s3
nginx-webserver-69878cbf8d-9cf64 1/1 Running 0 10m 10.244.2.43 k8s3
nginx-webserver-69878cbf8d-9vhr9 1/1 Running 0 10m 10.244.2.45 k8s3
nginx-webserver-69878cbf8d-jm6c2 1/1 Running 0 3m 10.244.2.47 k8s3
nginx-webserver-69878cbf8d-kjgcf 1/1 Running 0 10m 10.244.2.44 k8s3
nginx-webserver-69878cbf8d-lbbqh 0/1 Terminating 0 10m <none> k8s2
nginx-webserver-69878cbf8d-x4946 1/1 Running 0 3m 10.244.2.48 k8s3
HTTPクライアントのアクセス状況
HTTPクライアントでは、エラーは発生しません。 すべて HTTP 200 OK
の結果が返ります。
復旧後にポッドの配置をリバランスするには?
この偏った状態では、次にk8s3で障害が発生した時に5分以上は完全に停止する事になります。 したがって、ポッドの配置をリバランスして、リスクを減らしたいと思うのですが、ポッドの配置をリバランスするという事は、実行中のポッドを停止させることを意味しており、自動的リバランスの機能はしばらく実装されない様な事が、Issuesに書かれていました。 そこで、タグ名を更新したコンテナを kubectl apply -f new_version_apl.yaml
によって、ロールアウトする事で、リバランスする事ができます。
Mon Apr 16 15:57:21 UTC 2018
NAME STATUS ROLES AGE VERSION
k8s1 Ready master 1d v1.10.1
k8s2 Ready node 1d v1.10.1
k8s3 Ready node 1d v1.10.1
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-webserver 6 6 6 6 2h
NAME READY STATUS RESTARTS AGE IP NODE
nginx-webserver-5dbb4f8976-2l62j 1/1 Running 0 1h 10.244.2.49 k8s3
nginx-webserver-5dbb4f8976-dnrhr 1/1 Running 0 1h 10.244.1.66 k8s2
nginx-webserver-5dbb4f8976-fqxrp 1/1 Running 0 1h 10.244.1.68 k8s2
nginx-webserver-5dbb4f8976-pmnr5 1/1 Running 0 1h 10.244.2.50 k8s3
nginx-webserver-5dbb4f8976-qgwxb 1/1 Running 0 1h 10.244.1.65 k8s2
nginx-webserver-5dbb4f8976-vrqjm 1/1 Running 0 1h 10.244.1.67 k8s2
まとめ
障害発生時直後の振る舞いは、ドキュメントされる事も少なくて、設計上の振る舞いが記載され、実装結果の振る舞いが、諸所の条件から異なる事も少なくなく、実際に検証しないと確信が持てないことが多いものです。 今回、K8s v1.10の最新バージョンをvagrantの仮想環境に作りましたから、心おきなく、模擬障害を発生させて、ノードロスト時の振る舞いを確認することができました。
クライアントにエラーを検知するのは、発生から約30秒間だけで、ノード障害を検知した後はクライアントでエラーが発生する事はありませんでした。また、障害停止したノードが復旧した後は、自動的に再配置(リスケジュール)される事はなく、ロールアウトする事で、リバランスされる事が解りました。
ノード数が2で実験しましたが、ノード数が多いほど、ノード障害時の影響を受けるポッドの割合が減らせる事になります。また、マイグレーションが発生するまで、約5分を要するので、ノードが1台ロスとしても、負荷に耐えらえるポッド数を配置しておく必要もあります。