不揮発性メモリエクスプレス (NVMe) プロトコルをサポートするエンタープライズSSD (ESSD) は、NVMeディスクと呼ばれます。 NVMeディスクはマルチアタッチ機能をサポートしています。 この機能を使用すると、最大16個のElastic Compute Service (ECS) インスタンスにNVMeディスクを接続し、さらにNVMe仕様に準拠したNVMe予約機能を使用できます。 これらの機能により、アプリケーションのポッドを実行するすべてのノード間でのデータ共有が容易になり、データの読み書きパフォーマンスが向上します。 このトピックでは、Container Service for Kubernetes (ACK) クラスターでNVMeディスクのマルチアタッチおよびNVMe予約機能を使用する方法について説明します。
始める前に
NVMeディスクのマルチアタッチ機能とNVMe予約機能をより有効に活用するために、このトピックを読む前に次の内容を理解することをお勧めします。
シナリオ
マルチアタッチ機能は、次のシナリオに適しています。
制限事項
1つのNVMeディスクを、同じゾーンにある最大16のECSインスタンスに接続できます。
マルチアタッチ機能を使用する場合、ACKではvolumeDevicesメソッドを使用してのみNVMeディスクをアタッチできます。 この場合、複数のノード上のディスクからデータを読み書きできますが、ファイルシステムからディスクにアクセスすることはできません。
詳細については、「マルチアタッチの有効化」トピックの制限セクションを参照してください。
前提条件
Kubernetes 1.20以降を実行するACKマネージドクラスターが作成されます。 詳細については、「ACK管理クラスターの作成」をご参照ください。
V1.24.10-7ae4421-aliyun以降のcsi-pluginおよびcsi-provisionerコンポーネントがインストールされます。 csi-pluginおよびcsi-provisionerコンポーネントを更新する方法の詳細については、「CSIプラグインの管理」をご参照ください。
ACKクラスタは、同じゾーンに存在し、マルチアタッチ機能をサポートする少なくとも2つのノードを含む。 マルチアタッチ機能をサポートするインスタンスファミリーの詳細については、「マルチアタッチの有効化」トピックの制限セクションをご参照ください。
以下の要件を満たすアプリケーションを用意する。 アプリケーションは、ACKクラスターにデプロイするためにコンテナイメージにパッケージ化されます。
アプリケーションは、複数のレプリケートされたポッドからディスク上のデータへの同時アクセスをサポートします。
アプリケーションは、NVMe予約機能などの標準機能を使用して、データの一貫性を確保できます。
課金
NVMeディスクのマルチアタッチ機能は無料です。 個々の課金方法に基づいて、NVMeをサポートするリソースに対して課金されます。 ディスク課金の詳細については、「課金」をご参照ください。
サンプル申請
この例では、次のソースコードとDockerfileを使用してサンプルアプリケーションを開発します。 ソースコードとDockerfileはイメージリポジトリにアップロードされ、その後クラスターにデプロイされます。 複数のレプリケートされたポッドが共同でコンテナリースを管理しますが、リースをマスターするポッドは1つだけです。 コンテナリースをマスターするポッドが期待どおりに実行できない場合、他のポッドが自動的にこのリースを先取りします。 サンプルアプリケーションを開発するときは、次の項目に注意してください。
サンプルアプリケーションでは、
O_DIRECT
を使用してブロックストレージデバイスを開き、読み取りおよび書き込み操作を実行します。 これにより、この例のテストがキャッシュの影響を受けないようにします。サンプルアプリケーションでは、Linuxカーネルが提供する簡易予約用のインターフェイスを使用しています。 次のいずれかの方法を使用して、NVMe予約コマンドを実行することもできます。 この場合、コンテナに必要な権限を付与する必要があります。
C:
ioctl(fd、NVME_IOCTL_IO_CMD、&cmd);
コマンドラインツール:
nvme-cli
NVMe予約機能の詳細については、「NVMe仕様」をご参照ください。
手順1: アプリケーションのデプロイとマルチアタッチの設定
alicloud-disk-sharedという名前のStorageClassを作成し、NVMeディスクのマルチアタッチ機能を有効にします。
data-diskという名前の永続ボリュームクレーム (PVC) を作成し、accessModes
パラメーターをReadWriteMany
に設定し、volumeMode
パラメーターをBlock
に設定します。
この例のサンプルアプリケーションのイメージを使用して、リーステストという名前のStatefulSetを作成します。
次のコンテンツを含むlease.yamlファイルを作成します。
次のYAMLファイルのコンテナイメージURLをアプリケーションのイメージURLに置き換えます。
重要NVMe予約機能はノードで有効になります。 同じノード上の複数のポッドが互いに干渉する可能性があります。 この例では、
podAntiAffinity
設定は、複数のポッドが同じノードにスケジュールされないように設定されています。クラスターにNVMeプロトコルを使用しない他のノードが含まれている場合は、nodeAffinity設定を構成して、NVMeプロトコルを使用するノードにポッドをスケジュールする必要があります。
パラメータまたは設定
マルチアタッチ機能の設定
通常のアタッチ機能の設定
StorageClass
パラメータ. multiAttach
true: NVMeディスクのマルチアタッチ機能を有効にします。
設定は必要ありません。
PVC
accessModes
ReadWriteMany
ReadWriteOnce
volumeMode
ブロック
ファイルシステム
ボリューム接続方法
volumeDevices: ブロックストレージデバイスを使用してディスク上のデータにアクセスします。
volumeMounts: ファイルシステムのボリュームをアタッチします。
次のコマンドを実行して、アプリケーションをデプロイします。
kubectl apply -f lease.yaml
ステップ2: マルチアタッチ機能とNVMe予約機能を確認する
NVMeクラウドディスクのデータの一貫性を確保するために、予約機能を使用して、アプリケーションの読み取りおよび書き込み権限を制御できます。 1つのポッドが書き込み操作を実行している場合、他のポッドは読み取り操作のみを実行できます。
複数のノードのディスクからのデータの読み取りとディスクへのデータの書き込み
次のコマンドを実行して、ポッドログを照会します。
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予約を取得したかどうかを確認する
次のコマンドを実行して、ディスクIDを照会します。
kubectl get pvc data-disk -ojsonpath='{.spec.volumeName}'
2つのノードのいずれかにログインし、次のコマンドを実行して、NVMe予約が取得されているかどうかを確認します。
次のコードの
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予約が取得されることを示す。
NVMe予約機能を使用した異常なノードでの書き込み操作のブロック
Pod lease-test-0が存在するノードにログインし、次のコマンドを実行して、障害シミュレーションのプロセスを一時停止します。
pkill -STOP -f /usr/local/bin/lease
30秒待ってから次のコマンドを実行し、ポッドログを照会します。
kubectl logs -l app=lease-test --prefix -f
期待される結果
[pod/lease-test-1/lease] Remote lease-test-0 refreshed lease [pod/lease-test-1/lease] Remote is dead, preempting [pod/lease-test-1/lease] Register as key 4745d0c5cd9a2fa4 [pod/lease-test-1/lease] Refreshed lease [pod/lease-test-1/lease] Refreshed lease [pod/lease-test-1/lease] Refreshed lease
予想される結果は、ポッドのリーステスト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がディスクにデータを書き込むことができなくなり、コンテナリースが自動的に再開されることを示しています。 これは、ポッドリーステスト0の書き込み操作がNVMe予約機能によってブロックされていることを示しています。
関連ドキュメント
NVMeディスクに十分な容量がない場合は、「ディスクボリュームの拡張」をご参照ください。