複数のノードが同じクラウドディスクに同時に読み書きして、効率的なデータ共有と高速なフェイルオーバーを実現する必要がある場合、マルチアタッチ機能を使用して、単一の ESSD、ESSD AutoPL、または他のタイプのクラウドディスクを同じゾーン内の NVMe プロトコルをサポートする複数のノードにアタッチしたり、単一のゾーン冗長ストレージ ESSD を同じリージョン内の複数のノードにアタッチしたりできます。このトピックでは、ACK クラスターで NVMe クラウドディスクのマルチアタッチと Reservation 機能を使用する方法を説明します。
始める前に
NVMe クラウドディスクのマルチアタッチと Reservation 機能をより良く使用するために、このドキュメントを読む前に以下の情報を理解することをお勧めします。
NVMe プロトコルに関する詳細については、「NVMe プロトコルの概要」をご参照ください。
クラウドディスクのマルチアタッチ機能とその制限に関する詳細については、「クラウドディスクのマルチアタッチ機能」をご参照ください。
シナリオ
マルチアタッチ機能は、以下のシナリオに適しています。
制限事項
単一の NVMe クラウドディスクは、同じゾーン内の最大 16 個の ECS インスタンスに同時にアタッチできます。
複数のノードからクラウドディスクに同時に読み書きする場合は、volumeDevices を使用してクラウドディスクをマウントする必要があります。このメソッドは、クラウドディスクをブロックデバイスとしてマウントし、ファイルシステムを介したアクセスをサポートしません。
制限事項の詳細については、「マルチアタッチ機能の制限事項」をご参照ください。
準備
ACK マネージドクラスターが作成され、クラスターの Kubernetes バージョンが 1.20 以降です。詳細については、「ACK マネージドクラスターの作成」をご参照ください。
csi-plugin および csi-provisioner コンポーネントがインストールされており、コンポーネントのバージョンは v1.24.10-7ae4421-aliyun 以降です。csi-plugin および csi-provisioner コンポーネントのアップグレード方法の詳細については、「csi-plugin および csi-provisioner コンポーネントの管理」をご参照ください。
クラスターには、同じゾーンにあり、マルチアタッチ機能をサポートする少なくとも 2 つのノードが含まれています。マルチアタッチ機能をサポートするインスタンスファミリーの詳細については、「マルチアタッチ機能の制限事項」をご参照ください。
以下の要件を満たすビジネスアプリケーションが準備され、ACK クラスターにデプロイするためにコンテナイメージにパッケージ化されています。
アプリケーションは、複数のレプリカから同じクラウドディスク上のデータに同時にアクセスすることをサポートします。
アプリケーションは、NVMe Reservation などの標準機能を使用してデータ整合性を確保できます。
課金に関する説明
マルチアタッチ機能に追加料金は発生しません。NVMe プロトコルをサポートするリソースは、引き続き元の課金方法に基づいて課金されます。クラウドディスクの課金の詳細については、「Elastic Block Storage ボリューム」をご参照ください。
アプリケーション例
このトピックでは、次のアプリケーション例のソースコードと Dockerfile を使用します。アプリケーションがビルドされた後、クラスターにデプロイするためにイメージリポジトリにアップロードします。このアプリケーション例では、複数のレプリカが共同でリースを管理しますが、リースを保持するのは 1 つのレプリカのみです。レプリカが正常に動作しない場合、他のレプリカが自動的にリースを引き継ぎます。アプリケーションを作成する際には、次の点に注意してください。
この例では、テストに影響を与えるキャッシュを防ぐために、ブロックデバイスを読み書き用に開くために
O_DIRECTが使用されます。この例では、Linux カーネルが提供する Reservation の簡略化されたインターフェイスが使用されます。また、次のいずれかの方法を使用して、Reservation 関連のコマンドを実行することもできます。これらの方法には権限が必要です。
C コード:
ioctl(fd, NVME_IOCTL_IO_CMD, &cmd);コマンドラインインターフェイス:
nvme-cli
NVMe Reservation 機能の詳細については、「NVMe Specification」をご参照ください。
ステップ 1: アプリケーションをデプロイし、マルチアタッチ機能を設定する
alicloud-disk-shared という名前の StorageClass を作成し、クラウドディスクのマルチアタッチ機能を有効にします。
data-disk という名前の PVC を作成し、accessModes を ReadWriteMany に、volumeMode を Block に設定します。
lease-test という名前の StatefulSet アプリケーションを作成し、このトピックのアプリケーション例のイメージを使用します。
次の内容で lease.yaml ファイルを作成します。
次の YAML のコンテナイメージアドレスを、アプリケーションの実際のイメージアドレスに置き換えてください。
重要NVMe Reservation はノードレベルで有効になるため、同じノード上の複数の Pod が互いに干渉する可能性があります。したがって、この例では
podAntiAffinityを使用して、複数の Pod が同じノードにスケジュールされるのを防ぎます。クラスターに NVMe プロトコルを使用しない他のノードが含まれている場合は、アフィニティを設定して、Pod が NVMe プロトコルを使用するノードにスケジュールされるようにする必要があります。
パラメーター
マルチアタッチ機能の設定説明
通常のマウントの設定説明
StorageClass
parameters.multiAttach
true に設定して、クラウドディスクのマルチアタッチ機能を有効にします。
設定不要
PVC
accessModes
ReadWriteMany
ReadWriteOnce
volumeMode
Block
Filesystem
ストレージボリュームのマウント方法
volumeDevices: ブロックデバイスを介してクラウドディスク上のデータに直接アクセスします。
volumeMounts: 主にファイルシステムタイプのボリュームをマウントするために使用されます。
次のコマンドを実行してアプリケーションをデプロイします。
kubectl apply -f lease.yaml
ステップ 2: マルチアタッチと Reservation の効果を検証する
NVMe クラウドディスク上のデータ整合性を確保するために、アプリケーションで Reservation を介して読み書き権限を制御できます。1 つの Pod が書き込み操作を実行する場合、他の Pod は読み取り操作のみを実行できます。
複数のノードが同じクラウドディスクに読み書きできる
次のコマンドを実行して Pod のログを表示します。
kubectl logs -l app=lease-test --prefix -f期待される結果:
[pod/lease-test-0/lease] Register as key 4745d0c5cd9a2fa4
[pod/lease-test-0/lease] Refreshed lease
[pod/lease-test-0/lease] Refreshed lease
[pod/lease-test-1/lease] Remote lease-test-0 refreshed lease
[pod/lease-test-0/lease] Refreshed lease
[pod/lease-test-1/lease] Remote lease-test-0 refreshed lease
[pod/lease-test-0/lease] Refreshed lease
[pod/lease-test-1/lease] Remote lease-test-0 refreshed lease
[pod/lease-test-0/lease] Refreshed lease
[pod/lease-test-1/lease] Remote lease-test-0 refreshed lease期待される結果は、Pod lease-test-1 が Pod lease-test-0 によって書き込まれたコンテンツをすぐに読み取れることを示しています。
NVMe Reservation が正常に作成された
次のコマンドを実行してクラウドディスク ID を取得します。
kubectl get pvc data-disk -ojsonpath='{.spec.volumeName}'2 つのノードのいずれかにログインし、次のコマンドを実行して NVMe Reservation が正常に作成されたかどうかを確認します。
次のコードの
2zxxxxxxxxxxxを、前のステップで取得したクラウドディスク ID のd-の後の内容に置き換えます。nvme resv-report -c 1 /dev/disk/by-id/nvme-Alibaba_Cloud_Elastic_Block_Storage_2zxxxxxxxxxxx期待される結果:
NVME Reservation status: gen : 3 rtype : 1 regctl : 1 ptpls : 1 regctlext[0] : cntlid : ffff rcsts : 1 rkey : 4745d0c5cd9a2fa4 hostid : 4297c540000daf4a4*****期待される結果は、NVMe Reservation が正常に作成されたことを示しています。
Reservation は異常なノードからの書き込み I/O 操作をブロックできる
Pod lease-test-0 があるノードにログインし、次のコマンドを実行してプロセスを一時停止し、障害シナリオをシミュレートします。
pkill -STOP -f /usr/local/bin/lease30 秒待ってから、次のコマンドを再度実行してログを表示します。
kubectl logs -l app=lease-test --prefix -f期待される結果:
[pod/lease-test-1/lease] リモートの lease-test-0 がリースをリフレッシュしました [pod/lease-test-1/lease] リモートは停止しており、プリエンプトしています [pod/lease-test-1/lease] キー 4745d0c5cd9a2fa4 として登録しました [pod/lease-test-1/lease] リースをリフレッシュしました [pod/lease-test-1/lease] リースをリフレッシュしました [pod/lease-test-1/lease] リースをリフレッシュしました期待される結果は、Pod lease-test-1 がサービスのプライマリノードとしてリースを引き継ぎ、保持していることを示しています。
Pod lease-test-0 があるノードに再度ログインし、次のコマンドを実行して一時停止したプロセスを再開します。
pkill -CONT -f /usr/local/bin/lease次のコマンドを再度実行してログを表示します。
kubectl logs -l app=lease-test --prefix -f期待される結果:
[pod/lease-test-0/lease] failed to write lease: Invalid exchange期待される結果は、Pod lease-test-0 がクラウドディスクに書き込むことができなくなり、リースコンテナが自動的に再起動することを示しています。これは、書き込み I/O 操作が Reservation によって正常にブロックされたことを示しています。
関連ドキュメント
NVMe クラウドディスクの容量が不足しているか、いっぱいになっている場合は、「クラウドディスクボリュームの拡張」をご参照ください。