Confluent の複数アベイラビリティゾーンのデプロイ¶
Confluent for Kubernetes は、Kubernetes における Confluent コンポーネントのデプロイ、管理、運用を支援します。
パブリッククラウドにおける Kubernetes 製品の多くは、Kubernetes クラスターが複数のアベイラビリティゾーン(マルチ AZ)に分散されるリージョナルな構成での実行をサポートしています。
このトピックでは、マルチ AZ デプロイにおける Confluent for Kubernetes の動作と慣例について説明します。
このトピックの例では、現在の名前空間を設定するものとし、明示的には名前空間を指定していないので注意してください。
Confluent for Kubernetes は、複数の AZ に Confluent for Kubernetes をデプロイするだけでなく、ラックが AZ である場合にラック認識機能に対応するよう構成できます。ラック認識機能を使用すれば、Kafka のパーティションレプリカを複数の AZ に配置して、AZ の障害イベントで失われるデータを最小にできます。ラック認識機能を構成する方法については、AZ のチュートリアルの、ラック認識機能の構成に関する説明 を参照してください。
マルチ AZ Kubernetes¶
マルチ AZ Kubernetes では、Kubernetes ワーカーノードが複数の AZ に分散されます。それぞれのノードには、その存在場所であるリージョンのラベルが付けられます。AZ ラベルを調べるには、次のコマンドを実行します。
kubectl get nodes --show-labels
前述のコマンドからの出力には、failure-domain.beta.kubernetes.io/zone
という AZ ラベルが含まれます。以下に例を示します。
failure-domain.beta.kubernetes.io/zone=us-central1-f
ワーカーノードによって使用されるストレージには、どの AZ からでもアクセスできます。
Confluent ポッドのスケジューリング¶
Confluent コンポーネントのインスタンスポッドは、AZ 全体にラウンドロビン方式でスケジューリングされます。
たとえば、6 つの Kafka ブローカーを 3 つの AZ(各 AZ に 2 つのワーカーノード)に対してスケジューリングした場合、最終的にそれぞれの AZ の Kafka ブローカー数は 2 つとなります。
その AZ のリソースキャパシティまたはワーカーキャパシティが十分ではない場合は、キャパシティがあるゾーン内のいずれかのワーカーにポッドがスケジューリングされます。
たとえば、次のワーカーノードが分散配置されている Kubernetes クラスターがあるとします。
- ワーカー×4(AZ 1)
- ワーカー×1(AZ 2)
- ワーカー×4(AZ 3)
6 つの Kafka ブローカーをスケジューリングした場合、ポッドは次のいずれかとしてスケジューリングされます。
- ブローカーポッド×2(AZ 1)、ブローカーポッド×1(AZ 2)、ブローカーポッド×3(AZ 3)
- ブローカーポッド×3(AZ 1)、ブローカーポッド×1(AZ 2)、ブローカーポッド×2(AZ 3)
デプロイ後は、次のようにして、ポッドのスケジューリング先ノードを調べることができます。
ポッドのノード名を取得します。
kubectl get pods -o wide
それぞれのノードについて、その
failure-domain.beta.kubernetes.io/zone
ラベルに着目し、そのノードが属している AZ を調べます。kubectl get nodes --show-labels | grep <node_name>
ストレージのスケジューリング¶
Confluent for Kubernetes では、各コンポーネントのストレージニーズに対して永続ボリュームが使用されます。ほとんどのクラウドプロバイダーでは、永続ボリュームのストレージメカニズムが AZ に対応していますが、AZ の境界を越えて永続ボリュームにアクセスしたり永続ボリュームを移動したりすることはできません。したがって特定の AZ にスケジューリングされたポッドの永続ボリュームは、同じ AZ に存在する必要があります。
CFK では、複数の AZ に分散された Kubernetes クラスター上のストレージクラスが遅延バインドであることが必要です。ご使用のストレージクラスの volumeBindingMode
が WaitForFirstConsumer
に設定されていることを確認してください。この場合、PersistentVolumeClaim を使用するポッドが作成されるまで、PersistentVolume のバインドとプロビジョニングが先延ばしされます。PersistentVolume は、ポッドのスケジューリング制約で指定されたトポロジーに従って選択またはプロビジョニングされます。
次のコマンドを使用してストレージクラスのバインディングモードを調べます。
kubectl describe sc <your_storage_class>
出力を見ると、次のように、VolumeBindingMode
が WaitForFirstConsumer
に設定されているはずです。
Name: <your_storage_class>
...
VolumeBindingMode: WaitForFirstConsumer
...
デプロイ後に、永続ボリュームの割り当て先の AZ を確認することができます。以下に例を示します。
kubectl describe pv pvc-008a81fd-cd28-4b3e-a26f-5fe9384476f9
上記コマンドのサンプル出力を見ると、永続ボリュームが us-central1-a
ゾーンにマウントされていることがわかります。
Name: pvc-008a81fd-cd28-4b3e-a26f-5fe9384476f9
Labels: failure-domain.beta.kubernetes.io/region=us-central1
failure-domain.beta.kubernetes.io/zone=us-central1-a
シナリオ: ワーカーの障害¶
単一の Kubernetes ワーカーノードで障害が発生すると、そのワーカーノードのポッドが消えます。
この場合、Confluent ポッドは、CFK によって、必要なリソースキャパシティを備えた、同じ AZ 内の別の Kubernetes ワーカーにスケジューリングされ、同じ永続ボリュームに接続されます。
必要なリソースキャパシティを備えた利用可能なワーカーノードが存在しない場合、ポッドはスケジューリングされず、保留状態となります。
そのゾーンのリソースキャパシティが利用可能な状態になったとき、ポッドはスケジューリングされます。
注釈
Confluent for Kubernetes では、oneReplicaPerNode の機能を使用して、同じ Kubernetes ワーカーノードに複数の Kafka ブローカーが併置されるのを回避しています。これは ZooKeeper サーバーについても同様です。そのため、Kafka と ZooKeeper を収容できるだけの Kubernetes ワーカーノードを確保する必要があります。
シナリオ: AZ の障害¶
AZ 全体の障害が発生すると、その AZ にある Kubernetes ワーカーノードがすべて利用できなくなります。ストレージの回復性は AZ の範囲に限定されるため、ストレージも利用できなくなります。
このケースでは、ポッドと永続ボリュームは利用できず、それらを自動的に起動することはできません。これらは保留状態となります。
この問題の解決には 2 つのパスがあります。つまり、AZ が利用可能な状態になるまで待つか、ポッドを別の AZ にスケジューリングします。
AZ が利用可能な状態になるまで待つ¶
AZ が利用可能な状態になるまで待つ場合、AZ が回復するまで、その AZ 内の特定のポッドは保留状態となります。AZ が復旧すると、それらのポッドも稼動状態となります。
このケースでは、万一 AZ がダウンしても動作するだけの十分なブローカーキャパシティが存在することを確認してください。1 つの AZ に障害が発生したときに利用できるブローカーの数とかみ合うように、レプリケーション係数と ISR(In-Sync Replicas: 同期レプリカ)が設定されている必要があります。
Confluent ポッドを別の AZ にスケジューリングする¶
このパスでは、Kafka ブローカーポッドが読み取り/書き込みリクエストの受け付けを開始できるのは、そのポッドが新しいストレージで起動し、他のブローカーからパーティションをレプリケートした後となります。
以下のコマンド例では、Kafka クラスター名として kafka
を使用しています。
異なる AZ にポッドをスケジューリングするには、次の手順に従います。
リソースのリコンサイルのアップデートを一時的に停止するよう CFK を設定します。
kubectl annotate kafka kafka platform.confluent.io/block-reconcile=true
永続ボリュームクレーム(pvc)を削除します。
pvc には "data0-<clustername>-0" という名前が付いています。
たとえば、障害が発生した AZ 上のポッドが "kafka-0" で、Kafka クラスターの名前が
kafka
である場合、コマンドは次のようになります。kubectl patch pvc data0-kafka-0 \ -p '{"metadata":{"finalizers":[]}}' \ --type=merge \ | kubectl delete pvc data0-kafka-0
障害のある AZ に関連付けられていたポッドを削除します。
kubectl delete pod kafka-0 --grace-period=0 --force
リソースのリコンサイルを再度有効にして、リコンサイルをトリガーします。これにより、利用可能な AZ 上でポッドがスケジューリングされます。
kubectl annotate kafka kafka platform.confluent.io/block-reconcile-