今回は、Portworx のコンテナのディザスタ・リカバリ機能を提供する PX-DR の非同期レプリケーション機能についてご説明します。同期レプリケーション機能については、こちらのブログご覧ください。本ブログは、テクニカル・マーケティング・マネージャーのライアン・ウォルナー(Ryan Wallner)による記事を参考に、わたくし溝口が日本語化および加筆、再構成したものです。
なお、PX-DR は 30 日間のトライアル・ライセンスには含まれません。もし、PoC をご検討いただける場合は、sales-japan@purestorage.com までお問い合わせください。
非同期レプリケーション
同期レプリケーションに関するブログでご説明したとおり、データベースのようなステートフル・アプリケーションを Kubernetes プラットフォームで実行しようとする場合には、データ保護の問題が発生します。PX-DR は、主に同期レプリケーションと非同期レプリケーションという 2 つの方法でこれらの問題を解決します。
非同期レプリケーションは、2 つの異なる Portworx クラスタを地理的に異なるエリアに配置し、それらをクラスタ・ペアにします。スタンバイ・サイトでは、継続的に非同期にレプリケーションをスケジューリングして、定義された RPO(目標復旧時点)および RTO の条件のもと、ディザスタ・リカバリ先のクラスタとして動作します。
ボリュームの非同期レプリケーションの設定
非同期レプリケーションには 2 つの Portworx クラスタを使用します。このうち 1 つのクラスタは DR サイトです。クラスタ・ペアは PX-DR の 2 つのクラスタ間で作成されます。クラスタがペアリングされた後、非同期レプリケーションは、スケジュール・ポリシーとマイグレーション・スケジュールの 2 つを使用して実施されます。
スケジュール・ポリシー
スケジュール・ポリシーは、マイグレーションをトリガーするタイミングを指定します。ポリシー自体にはアクションは含まれていませんが、マイグレーション機能によって参照および使用されます。
スケジュール・ポリシーには 4 つのセクションがあります。
- インターバル(
interval
):アクションがトリガーされる間隔を分単位で指定します。 - 日次(
daily
):アクションが毎日トリガーされる時刻を指定します。 - 週次(
weekly
):アクションがトリガーされる曜日と、その日の時刻を指定します。 - 月次(
monthly
):アクションがトリガーされる月の日付と、その日の時刻を指定します。
以下に mysql
という名前空間(namespace)を対象として、インターバル、日次、週次および月次で DR サイトと同期する設定例を示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
apiVersion: stork.libopenstorage.org/v1alpha1 kind: SchedulePolicy metadata: name: testpolicy namespace: mysql policy: interval: intervalMinutes: 1 daily: time: "10:14PM" weekly: day: "Thursday" time: "10:13PM" monthly: date: 14 time: "8:05PM" |
マイグレーション・スケジュール
マイグレーション・スケジュールにより、SchedulePolicy
とマイグレーションを関連付けることができます。以下は、上記の testpolicy
を使用した例です。このマイグレーションは mysql
という名前空間を指し、その名前空間で remotecluster
という名前の clusterPair
(後述)が存在する場合、それを使用します。また、includeResources
、includeVolumes
および、startApplications
を spec
の中で指定することでマイグレーションを制御できます。
includeResources
:Secret、ConfigMaps、Service など、ボリュームに関連付けられた Kubernetes オブジェクトを含めるかどうか。includeVolumes
:PVC に関連付けられた Portworx ボリュームのマイグレーションを含めるかどうか。startApplications
:リソースやボリュームが同期した後、Destination クラスタでアプリケーションを開始するかどうか。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
apiVersion: stork.libopenstorage.org/v1alpha1 kind: MigrationSchedule metadata: name: mysqlmigrationschedule namespace: mysql spec: template: spec: clusterPair: remotecluster includeResources: true includeVolumes: true startApplications: false namespaces: - mysql schedulePolicyName: testpolicy |
Kubernetes ディザスタ・リカバリのワークフロー例
では、Portworx で Google Kubernetes Engine(GKE) を使用して、2 つのサイト間で DR サイトの非同期レプリケーションを設定してみましょう。
以下のゾーンでクラスタを作成しました。us-east4-c に存在するクラスタは、DR サイトです。
- クラスタ 1:米国サウスカロライナ州モンクスコーナーのゾーン D、別名 us-east1-d
- クラスタ 2:米国バージニア州北部アッシュバーンのゾーン C、別名 us-east4-c(DR サイト)
クラスタ 1 とクラスタ 2 をペアにするには、DR 側のクラスタ(以降、「宛先クラスタ」)からトークンを取得し、ソース・クラスタがアクセス可能な宛先クラスタの Portworx ノードの IP アドレスを少なくとも 1 つ用意します。
1 2 3 4 5 6 |
$ kubectl config use-context gke_portworx-cluster-2 $ PX_POD=$(kubectl get pods -l name=portworx -n kube-system -o jsonpath='{.items[0].metadata.name}')\n $ kubectl exec $PX_POD -n kube-system -- /opt/pwx/bin/pxctl cluster token show $ kubectl describe no | grep ExternalIP |
宛先クラスタで storkctl
を使用して、DR を行う名前空間の clusterpair
を生成します。
1 2 3 |
$ storkctl generate clusterpair incremental-dr --namespace mysql |
出力を pair.yaml
という名前のファイルに保存し、Portworx のノード IP と、先に取得したトークンを追加します。詳細は、同期レプリケーションに関するブログの「手順 2. ClusterPair」をご参照ください。
次に、pair.yaml
をソース・クラスタに適用し、状態が Ready
であることを確認します。
1 2 3 4 5 6 7 |
$ kubectl config use-context gke_portworx_cluster-1 $ kubectl create -f pair.yaml $ storkctl get clusterpair NAME STORAGE-STATUS SCHEDULER-STATUS CREATED incremental-dr Ready Ready 08 Mar 19 15:32 EST |
これでクラスタがペアになったので、アプリケーションの非同期レプリケーションを設定できます。MySQL データベースを使用してこれを行う方法を以下に示します。
まず、先に作成した clusterpair
がターゲットとする mysql
という名前の名前空間を作成します。
1 2 3 |
$ kubectl create ns mysql |
次に、Portworx ボリュームと MySQL ポッドを含む MySQL デプロイメントを適用します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
kind: StorageClass apiVersion: storage.k8s.io/v1beta1 metadata: name: mysql-tester-class provisioner: kubernetes.io/portworx-volume parameters: repl: "1" --- ##### Portworx persistent volume claim kind: PersistentVolumeClaim apiVersion: v1 metadata: # Important do not change for testing name: mysql-data namespace: mysql annotations: volume.beta.kubernetes.io/storage-class: mysql-tester-class spec: accessModes: - ReadWriteOnce resources: requests: storage: 12Gi --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: mysql namespace: mysql spec: strategy: rollingUpdate: maxSurge: 1 maxUnavailable: 1 type: RollingUpdate replicas: 1 template: metadata: labels: app: mysql spec: containers: - name: mysql image: mysql:5.6 env: # Use secret in real usage - name: MYSQL_ROOT_PASSWORD value: password - name: ENVVARTEST value: foo ports: - containerPort: 3306 name: mysql volumeMounts: - name: mysql-data mountPath: /var/lib/mysql volumes: - name: mysql-data persistentVolumeClaim: claimName: mysql-data $ kubectl apply -f mysql-pwx.yml |
pxctl
コマンドを使用して、MySQL デプロイメントによって作成された Portworx ボリュームを一覧表示します。
1 2 3 4 5 |
$ kubectl exec $PX_POD -n kube-system -- /opt/pwx/bin/pxctl v l ID NAME SIZE HA SHARED ENCRYPTED IO_PRIORITY STATUS SNAP-ENABLED 911201993725013670 pvc-6ecdbffb-41e3-11e9-918f-42010a8e00c7 12 GiB 1 no no LOW up - attached on 10.142.0.27 no |
次に、MySQL データベースにデータをいくつか追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
kubectl exec -it mysql-7f45c7b6c6-5szcn -n mysql -- /bin/bash -c "mysql -uroot -ppassword -D foo -e 'create database foo;'" kubectl exec -it mysql-7f45c7b6c6-5szcn -n mysql -- /bin/bash -c "mysql -uroot -ppassword -D foo -e \"CREATE TABLE pet (name VARCHAR(20), owner VARCHAR(20),species VARCHAR(20), sex CHAR(1), birth DATE, death DATE);\"" kubectl exec -it mysql-7f45c7b6c6-5szcn -n mysql -- /bin/bash -c "mysql -uroot -ppassword -D foo -e 'SHOW TABLES;'" kubectl exec -it mysql-7f45c7b6c6-5szcn -n mysql -- /bin/bash -c "mysql -uroot -ppassword -D foo -e 'DESCRIBE pet;'" kubectl exec -it mysql-7f45c7b6c6-5szcn -n mysql -- /bin/bash -c "mysql -uroot -ppassword -D foo -e \"INSERT INTO pet VALUES ('Roscoe','Beau','dog','m','2000-03-30',NULL);\"" kubectl exec -it mysql-7f45c7b6c6-5szcn -n mysql -- /bin/bash -c "mysql -uroot -ppassword -D foo -e 'select * from pet;'" +----------+-------+---------+------+------------+-------+ | name | owner | species | sex | birth | death | +----------+-------+---------+------+------------+-------+ | Puffball | Diane | hamster | f | 1999-03-30 | NULL | +----------+-------+---------+------+------------+-------+ 1 row in set (0.00 sec) |
非同期 PX-DR のセットアップ
スケジュール・ポリシーを適用します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
$ cat policy.yaml apiVersion: stork.libopenstorage.org/v1alpha1 kind: SchedulePolicy metadata: name: mysql-policy namespace: mysql policy: interval: intervalMinutes: 1 daily: time: "10:14PM" weekly: day: "Thursday" time: "10:13PM" monthly: date: 9 time: "8:05PM" $ kubectl apply -f policy.yaml schedulepolicy.stork.libopenstorage.org/mysql-policy created $ storkctl get schedulepolicy NAME INTERVAL-MINUTES DAILY WEEKLY MONTHLY mysql-policy 1 10:14PM Thursday@10:13PM 9@8:05PM |
次に、マイグレーション・スケジュールを構成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
$ cat mig-schedule.yml apiVersion: stork.libopenstorage.org/v1alpha1 kind: MigrationSchedule metadata: name: mysqlmigrationschedule namespace: mysql spec: template: spec: clusterPair: incremental-dr includeResources: true includeVolumes: true startApplications: false namespaces: - mysql schedulePolicyName: mysql-policy $ kubectl apply -f mig-schedule.yml $ kubectl describe migrationschedules mysqlmigrationschedule -n mysql |
以上で完了です!
現在の名前空間のアクティブなマイグレーションのリストを取得するには、kubectl
を使用します。ここでは、ポリシーで選択した 1 分の間隔に基づいた初期同期であることを示しています。ポリシーで構成されている時間設定ごとに同期(マイグレーション)が表示されます。
1 2 3 4 5 |
$ kubectl get migration -n mysql NAME AGE mysqlmigrationschedule-interval-2019-03-12-150954 7s |
マイグレーションの詳細を表示するには、kubectl
を使用します。これにより、ボリュームやその他の Kubernetes リソースのマイグレーションの成功または失敗を示す以下のようなイベントが表示されます。
1 2 3 4 5 6 7 8 9 10 11 12 |
$ kubectl describe migration mysqlmigrationschedule-interval-2019-03-12-150954 -n mysql . . . Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Successful 18s stork /v1, Kind=PersistentVolumeClaim mysql/mysql-data: Resource migrated successfully Normal Successful 18s stork /v1, Kind=PersistentVolume /pvc-0c067805-44d8-11e9-a638-42010a8e0094: Resource migrated successfully Normal Successful 18s stork apps/v1, Kind=Deployment mysql/mysql: Resource migrated successfully |
また、storkctl
コマンドを使用すると、作成したスケジュールで実施されたマイグレーションの成功や失敗、進捗状況といった Stage
や Status
を表示できます。
1 2 3 4 5 6 |
$ storkctl get migration -n mysql NAME CLUSTERPAIR STAGE STATUS VOLUMES RESOURCES CREATED mysqlmigrationschedule-interval-2019-03-12-154216 incremental-dr Final Successful 1/1 3/3 12 Mar 19 11:42 EDT mysqlmigrationschedule-interval-2019-03-12-164400 incremental-dr Volumes InProgress 0/1 0/0 12 Mar 19 12:44 EDT |
それでは、ソース・クラスタから同期したデータを使用して、DR サイトでアプリケーションをリストアしてみましょう。
まず、新しいクラスタで使用可能なボリュームを確認します。Creation time
は、ソース・クラスタからの最新の同期と一致している必要があります。startApplications
は false
に設定したため、detached
になっていることに留意してください。
1 2 3 4 5 |
$ kubectl exec $PX_POD -n kube-system -- /opt/pwx/bin/pxctl v list -l owner=Migration ID NAME SIZE HA SHARED ENCRYPTED IO_PRIORITY STATUS SNAP-ENABLED 696635235911597484 pvc-0c067805-44d8-11e9-a638-42010a8e0094 12 GiB 1 no no LOW up - detached no |
次に、ボリュームを調べて、そのタイム・スタンプをメモします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$ kubectl exec $PX_POD -n kube-system -- /opt/pwx/bin/pxctl v inspect 696635235911597484 Volume : 696635235911597484 Name : pvc-0c067805-44d8-11e9-a638-42010a8e0094 Size : 12 GiB ... ... Format : ext4 HA : 1 Creation time : Mar 12 15:44:23 UTC 2019 Shared : no Status : up |
DR サイトのクラスタ内にあるポッド(pod
)とデプロイメント(deployment
)を見て、これらが正しく動作しているかを確認できます。
1 2 3 4 5 6 7 8 |
$ kubectl get po -n mysql No resources found. $ kubectl get deployment -n mysql NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE mysql 0 0 0 0 1h |
上記のとおり、こちらにはアクティブなポッドはありませんが、デプロイメントが存在します。これは、Kubernetes オブジェクトをマイグレーションするかどうかを設定する includeResources
を true
にしたためです。Kubernetes オブジェクトはマイグレートされましたが、startApplications
を false
に設定したため、ポッドのアクティブなレプリカはない状態となっています。
includeResources
を false
に設定します。
DR サイトでアプリケーションをリストアするには、storkctl
コマンドを使用して、最新のマイグレーションを activate
します。
1 2 3 4 |
$ storkctl activate migrations -n mysql Updated replicas for deployment mysql/mysql to 1 |
次に mysql
という名前の名前空間内のポッドを DR サイトで確認します。
1 2 3 4 5 |
$ kubectl get po -n mysql NAME READY STATUS RESTARTS AGE mysql-7f45c7b6c6-xjcb9 1/1 Running 0 6s |
これで、アプリケーションのコピーが DR サイトに正常にリストアされました。
補足情報として、動画をご紹介します。MySQL と WordPress を使用して複数のボリューム、サービスおよびオブジェクトを DR サイトにマイグレーションするという同様のユースケースのデモ動画です。ぜひご覧ください。
PX-DR により、さまざまなタイプの災害からのフェイルオーバーが可能となり、より自信を持ってミッション・クリティカルなデータ・サービスを提供できるようになりました。将来のリリースでは、ここでご紹介したクラスタ・ペアリングやレプリケーション・タイプの設定などは、今後 GUI 等の提供により、直感的でシンプルなものにすることを目指してまいります!
Pure Storage、Pure Storage のロゴ、およびその他全ての Pure Storage のマーク、製品名、サービス名は、米国およびその他の国における Pure Storage, Inc. の商標または登録商標です。その他記載の会社名、製品名は、各社の商標または登録商標です。