三台のコントロールプレーンVMは、悪い夜を生き延びる三つの機会のように思えます。実際はそうではなく、この二つの信念の隔たりが、整った三ノード設計を、一つの建物が電源を失うと書き込みを受け付けなくなるクラスタへと変えます。拠点間のVPNリンクはマシン同士を到達可能にし、問題を直すのではなく隠します。票はetcdメンバーごとに数えられ、そのうち二つのメンバーは依然として一つのスイッチ、一つのUPS、一本のアップリンクの背後に置けます。

三台のコントロールプレーンノード、一つの障害ドメイン

kubectl get nodes を実行すると、コントロールプレーンのエントリが三つ見え、クラスタを高可用と記録します。その数はスケジュール可能な容量を表すもので、生存性ではありません。外部etcdを持たないkubeadmでは、各コントロールプレーンノードがメンバーもホストするため、三ノードは本当に三投票者になります。それらの投票者が独立に故障するかどうかは、ノード一覧では答えられない別の問いです。

一つのハイパーバイザー上の二台のVM、一つの電源系統上の二つのラック、一つのISPからの二本のアップリンク、つまり各ペアは二つのホスト名をまとった一つのドメインです。配置を書き出し、各投票者が何を共有しているかに印を付けます — ハイパーバイザー、PDU、ラック上部のスイッチ、ストレージアレイ、NAT装置、VPN集約装置。次に紙の上で共有物を一つずつ外し、残る票を数え直します。一台のホスト障害で二投票者を失うクラスタは、最初から一投票者のクラスタでした;誰もその問いをまだ投げていなかっただけです。

二拠点分割が耐えられることと耐えられないこと

三投票者を二拠点に二と一で置くと、他方の拠点が消えたとき大きい側はクォーラムを保ち、一投票者の側は決して保ちません。この非対称性は算術であり、調整ではありません。ちょうど二つの独立拠点に広がる多数決ベースのetcdクラスタは、「どちらの拠点を失ってもコミットを続ける」という試験に失敗します;両側が同時に過半数の票を持つ必要があるからです。

下の表は、実際にどの障害を買ったのかを最も速く見る方法です。各行はこう読みます:今夜この行全体が消えたら、生存者はまだ書き込みをコミットできるでしょうか。

What disappearsVoters leftWrites still commit
Site B, holding voter 32 of 3Yes
Site A, holding voters 1 and 21 of 3No
One hypervisor carrying any two voters1 of 3No
The inter-site VPN only2 of 3 on one sideOnly on the majority side

トンネルが決して票を増やさない理由

VPNはメンバーではなく輸送です。遠隔の投票者を到達可能にし、分断を遅いタイムアウトのように見えるものへ変えられます;クォーラムへの貢献はそれだけです。追加するのはコストです:すべてのコミットがリンクを渡る必要があり、etcdはraftログに触れる書き込みでその往復を払います。揺らぐ経路は複製を再試行と選挙に変えます。

分断は人が魔法を期待する場所なので、正確に語りましょう。古いリーダーが一投票者側にいるときにリンクが落ちると、その側はコミットできず、選挙タイムアウトが切れるとリーダーは退きます;一方、二投票者側は後任を選びます。障害モードのガイドは挙動を明快に説明しています:多数側ではサービスが続き、孤立した側には書き込み可能な第二のクラスタはない、と。

どの停止を買うのかを決める

二対一は、サイトAが主系で、それを失うと誰かが動くまでコントロールプレーンの書き込みを失うことを受け入れるなら、正当な設計です。それを欠陥に変えるのは、その決定を暗黙のままにすることです。runbookに書きましょう:コントロールプレーンがどちらの拠点で生き残るのか、もう一方の拠点が03:00に落ちたとき運用者が何をするのかを。

要件が代わりに「どちらの拠点が落ちてもよい」なら、配置は各拠点で過半数を保つ必要があり、二拠点に三投票者ではそれはできません。本当に独立した第三のドメインを足す — 別プロバイダの小さいリージョンはそこへの経路が安定していれば機能します — か、別々のetcdを持つ二クラスタに分かれてその分割の運用コストを受け入れるかです。証人による近道はこれを避けられません:etcdには軽量な仲裁メンバーがないため、第三の投票者は独自のディスク、メモリ、ネットワーク要求を持つ完全なメンバーです。図に「証人」と書いた箱を描いても証人は生まれません。

クォーラムはサービスと同じではない

etcdのクォーラムはAPIサーバーが書き込みを受け付けられる状態を保つだけで、保つのはそれだけです。ロードバランサーのヘルスチェック、イングレス、トンネル越しのCNI到達性、ボリューム接続ゾーン、アプリの複製はそれぞれ別の答えを必要とします。クラスタがきれいな過半数を持っていても、利用者に有用なものを何も提供できないことがあります。

次に、図はずれるので、あると思っているメンバー構成を確認してください:

kubectl -n kube-system get pods -l component=etcd -o wide
kubectl get endpoints kube-apiserver -n default
etcdctl member list -w table

メンバー一覧を配置図と比べてください。二つのメンバーが同じホストや同じラックに解決するなら、間違っているのはクラスタではなく図であり、誤ったトポロジーの周りでサイズを変えても同じ停止の高くつく版を買うだけです。

三投票者の設計を承認する前に、四つの問いに答えてください:何台の投票者が同時に電源を失うか、どの拠点の喪失ならまだ過半数が残るか、トンネルが落ちたときリーダーはどこにいるか、生き残った拠点はまだ何ができるか。「確信がない」がどれか一つでもあれば、そのクラスタはまだ高可用ではありません。それは幸運だった三台のマシンです。

関連記事