nekop's blog

OpenShift / JBoss / WildFly / Infinispanの中の人 http://twitter.com/nekop

OpenShiftでPVの中身を別のPVへ移行する

OpenShift 全部俺 Advent Calendar 2017

OpenShiftやKubernetesでPVを作って使ってたらPVが一杯になってしまったので大きなサイズのPVへ移行したい、であるとか、HDDのPVを使ってたけどSSDのPVに変えよう、というようなデータ移行のユースケースが発生します。

OpenShiftのdocker-reigstyのPVを移行してみましょう。

oc project default
### 現在のPVC名とボリューム名の確認 (この例では registry と registry-storage)
oc get pvc
### docker-registryを一旦停止
oc scale dc docker-registry --replicas=0
### データ移行に利用するno-opコンテナを起動
oc run sleep --image=registry.access.redhat.com/rhel7 -- tail -f /dev/null
### 現在のPVCをno-opコンテナにマウント
oc volume dc/sleep --add -t pvc --name=registry --claim-name=registry --mount-path=/old-registry
### 新しいPV/PVCをno-opコンテナにマウント(dynamic provisioning前提、dynamic provisioningがないならPVを事前に設定)
oc volume dc/sleep --add -t pvc --name=new-registry --claim-name=new-registry --mount-path=/new-registry --claim-mode=ReadWriteMany --claim-size=400Gi
### no-opコンテナにrsh
oc rsh sleep-X-XXXXX
### no-opコンテナ上でデータをrsyncで移行
rsync -avxHAX --progress /old-registry /new-registry
### docker-registryを現在のPVから新しいPVへスイッチ
oc volume dc/docker-registry --remove --name=registry-storage --confirm
oc volume dc/docker-registry --add -t pvc --name=registry-storage --claim-name=new-registry --mount-path=/registry
### docker-registryを再開
oc scale dc docker-registry --replicas=1

問題なければ古いPVCは消して良いでしょう。

KubernetesだとOpenShiftのoc volumeのようなコマンドが無いと思いますが、新PVCとデータ移行Podをapplyして同じ作業をすれば良いはずです。

他にkubectl cpでデータ吸い出してPV/PVC切り替えて新しいPodに書き戻す、という安直なアプローチもありますが、アプリが動いたままで書き込み途中のデータを吸い出してしまったり、バックアップ後に書き込まれたデータがロストしたり、新しいPodがデータを上書きされる想定ではないので誤動作する、などの可能性があるので注意しましょう。

Resources