GCE 永続ディスクの縮小リサイズは本当にできないのか?!


株式会社アドベンチャー Advent Calendar 2018 の3日目記事です。

はじめまして。株式会社アドベンチャーに所属しております@adv-m-kuroshimaと申します。
普段は弊社サービス「Skyticket」のインフラ、サーバサイド開発、社内SEを兼務してます。

チームでアドベントカレンダー記事を投稿しよーということになり、今回 投稿したことのないQiitaへ恐る恐る書かせてもらいます
なんていいますか、今の心境はこんなんです

はじめに

今回は自分の業務の中からインフラ分野をピックアップします。
弊社サービス「Skyticket」ではプラットフォームにGCPを利用しています。
GCPは多くの特徴を持つ優れたパブリッククラウドで、その特徴の1つ「ディスクのオンラインリサイズ機能」に今回は焦点を当ててみます。

この機能は、起動状態のままストレージサイズを即時変更できる素晴らしい物で、インスタンス構築初期段階でディスクサイズを確定しなくてもどうにかできるという点などでとても助かっている機能です。

しかし、、、このリサイズ機能、、増やせはしますが減らせません。 (この仕様は他クラウドでも概ね同様)
手軽さから調子に乗って拡張してしまうと戻せない。月々の請求額もこの先 拡張したままになってしまうわけです。

Compute Engine ドキュメント : 永続ディスクの追加またはサイズ変更
https://cloud.google.com/compute/docs/disks/add-persistent-disk?authuser=19&hl=ja
~永続ディスクのサイズを小さくすることはできません。

できないことの疑問


か、かわいい・・・

あ、すみません、えーと
そう・・・疑問を持ったんです。 本当に縮小リサイズはできないのだろうか?と
切っ掛けは 500Gに拡張したつもりが5,000Gになってて焦った オンラインサイズ変更機能以外の方法ならできるのでは という所から調査を始め、ディスクサイズ縮小に成功。
ここではその操作手順を記します。

対象OS環境

今回はLinux全般。 対象デストリビューションはどんなものでも問題ないです。
※今回Windows Serverは試していませんが原理上は同じように出来るはずです

今回のテスト環境

  • インスタンス名 : test1
  • ディスク名: test-disk1
  • ディスク変更サイズ: 300GB → 100GB
  • CentOS 7系

永続ディスクサイズの縮小手順

  • ディスク作成時の注意点
    • ドライブコピーを伴うため所要時間はディスクサイズにもより30~60分ほどかかる
    • 作業を速くするために全てSSDで作成する。 運用時にHDDを使う場合は、スナップショット化してからHDD化する
    • 作業リージョンに注意。 全ての作業を最終的にインスタンスを立てるリージョンで行う

1. スナップショット作成 (兼バックアップ)

  1. test-disk1の使用容量が 変更後サイズ100GB未満になっていることを確認
  2. 念のため対象インスタンスtest1を停止
  3. test-disk1のスナップショットss-test-disk1を作成

2. 移行元移行先ディスクを作成

  1. 作成したスナップショットss-test-disk1を使いソースディスクtest-source1 を作成
  2. 変更後サイズ100GBで 新規に移行先ディスクtest-dest1を作成する。 ディスク作成の際、システムパーティションが必要なため、適当なLinuxイメージを使ってディスクを作成する

3. コピー作業用Linuxインスタンスを作成

  1. Linuxインスタンスを作成。(スペックはn1-standard-2(CPUx2 7.5GB) 程度) ディストリビューションは操作に慣れてるものでよい。 起動ディスクは最小サイズ。
  2. 追加ディスクにtest-source1test-dest1を追加
  3. 起動させる

4.test-source1の内容をtest-dest1へコピーする

lsblkコマンドでディスクが認識されているか確認

$ lsblk
NAME    MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda       8:0    0    10G  0 disk 
└─sda1    8:1    0    10G  0 part /

sdb       8:16   0   300G  0 disk 
├─sdb1    8:17   0 299.9G  0 part 
├─sdb14   8:30   0     4M  0 part 
└─sdb15   8:31   0   106M  0 part 

sdc       8:32   0   100G  0 disk 
├─sdc1    8:33   0  99.9G  0 part 
├─sdc14   8:46   0     4M  0 part 
└─sdc15   8:47   0   106M  0 part 

test-dest1をフォーマット

$ sudo mkfs.ext4 /dev/sdc1

test-source1test-dest1をマウント

$ sudo mkdir  /test-src /test-dst
$ sudo mount /dev/sdb1 /test-src
$ sudo mount /dev/sdc1 /test-dst

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        10G  4.7G  5.4G  47% /
devtmpfs        3.6G     0  3.6G   0% /dev
tmpfs           3.6G     0  3.6G   0% /dev/shm
/dev/sdb1     299.9G 76.7G 223.2G 26% /test-src
/dev/sdc1      99.9G   40M  99.3G  1% /test-dst

マウント成功

2つのディスク間でコピー実施

後ろのスラッシュ有無は重要

$ sudo rsync -axHAXSP /test-src/ /test-dst

ディスクをアンマウントしファイルシステムチェック

$ sudo umount /test-src
$ sudo umount /test-dst
$ sudo e2fsck -f /dev/sdc1

UUIDを合わせる

$ blkid|grep sdb1
/dev/sdb1: LABEL="cloudimg-rootfs" UUID="789479ec-e43c-4896-9788-b3243b7fdbc5" TYPE="ext4"

$ sudo tune2fs -U 789479ec-e43c-4896-9788-b3243b7fdbc5 /dev/sdc1
$ blkid
/dev/sda1: LABEL="/" UUID="a0eef40f-aa6f-474b-8083-978a4342b851" TYPE="xfs"
/dev/sdb1: LABEL="cloudimg-rootfs" UUID="789479ec-e43c-4896-9788-b3243b7fdbc5" TYPE="ext4"
/dev/sdc1: LABEL="/" UUID="789479ec-e43c-4896-9788-b3243b7fdbc5" TYPE="ext4"

パーティションラベルを合わせる

前述blkidの内容から移行元のLABEL名を移行先に設定

$ sudo e2label /dev/sdc1 cloudimg-rootfs

5. コピー作業用Linuxインスタンスを削除

  • GCPコントロールパネルからコピー作業用Linuxインスタンスを削除
  • 次の2ディスクを削除 「コピー作業用Linux」 「test-source1」
  • ディスクの「test-dest1」が残る

6. test-dest1でインスタンスを作成

  • 残していたインスタンスtest1を削除し、test-disk1も削除。
  • ディスク「test-dest1」で 新たにインスタンスtest1を作成する

※ディスク「test-dest1」test-disk1にリネームしたい場合はスナップショットを介してディスクを作り直します

7. 新インスタンスを起動

sshログインしてディスク確認

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1      99.9G 76.7G 23.2G  77% /
devtmpfs        3.6G     0  3.6G   0% /dev
tmpfs           3.6G     0  3.6G   0% /dev/shm

300Gディスクを100G化することができています

最後に

これでディスクサイズ大きすぎても安心。 メリークリスマス