storage-operator アドオンは、StatefulSet のゾーン間ディスク移行とマルチゾーンへの分散を自動化します。移行中にエラーが発生した場合、アドオンは事前チェックとロールバックを通じて元のゾーンでアプリケーションを復元し、サービスの可用性を確保します。
利用シーン
| シナリオ | 説明 |
|---|---|
| ゾーン計画の変更 | インフラストラクチャやキャパシティの更新に伴い、ワークロードを別のゾーンに移動します。 |
| マルチゾーンへの分散 | レプリカとそのディスクを複数のゾーンに分散させ、可用性を向上させます。 |
| リソースの制約 | 現在のゾーンのキャパシティが不足し、継続的な運用やスケールアウトが困難な場合。 |
NAS と OSS はゾーン間の利用とマルチマウントをサポートしています。ディスクはゾーンに紐付けられており、ゾーンをまたいで移動したり、既存の永続ボリューム要求 (PVC) や永続ボリューム (PV) を再利用したりすることはできません。スナップショットからターゲットゾーンに新しいディスクを作成する必要があります。
主な制約
移行前に、以下の制約を確認してください:
-
業務の中断が必要: データ整合性を確保するため、移行では StatefulSet のレプリカ数を 0 にスケールダウンし、ディスク移行後にすべてのレプリカを一度に復元します。これはローリングアップデートではありません。ダウンタイムを計画してください。所要時間は、レプリカ数、コンテナの起動時間、ディスク容量によって異なります。
-
ESSD ディスクが必須: StatefulSet で使用されるすべてのストレージは ESSD ディスクである必要があります。移行では高速スナップショット機能を使用しますが、この機能は ESSD ディスクのみをサポートしています。
-
ターゲットゾーンの要件: ターゲットゾーンが ESSD ディスクをサポートしており、クラスター内にスケジューリング可能なノードがそのゾーンに存在する必要があります。
アプリケーションが ESSD 以外のディスクを使用している場合は、移行前に以下のいずれかの操作を実行してください:
-
手動で単一のディスクボリュームのスナップショットを作成し、ゾーンをまたいでディスクを再構築する。
仕組み
クロスゾーン移行は、ソースディスクのスナップショットを作成し、インスタントアクセスを使用して作成時間を最小化します。 詳細については、「スナップショットの課金」をご参照ください。
storage-operator は以下の手順を実行します:
-
事前チェック: アプリケーションが実行中であることを確認し、移行対象のディスクを特定します。事前チェックに失敗した場合は停止します。
-
ゼロへのスケールダウン: StatefulSet のレプリカ数を 0 にスケールダウンし、アプリケーションを一時停止します。
-
スナップショットの作成: マウントされているすべてのディスクに対して高速スナップショットを作成します。スナップショットはゾーンに依存しません。
-
新しいディスクのプロビジョニング: スナップショットが利用可能になったことを確認後、同じデータを持つ新しいディスクをターゲットゾーンに作成します。
-
PVC と PV の再構築: 同じ名前の PVC と、それに対応する PV を再構築し、新しいディスクにバインドします。
-
レプリカの復元: 元のレプリカ数に復元します。レプリカは再構築された PVC にバインドされ、新しいディスクをマウントします。
-
(オプション) 元のリソースの削除: アプリケーションの正常性を確認した後、元の PV とディスクを削除します。詳細については、「ブロックストレージの課金」をご参照ください。
事前チェック後の各ステップには、ロールバック戦略が用意されています。移行後に StatefulSet が正しく動作することを確認してから、元のディスクを削除してください。これにより、ロールバックが必要になった場合に、アプリケーションが元のディスクを再マウントできるようになります。
前提条件
以下を確認してください:
-
Kubernetes 1.20 以降を実行し、Container Storage Interface (CSI) ドライバーがインストールされているクラスター
-
storage-operator v1.26.2-1de13b6-aliyun 以降がインストールされていること
-
csi-plugin と csi-provisioner がインストールされており、csi-provisioner が非マネージド版を使用していること
マネージド版がインストールされている場合は、非マネージド版に切り替えてください。その後、ストレージコントローラを再起動します:
kubectl delete pod -n kube-system <storage-controller-pod-name> -
(ACK 専用クラスターのみ) ワーカー RAM ロールとマスター RAM ロールは、ECS API に対する
ModifyDiskSpec権限を持ちます。詳細については、「カスタムポリシーの作成」をご参照ください。必須の RAM ポリシーは次のとおりです:ACK マネージドクラスターでは
ModifyDiskSpec権限は不要です。{ "Version": "1", "Statement": [ { "Effect": "Allow", "Action": [ "ecs:CreateSnapshot", "ecs:DescribeSnapshot", "ecs:DeleteSnapshot", "ecs:ModifyDiskSpec", "ecs:DescribeTaskAttribute" ], "Resource": "*" } ] }</details>
StatefulSet のゾーン間移行
ステップ 2:移行タスクを作成する
ContainerStorageOperator リソースを作成します:
cat <<EOF | kubectl apply -f -
apiVersion: storage.alibabacloud.com/v1beta1
kind: ContainerStorageOperator
metadata:
name: default
spec:
operationType: APPMIGRATE
operationParams:
stsName: web
stsNamespace: default
stsType: kube
targetZone: cn-beijing-h,cn-beijing-j
checkWaitingMinutes: "1"
healthDurationMinutes: "1"
snapshotRetentionDays: "2"
retainSourcePV: "true"
EOF
パラメーター:
| パラメーター | 必須 | デフォルト値 | 説明 |
|---|---|---|---|
operationType |
必須 | — | ステートフルアプリケーションの移行には APPMIGRATE を設定します。 |
stsName |
必須 | — | 移行する StatefulSet の名前。タスクごとに 1 つの StatefulSet のみ指定できます。複数のタスクはデプロイ順に逐次実行されます。 |
stsNamespace |
必須 | — | StatefulSet の名前空間。 |
targetZone |
必須 | — | カンマ区切りのターゲットゾーン。例:cn-beijing-h,cn-beijing-j。すでに指定されたゾーンにあるディスクはスキップされます。複数のゾーンを指定した場合、残りのディスクはリストの順序で分散されます。 |
stsType |
任意 | kube |
StatefulSet のタイプ。有効な値:kube (ネイティブ) および kruise (OpenKruise Advanced StatefulSet)。 |
checkWaitingMinutes |
任意 | "1" |
移行後のレプリカの可用性チェックのポーリング間隔 (分)。大規模な StatefulSet や起動が遅い場合は、早すぎるロールバックを避けるために値を増やしてください。 |
healthDurationMinutes |
任意 | "0" |
レプリカが期待される数に達してから、二次的なヘルスチェックを行うまでの待機時間 (分)。"0" に設定するとスキップされます。 |
snapshotRetentionDays |
任意 | "1" |
高速スナップショットの保持期間。有効な値:"1" (1 日) および "-1" (永久)。 |
retainSourcePV |
任意 | "false" |
移行後に元のディスクと PV を保持するかどうか。"false" は両方を削除します。"true" はそれらを保持します。ディスクは ECS コンソールに残り、PV は Released 状態になります。 |
例
以下の例では、3 つのゾーンにノードを持つ ACK Pro クラスターを使用します:
-
ゾーン B: cn-shanghai.192.168.5.245
-
ゾーン G: cn-shanghai.192.168.2.214
-
ゾーン M: cn-shanghai.192.168.3.236, cn-shanghai.192.168.3.237
ステップ 1:ESSD ディスクを持つ StatefulSet を作成する
ESSD ディスクを持つテスト用の StatefulSet を作成します。移行対象の StatefulSet がすでにある場合は、このステップをスキップしてください。
-
StatefulSet をデプロイします。Nginx StatefulSet の YAML は以下の通りです:
cat << EOF | kubectl apply -f - apiVersion: apps/v1 kind: StatefulSet metadata: name: web spec: selector: matchLabels: app: nginx serviceName: "nginx" replicas: 2 template: metadata: labels: app: nginx spec: containers: - name: nginx image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6 ports: - containerPort: 80 name: web volumeMounts: - name: www mountPath: /usr/share/nginx/html volumeClaimTemplates: - metadata: name: www labels: app: nginx spec: accessModes: [ "ReadWriteOnce" ] storageClassName: "alicloud-disk-essd" resources: requests: storage: 20Gi EOF</details>
-
両方の Pod が実行中であることを確認します:
kubectl get pod -o wide -l app=nginx出力は、両方の Pod がゾーン M にスケジュールされていることを示しています (実際の配置はスケジューラに依存します):
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES web-0 1/1 Running 0 2m 192.168.3.243 cn-shanghai.192.168.3.237 <none> <none> web-1 1/1 Running 0 2m 192.168.3.246 cn-shanghai.192.168.3.236 <none> <none>
ステップ 2:移行タスクを作成する
例 1:ゾーン間移行
すべての Pod を単一のターゲットゾーン (この例ではゾーン B) に移行します。
ターゲットゾーンに十分なノードリソースがあり、ESSD ディスクをサポートしていることを確認してください。
-
移行タスクを作成します:
cat <<EOF | kubectl apply -f - apiVersion: storage.alibabacloud.com/v1beta1 kind: ContainerStorageOperator metadata: name: migrate-to-b spec: operationType: APPMIGRATE operationParams: stsName: web stsNamespace: default stsType: kube targetZone: cn-shanghai-b # 移行先のターゲットゾーン healthDurationMinutes: "1" # 移行後 1 分間待機し、アプリケーションが正常に動作していることを確認します snapshotRetentionDays: "-1" # スナップショットを手動で削除するまで永久に保持します retainSourcePV: "true" # 元のディスクと PV を保持します EOF -
移行ステータスを確認します:
ステータスが
FAILEDの場合は、「よくある質問」を参照してトラブルシューティングを行ってください。kubectl describe cso migrate-to-b | grep StatusSUCCESSステータスは、移行が完了したことを示します:Status: Status: SUCCESS -
移行後の Pod の配置を確認します:
kubectl get pod -o wide -l app=nginx両方の Pod は、ゾーン B の
cn-shanghai.192.168.5.245ノード上にあります:NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES web-0 1/1 Running 0 2m36s 192.168.5.250 cn-shanghai.192.168.5.245 <none> <none> web-1 1/1 Running 0 2m14s 192.168.5.2 cn-shanghai.192.168.5.245 <none> <none> -
ECS コンソールで結果を確認します:
-
[スナップショット] ページ:永久保持で 2 つの新しいスナップショットが作成されています。
-
[ブロックストレージ] ページ:ゾーン B に 2 つの新しいディスクが作成され、ゾーン M の元の 2 つのディスクは保持されています (
retainSourcePVが"true"のため)。
-
例 2:マルチゾーンへの分散
可用性を向上させるために、Pod を 2 つのゾーン (ゾーン B と G) に分散させます。
-
移行タスクを作成します:
cat <<EOF | kubectl apply -f - apiVersion: storage.alibabacloud.com/v1beta1 kind: ContainerStorageOperator metadata: name: migrate spec: operationType: APPMIGRATE operationParams: stsName: web stsNamespace: default stsType: kube targetZone: cn-shanghai-b,cn-shanghai-g # ターゲットゾーン。複数のゾーンを指定すると自動的に分散されます healthDurationMinutes: "1" # 移行後 1 分間待機し、アプリケーションが正常に動作していることを確認します snapshotRetentionDays: "-1" # スナップショットを手動で削除するまで永久に保持します retainSourcePV: "true" # 元のディスクと PV を保持します EOF -
移行ステータスを確認します:
ステータスが
FAILEDの場合は、「よくある質問」を参照してトラブルシューティングを行ってください。kubectl describe cso migrate | grep StatusSUCCESSステータスは、移行が完了したことを示します:Status: Status: SUCCESS -
移行後の Pod の配置を確認します:
kubectl get pod -o wide -l app=nginxPod はゾーン B (
cn-shanghai.192.168.5.245) とゾーン G (cn-shanghai.192.168.2.214) に分散されています:NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES web-0 1/1 Running 0 4m59s 192.168.2.215 cn-shanghai.192.168.2.214 <none> <none> web-1 1/1 Running 0 4m38s 192.168.5.250 cn-shanghai.192.168.5.245 <none> <none> -
ECS コンソールで結果を確認します:
-
[スナップショット] ページ:永久保持で 2 つの新しいスナップショットが作成されています。
-
[ブロックストレージ] ページ:ゾーン B と G にまたがって 2 つの新しいディスクが作成され、ゾーン M の元の 2 つのディスクは保持されています。
-
よくある質問
移行タスクが FAILED を返した場合、エラーメッセージを取得します:
kubectl describe cso <ContainerStorageOperator-name> | grep Message -A 1
出力例:
Message:
Consume: failed to get target pvc, err: no pvc mounted in statefulset or no pvc need to migrated web
コンポーネントが移行対象の PVC を見つけられませんでした。一般的な原因は次のとおりです:
-
StatefulSet にマウントされたストレージがありません。
-
すべてのディスクがすでにターゲットゾーンにあるため、移行は不要です。
-
コンポーネントが PVC 情報を取得できませんでした。
エラーメッセージに基づいて問題を解決し、移行タスクを再適用してください。