GKE移行ツール”Migrate for Anthos”でGCEからGKEへの移行を試してみた

Shohei Okada
google-cloud-jp
Published in
19 min readFeb 28, 2020

Googleが提供する、V2C(Virtual Machine to Container)移行ツールである、Migrate for Anthos(M4A)の動作確認を行いました。

tl;dr

  • M4Aを使って、GCEからGKEにワークロードを移行しました
  • 数ステップで簡単に実現できました
  • StatefulSetへの移行となるので、現時点では、”完全なModernizeをしてくれる魔法のツール”ではない印象でした

ツールの概要

M4Aを使うとVMware/AWS/Azure/Google Compute Engine(GCE)で動いているワークロードを、簡単にGoogle Kubenetes Engine(GKE)のコンテナに変換することができます。具体的な移行イメージは以下の通りです。

移行後のワークロードは、Persistent Disk (PD)をPersistentVolumeとしたStatefulSetになります。State”ful”ですので、”ワークロードを完全にModernizeしてくれる魔法のツール”という訳ではなく、あくまでModernizeのための一歩だと個人的には捉えています。とはいえ、以下のようなメリットは得られます。

  • OSのメンテから解放される
  • コンテナ化によりリソース効率が高まり、場合によってはコスト削減になる
  • すでにGKEを使っている場合、GCE/GKEの複数の環境のマネジメントが不要になる

動作確認環境

今回は、GCEに乗っているWordpressを、GKE上で動くコンテナに移行します。WordPressの環境は、GCPのMarket Placeを利用してデプロイしました。

VMが出来上がりました。中身は以下のような状態です。

動作検証

検証の流れは、以下の通りです。手順は公式ドキュメントを参照ください。

  1. 移行先のGKEクラスタの用意
  2. Migrate for Anthosのデプロイ
  3. 移行先のDiskの作成と構成ファイルの作成
  4. 移行先コンテナのデプロイ
  5. 移行先コンテナの動作確認

1. 移行先のGKEクラスタの用意

移行先のGKE Clusterを作成します。既に存在するクラスタに移行する場合はスキップして構いません。

2. Migrate for Anthosのデプロイ

Market Placeより、”Migrate for Anthos”を選択し、移行先のGKEクラスタにツールをデプロイします。必要情報を入力し、Deployを押します。

必要情報は、以下の通り数項目程度です。StorageClassのところはOptionalですが、デフォルトで以下のような値が入っており、空欄にしてもこの名前でStorageClassが作られます。

1–2分程度でデプロイが完了します。

CloudShellを開き、コマンドラインで状況をみていきましょう。まずは、kubectlでクラスタにアクセスできるよう、Credentialを作成します。

$ gcloud container clusters get-credentials destination-cluster --zone asia-northeast1-a --project *****

・Storage Classの確認

anthos-migrateにより、v2k-csi-gce-diskが作成されています。

$ kubectl get storageclass
NAME PROVISIONER AGE
standard (default) kubernetes.io/gce-pd 7m17s
v2k-csi-gce-disk io.gcr.anthos-migrate 2m11s
$
$ kubectl describe storageclass v2k-csi-gce-disk
Name: v2k-csi-gce-disk
IsDefaultClass: No
Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"storage.k8s.io/v1beta1","kind":"StorageClass","metadata":{"annotations":{},"name":"v2k-csi-gce-disk"},"parameters":{"type":"simple"},"provisioner":"io.gcr.anthos-migrate"}
Provisioner: io.gcr.anthos-migrate
Parameters: type=simple
AllowVolumeExpansion: <unset>
MountOptions: <none>
ReclaimPolicy: Delete
VolumeBindingMode: Immediate
Events: <none>

・Applicationの確認

デプロイ時の設定通り、”anthos-migrate”というnamespaceの中に、いくつかアプリケーションがデプロイされています。

$ kubectl get pods --namespace=anthos-migrate
NAME READY STATUS RESTARTS AGE
anthos-migrate-instance-deployer-rjnrb 0/1 Completed 0 100s
anthos-migrate-instance-sc-deployer-8zdkp 0/1 Completed 0 96s

これで、Migrate for Anthosのセットアップは終了です。

3. 移行先のDiskの作成と構成ファイルの作成

手順に従い、依存関係のあるパッケージを導入します。

$ pip install — user pyyaml

続いてツールを実行します。なおこのコマンドを実行する前に、移行対象の仮想マシンの停止が必要です。

このコマンドを実行すると、以下が行われます。

  • 移行先ワークロードのためのPDの作成 (移行元PDを元に作成)
  • 移行に必要な構成ファイルの作成

ツール実行します。

$ python3 /google/migrate/anthos/gce-to-gke/clone_vm_disks.py \
-p '*****' \
-z 'asia-northeast1-a' \
-T 'asia-northeast1-a' \
-i 'wordpress-1-vm' \
-A 'wordpress-dest' \
-o 'deployment.yaml'

なおOptionの意味は以下の通りです。

実行中のログは以下の通り。Snapshot経由で新しいdisk(PD)を作成し、その後deployment.yamlという構成ファイルを作っていることがわかります。

Found disks:
0) wordpress-1-vm
Snapshotting disks
Start creating snapshot: vls-056c-snap-wordpress-1-vm
Waiting for snapshot tasks
- (1/1)Creating disks
Creating new disk vls-056c-wordpress-1-vm
Waiting for create tasks
- (1/1)Deleting snapshots
Done.
GCE->V2K Yaml is at: deployment.yaml

今回は、vls-056c-wordpress-1-vmというディスクが作成されました。コピーしただけなので当たり前ですが、元と同じSizeのものが出来上がっています。

なお、”056c”の部分は、ランダムな文字列になっており、複数回試すと、別の文字列になるようです。

作成されたdeployment.yamlファイルの中身を確認しつつ、どんな構成が定義されているか一つずつ見ていきましょう。

$ cat deployment.yaml

<PersistentVolumeClaimの作成>

spec.storageClassNameにて、M4Aをデプロイした時に作成されたv2k-csi-gce-diskが指定されています。このPVCをデプロイすると、podに紐づいたPVがデプロイされるので(persistentVolumeReclaimPolicy: Deleteのもの)、pod自身の管理用の領域などのためのPVCではないかと推察しています。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wordpress-dest-pvc
spec:
storageClassName: v2k-csi-gce-disk
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50G
---

<PersistentVolumeの作成>

spec.gcePersistentDisk.pdNameにて、先ほど作成したPD(vls-056c-wordpress-1-vm)が指定されています。言い換えると、移行元VMが持っていたデータがそのものがこのPVに入っています。

apiVersion: v1
kind: PersistentVolume
metadata:
name: vls-pv-vls-056c-wordpress-1-vm
spec:
storageClassName: ""
capacity:
storage: 50G
accessModes:
- ReadWriteOnce
gcePersistentDisk:
# Name of pd
pdName: vls-056c-wordpress-1-vm
volumeMode: Block
---

<PersistentVolumeClaimの作成2>

上記で作成したPersistentVolume(vls-pv-vls-056c-wordpress-1-vm)を要求するためのリソースです。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: vls-pvc-vls-056c-wordpress-1-vm
spec:
storageClassName: ""
volumeName: vls-pv-vls-056c-wordpress-1-vm
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50G
volumeMode: Block
---

<StatefulSetの作成>

PersistentVolumeClaimに、上記で作成した2つのPVCが指定されています。

kind: StatefulSet
apiVersion: apps/v1
metadata:
name: wordpress-dest
namespace: default
spec:
serviceName: "wordpress-dest-svc"
replicas: 1
selector:
matchLabels:
app: wordpress-dest
template:
metadata:
labels:
app: wordpress-dest
spec:
initContainers:
- name: lister
image: anthos-migrate.gcr.io/vls-runimg:v1.0.1
imagePullPolicy: Always
volumeMounts:
- name: volumes
mountPath: /volumes
volumeDevices:
- name: vls-056c-wordpress-1-vm
devicePath: /devices/000-vls-056c-wordpress-1-vm
env:
- name: "HC_BOOT_DEVICE_NAME"
value: "000-vls-056c-wordpress-1-vm"
- name: "HC_DEVICES_DIR"
value: "/devices"
- name: "HC_DEVICES_LIST_DIR"
value: "/volumes"
- name: "HC_RUNNER_PARAMS"
value: "listdevs"
- name: init
image: anthos-migrate.gcr.io/v2k-init:v1.0.1
imagePullPolicy: Always
env:
- name: "HC_BLOCKDEV_MODE"
value: "true"
- name: "HC_TRIM_MOUNTS"
value: "false"
- name: "HC_VOLUME_PATH"
value: "/volumes"
volumeMounts:
- name: volumes
mountPath: /volumes
- name: rootfs
mountPath: /rootfs
- name: lvmdata
mountPath: /run/lvm
- name: udevdata
mountPath: /run/udev
securityContext:
privileged: true
containers:
- name: wordpress-dest
image: anthos-migrate.gcr.io/v2k-run:v1.0.1
imagePullPolicy: Always
volumeMounts:
- name: rootfs
mountPath: /rootfs
- name: cgroups
mountPath: /sys/fs/cgroup
securityContext:
privileged: true
readinessProbe:
exec:
command:
- /code/ready.sh
volumes:
- name: vls-056c-wordpress-1-vm
persistentVolumeClaim:
claimName: vls-pvc-vls-056c-wordpress-1-vm
readOnly: false
- name: volumes
emptyDir: {}
- name: rootfs
persistentVolumeClaim:
claimName: wordpress-dest-pvc
readOnly: false
- name: lvmdata
hostPath:
path: /run/lvm
type: Directory
- name: udevdata
hostPath:
path: /run/udev
type: Directory
- name: cgroups
hostPath:
path: /sys/fs/cgroup

4.移行先コンテナのデプロイ

構成ファイルのApplyを実施します。これにより上記のyamlファイルに記載のある4つのリソースがデプロイされます。コマンドの実行自体は一瞬で終わります。

$ kubectl apply -f deployment.yaml
persistentvolumeclaim/wordpress-dest-pvc created
persistentvolume/vls-pv-vls-056c-wordpress-1-vm created
persistentvolumeclaim/vls-pvc-vls-056c-wordpress-1-vm created
statefulset.apps/wordpress-dest created

5.移行先コンテナの動作確認

作られたリソースをみてみます。StatefulSet, PV, PVCがそれぞれ構成ファイル通りに作られていることが確認できます。

$ kubectl get pods,pv,pvc
NAME READY STATUS RESTARTS AGE
pod/wordpress-dest-0 0/1 Running 0 52s
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/pvc-b76f1529-5879-11ea-a826-42010a920120 47Gi RWO Delete Bound default/wordpress-dest-pvc v2k-csi-gce-disk 53s
persistentvolume/vls-pv-vls-056c-wordpress-1-vm 50G RWO Retain Bound default/vls-pvc-vls-056c-wordpress-1-vm 52s
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/vls-pvc-vls-056c-wordpress-1-vm Bound vls-pv-vls-056c-wordpress-1-vm 50G RWO 52s
persistentvolumeclaim/wordpress-dest-pvc Bound pvc-b76f1529-5879-11ea-a826-42010a920120 47Gi RWO v2k-csi-gce-disk 53s
shohei@cloudshell:~ (shohei-job-account)$

また、中身のプロセスを確認してみると、元のWordpressのプロセス(apacheとmysql)が変わらず走っていることが確認できます。

$ kubectl exec -it wordpress-dest-0 /bin/bash
$ ps -ef |grep -e apache -e mysql
mysql 209 1 0 07:02 ? 00:00:00 /usr/sbin/mysqld — daemonize — pid-file=/var/run/mysqld/mysqld.pid
root 22259 1 0 07:05 ? 00:00:00 /usr/sbin/apache2 -k start
www-data 22272 22259 0 07:05 ? 00:00:00 /usr/sbin/apache2 -k start
www-data 22273 22259 0 07:05 ? 00:00:00 /usr/sbin/apache2 -k start
www-data 22274 22259 0 07:05 ? 00:00:00 /usr/sbin/apache2 -k start
www-data 22275 22259 0 07:05 ? 00:00:00 /usr/sbin/apache2 -k start
www-data 22276 22259 0 07:05 ? 00:00:00 /usr/sbin/apache2 -k start

ちなみに、移行元のVMのプロセスは以下のような見え方をしていました。

$ ps -ef |grep -e apache -e mysql
mysql 784 1 0 07:06 ? 00:00:00 /usr/sbin/mysqld
root 23640 1 0 07:07 ? 00:00:00 /usr/sbin/apache2
www-data 23653 23640 0 07:07 ? 00:00:00 /usr/sbin/apache2
www-data 23654 23640 0 07:07 ? 00:00:00 /usr/sbin/apache2
www-data 23655 23640 0 07:07 ? 00:00:00 /usr/sbin/apache2
www-data 23656 23640 0 07:07 ? 00:00:00 /usr/sbin/apache2
www-data 23657 23640 0 07:07 ? 00:00:00 /usr/sbin/apache2
www-data 28612 23640 0 07:09 ? 00:00:00 /usr/sbin/apache2

Wordpressの画面も引き続き表示されれていることもわかります。

$ kubectl expose pods wordpress-dest-0 --port 80 --type LoadBalancer

まとめ

Migrate for Anthosを使って、GCEに動くワークロードを、GKE上のコンテナに移行しました。現時点ではStatefulSetに動かすだけなので、一足飛びに”Modernize出来た”とは言い切れない印象を受けましたが、手軽にまずはGKE化を試してみる、という意味では有益なツールと感じました。

著者

(左) Shohei Okada (Google Cloud, Customer Engineer, Infrastructure Modernization Specialist), (右) Ren Nikuma (Google Cloud, Professional Services, Cloud Consultant, www.linkedin.com/in/renikuma)

Special thanks to Yori and Gossy!!

※このブログに記載している内容は、Google Cloud公式のものではなく、個人的見解です※このブログに記載している内容は、執筆時点(2020/2)での公式ドキュメントや、その他公開されている情報に基づいています

--

--

Shohei Okada
google-cloud-jp

Infrastructure Modernization Specialist, Customer Engineer, Google Cloud Japan. All views and opinions are my own.