Incus VMでMicroK8sクラスタを組んでみた (2of2) 検証編
List of documents
Incus VMでMicroK8sクラスタを組んでみた (1of2) 構築編
Incus VMでMicroK8sクラスタを組んでみた (2of2) 検証編
本記事は、構築編からの続きです。
MicroK8sのHA (High Availability)がどう動作するか実際に検証してみたメモ。
検証環境は、v1.33/stableで、Master node 3台、Standby node 1台のクラスタ構成です。
$ incus exec k8s1-vm -- microk8s kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s0-vm Ready <none> 2d14h v1.33.0
k8s1-vm Ready <none> 2d14h v1.33.0
k8s2-vm Ready <none> 2d14h v1.33.0
k8s3-vm Ready <none> 2d14h v1.33.0
MicroK8sのHAのGracefulとUngracefulについて
はじめに、microk8sの公式サイトに以下の記述があります。
To ensure the health of the cluster the following timings should be taken into account:
- If the leader node gets “removed” ungracefully, e.g. it crashes and never comes back, it will take up to 5 seconds for the cluster to elect a new leader.
- Promoting a non-voter to a voter takes up to 30 seconds. This promotion takes place when a new node enters the cluster or when a voter crashes.
leader: Master nodesの内の1台
voter: Master nodes
non-voter: Standby node
と読み替えます。
運用コマンドにより意図してノードをクラスタから切り離し(leave)、ノードをクラスタのメンバから削除する(remove-node)するのがGracefulで、意図せず障害で強制的に切り離されるのがUngracefulということですね。
今回、実際にGracefulとUngracefulの両方のケースで動作検証してみました。
以下、検証レポートとなります。
筆者の感覚で想定外だった動作は想定外の結果にまとめました。
検証1 Ungracefulのケース
テスト項目1.1 ノード障害 (stop VM)
テスト概要
- microbotサービスが動作しているVMインスタンスをstopする。
期待する結果
- StandbyノードがMasterノードに昇格する。
- microbotサービスが別のVMノード上で自動起動する。
テスト項目 | 期待する結果 | テスト結果 | |
---|---|---|---|
1 | incus list | stopしたVMインスタンスがSTOPPEDになる。 | PASSED |
2 | microk8s kubectl get nodes | stopしたVMノードがNotReadyになる。 | PASSED |
3 | microk8s status | Standby nodeがMaster nodeに昇格する。 | PASSED ※1 |
4 | microk8s kubectl describe pod microbot | stopしたVMノード上のmicrobotが、別のReadyなVMノード上で自動起動する。 | PASSED ※2 |
5 | microbot access via metallb | metallbのIPアドレスが変わらず、自動起動したmicrobotへアクセスできる。 | PASSED |
想定外の結果
※1 UngracefulでNotReadyになっているノードがあるとmicrok8s status
の挙動が異常
-
想定外1:
microk8s status
のコマンド応答が異常に遅くなる
UngracefulでNotReadyになっているノードがあるとコマンド応答に1分程度かかる。
なおstopしたVMインスタンスをstartすると(VMノードをReadyにすると)正常に戻る。 -
想定外2:
microk8s status
コマンドでHA状態が正しく表示されなくなる
no/none/none表示となってしまい、HA状態がコマンドで把握できなくなる。
<期待する表示>
high-availabilty: yes
datastore master nodes: <VM1 IP:Port> <VM2 IP:Port> <VM3 IP:Port>
datastore standby nodes: none
<実際の表示>
high-availabilty: no
datastore master nodes: none
datastore standby nodes: none
おかしいのは表示だけで、実際はStandbyからMasterへの昇格自体は行われている模様。
なおstopしたVMインスタンスをstartすると(VMノードをReadyにすると)正常表示に戻る。
※2 サービス復旧が遅い (microk8s kubectl describe pod microbot
による観測)
-
想定外3: サービスが別VMノード上で自動起動するまで5分程度かかる
これはmicrok8sの仕様どおりの挙動かもしれないが、5分程度もサービス障害が継続するとは想定していなかった。 -
想定外4: サービスが別VMノード上で自動起動した後も、microk8sの管理上、stopしたVMノード上のサービスが消されず状態が残り、状態のクリーンアップに手動操作が必要
残っていても実害なしだが、状態をクリーンアップするには手動操作でstopしたVMノードを組み戻す (start VMし、VMノードをReadyに戻す)必要がある。手動操作は想定していなかった。
テスト記録
microbotが動作しているVMインスタンスを確認し、stopします。
$ curl 10.57.140.201:80
<!DOCTYPE html>
<html>
<style type="text/css">
.centered
{
text-align:center;
margin-top:0px;
margin-bottom:0px;
padding:0px;
}
</style>
<body>
<p class="centered"><img src="microbot.png" alt="microbot"/></p>
<p class="centered">Container hostname: microbot-7d987d6fc6-8m2xz</p>
</body>
</html>
$ incus exec k8s0-vm -- microk8s kubectl describe pod microbot | grep Node:
Node: k8s2-vm/10.57.140.98
$ incus stop k8s2-vm
stopしたVMインスタンスがSTOPPEDになったことを確認します。
$ incus list | grep VIRTUAL
| k8s0-vm | RUNNING | 10.57.140.189 (enp5s0) | fdxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx (enp5s0) | VIRTUAL-MACHINE | 0 |
| k8s1-vm | RUNNING | 10.57.140.40 (enp5s0) | fdxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx (enp5s0) | VIRTUAL-MACHINE | 0 |
| k8s2-vm | STOPPED | | | VIRTUAL-MACHINE | 0 |
| k8s3-vm | RUNNING | 10.57.140.147 (enp5s0) | fdxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx (enp5s0) | VIRTUAL-MACHINE | 0 |
stopしたVMノードがNotReadyになったことを確認します。
$ incus exec k8s1-vm -- microk8s kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s0-vm Ready <none> 2d14h v1.33.0
k8s1-vm Ready <none> 2d14h v1.33.0
k8s2-vm NotReady <none> 2d14h v1.33.0
k8s3-vm Ready <none> 2d14h v1.33.0
Standby nodeがMaster nodeに昇格したことを確認します。
※想定外1: コマンド応答が遅くなり、1分程度かかる。
※想定外2: no/none/none表示になってしまい、昇格したことを確認できない。
$ incus exec k8s0-vm -- microk8s status --wait-ready | grep -e "high-" -e "nodes"
high-availability: no
datastore master nodes: none
datastore standby nodes: none
stopしたVMノード上のmicrobotが、別のReadyなVMノードで自動起動したことを確認します。
※想定外3: 自動起動に5分程度かかる。
※想定外4: 自動起動後も、stop VMしたノード上の状態が残る。
## stop VMの直後
$ incus exec k8s0-vm -- microk8s kubectl describe pod microbot | grep Node:
Node: k8s2-vm/10.57.140.98
## stop VMから約5分経過後
$ incus exec k8s0-vm -- microk8s kubectl describe pod microbot | grep Node:
Node: k8s3-vm/10.57.140.147
Node: k8s2-vm/10.57.140.98
metallbのIPアドレスが変わらず、自動起動したmicrobotへアクセスできることを確認します。
$ curl 10.57.140.201:80
<!DOCTYPE html>
<html>
<style type="text/css">
.centered
{
text-align:center;
margin-top:0px;
margin-bottom:0px;
padding:0px;
}
</style>
<body>
<p class="centered"><img src="microbot.png" alt="microbot"/></p>
<p class="centered">Container hostname: microbot-7d987d6fc6-h2fph</p>
</body>
</html>
テスト項目1.2 ノード障害復旧 (start VM)
テスト概要
- stopしたVMインスタンスをstartする。
期待する結果
- startしたVMがStandbyノードとしてクラスタに組み込まれる。
テスト項目 | 期待する結果 | テスト結果 | |
---|---|---|---|
1 | incus list | startしたVMインスタンスがRUNNINGになる。 | PASSED |
2 | microk8s kubectl get nodes | startしたVMノードがReadyになる。 | PASSED |
3 | microk8s status | startしたVMノードがStandby nodeになる。 | PASSED |
想定外の結果
- なし
テスト記録
stop VMしたVMをstart VMします。
$ incus start k8s2-vm
startしたVMインスタンスがRUNNINGになったことを確認します。
$ incus list | grep VIRTUAL
| k8s0-vm | RUNNING | 10.57.140.189 (enp5s0) | fdxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx (enp5s0) | VIRTUAL-MACHINE | 0 |
| k8s1-vm | RUNNING | 10.57.140.40 (enp5s0) | fdxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx (enp5s0) | VIRTUAL-MACHINE | 0 |
| k8s2-vm | RUNNING | 10.57.140.98 (enp5s0) | fdxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx (enp5s0) | VIRTUAL-MACHINE | 0 |
| k8s3-vm | RUNNING | 10.57.140.147 (enp5s0) | fdxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx (enp5s0) | VIRTUAL-MACHINE | 0 |
starしたVMノードがReadyになったことを確認します。
$ incus exec k8s0-vm -- microk8s kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s0-vm Ready <none> 2d14h v1.33.0
k8s1-vm Ready <none> 2d14h v1.33.0
k8s2-vm Ready <none> 2d14h v1.33.0
k8s3-vm Ready <none> 2d14h v1.33.0
startしたVMノードがStandby nodeになったことを確認します。
$ incus exec k8s0-vm -- microk8s status --wait-ready | grep -e "high-" -e "nodes"
high-availability: yes
datastore master nodes: 10.57.140.189:19001 10.57.140.40:19001 10.57.140.147:19001
datastore standby nodes: 10.57.140.98:19001
startしたVMノード(k8s2-vm)上に残っていたmicrobotの状態が消えたことを確認します。
$ incus exec k8s0-vm -- microk8s kubectl describe pod microbot | grep Node:
Node: k8s3-vm/10.57.140.147
検証2 Gracefulのケース
テスト項目2.1 クラスタからノード削除 (leave & remove-node)
テスト概要
- microbotサービスが動作しているVMノードをleave & remove-nodeする。
なお、leave後すぐremove-nodeせず5分以上経過させる。
期待する結果
- leaveにより、StandbyノードがMasterノードに昇格する。
- leaveにより、microbotサービスが別のVMノードで自動起動する。
(leave後)
テスト項目 | 期待する結果 | テスト結果 | |
---|---|---|---|
1 | microk8s kubectl get nodes | leaveしたVMノードがNotReadyになる。 | PASSED |
2 | microk8s status | Standby nodeがMaster nodeに昇格する。 | PASSED |
3 | microk8s kubectl describe pod microbot | leaveしたVMノード上のmicrobotが、別のReadyなVMノードで自動起動する。 | PASSED ※1 |
4 | microbot access via metallb | metallbのIPアドレスが変わらず、自動起動したmicrobotへアクセスできる。 | PASSED |
(remove-node後)
テスト項目 | 期待する結果 | テスト結果 | |
---|---|---|---|
5 | microk8s kubectl get nodes | remove-nodeしたVMノードがクラスタのノード一覧から消える。 | PASSED |
6 | microk8s kubectl describe pod microbot | remove-nodeしたVMノード上のmicrobot状態が消える。 | PASSED |
想定外の結果
※1 サービス復旧が遅い (microk8s kubectl describe pod microbot
による観測)
-
想定外1: サービスが別VMノード上で自動起動するまで5分程度かかる
これはmicrok8sの仕様どおりの挙動かもしれないが、5分程度もサービス障害が継続するとは想定していなかった。 -
想定外2: サービスが別VMノード上で自動起動した後も、microk8sの管理上、stopしたVMノード上のサービスが消されず状態が残り、状態のクリーンアップに手動操作が必要
残っていても実害なしだが、状態をクリーンアップするには手動操作でremove-nodeする必要がある。手動操作は想定していなかった。
テスト記録
microbotが動作しているVMノード(k8s3-vm)をleaveします。
なお、leaveは、leaveするVMノード上で実行する必要があります。
$ incus exec k8s3-vm -- microk8s leave
Generating new cluster certificates.
Waiting for node to start. .
leaveしたVMノードがNotReadyになったことを確認します。
$ incus exec k8s0-vm -- microk8s kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s0-vm Ready <none> 2d15h v1.33.0
k8s1-vm Ready <none> 2d14h v1.33.0
k8s2-vm Ready <none> 2d14h v1.33.0
k8s3-vm NotReady <none> 2d14h v1.33.0
Standby nodeがMaster nodeに昇格したことを確認します。
昇格の結果、Standby nodeはnone表示となります。
$ incus exec k8s0-vm -- microk8s status --wait-ready | grep -e "high-" -e "nodes"
high-availability: yes
datastore master nodes: 10.57.140.189:19001 10.57.140.40:19001 10.57.140.98:19001
datastore standby nodes: none
stopしたVMノード上のmicrobotが、別のReadyなVMノードで自動起動したことを確認します。
※想定外1: 自動起動に5分程度かかる。
※想定外2: 自動起動後も、stop VMしたノード上の状態が残る。
## leaveの直後
$ incus exec k8s0-vm -- microk8s kubectl describe pod microbot | grep Node:
Node: k8s3-vm/10.57.140.147
## leaveから約5分経過後
$ incus exec k8s0-vm -- microk8s kubectl describe pod microbot | grep Node:
Node: k8s2-vm/10.57.140.98
Node: k8s3-vm/10.57.140.147
metallbのIPアドレスが変わらず、自動起動したmicrobotへアクセスできることを確認します。
$ curl 10.57.140.201:80
<!DOCTYPE html>
<html>
<style type="text/css">
.centered
{
text-align:center;
margin-top:0px;
margin-bottom:0px;
padding:0px;
}
</style>
<body>
<p class="centered"><img src="microbot.png" alt="microbot"/></p>
<p class="centered">Container hostname: microbot-7d987d6fc6-cv4hq</p>
</body>
</html>
leaveしたVMノードをremove-nodeします。
$ incus exec k8s0-vm -- microk8s remove-node k8s3-vm
remove-nodeしたVMノードがクラスタのノード一覧から消えたことを確認します。
$ incus exec k8s0-vm -- microk8s kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s0-vm Ready <none> 2d15h v1.33.0
k8s1-vm Ready <none> 2d15h v1.33.0
k8s2-vm Ready <none> 2d15h v1.33.0
remove-nodeしたVMノードに残っていたmicrobotサービスの状態が消えたことを確認します。
※すぐには消えず、消えるのに3-5分程度かかります。
$ incus exec k8s0-vm -- microk8s kubectl describe pod microbot | grep Node:
Node: k8s2-vm/10.57.140.98
(補足) MasterとStandbyの状態はleaveした後の状態から変化しません。
$ incus exec k8s0-vm -- microk8s status --wait-ready | grep -e "high-" -e "nodes"
high-availability: yes
datastore master nodes: 10.57.140.189:19001 10.57.140.40:19001 10.57.140.98:19001
datastore standby nodes: none
検証の総括
検証する前にmicrok8sのドキュメント等から想定していた動作がおおむね確認できましたが、一部、想定外の挙動も確認できました。
特に、UngracefulのケースでHA状態がno/none/none表示になってしまった点は、リアルの運用を想定すると厳しいな、という印象です。
今後時間があれば、別のバージョン等で追試してみたいと思いますが、いったん以上です。
The previous document:
Incus VMでMicroK8sクラスタを組んでみた (1of2) 構築編
Discussion