1年ほど前、仮想化プラットフォーム (仮想化基盤) Proxmox VE (以下「PVE」) の環境構築について書きました。
このPVEの上で稼働している仮想マシンのイメージを、クラウドへバックアップしたくなったと想定します。PVEには様々な形式に対応したストレージ連携機能が標準で備わっていますが、たとえばGoogle Cloud Storageはその対応外です。
そこで、Rcloneというツールを使ってPVEサーバにGoogle Cloud Storageをマウントした上で、PVE上のVMイメージをクラウドバックアップする仕組みを実現してみました。PVEのVMイメージを遠隔地バックアップする一つの方法としてご紹介です。今回のPVEの環境は次の通り。
項目 | 内容 | 備考 |
---|---|---|
PVE OS | Debian GNU/Linux 11 (bullseye) | |
PVE サーバ名 | proxmoxve | |
PVE ユーザID | root | 一般ユーザ権限を常用している場合は下記手順のコマンドに適宜sudoを加えてください |
ssh -L 53682:localhost:53682 root@proxmoxve
でPVEサーバに接続する (そのまま維持する)# sudo -v ; curl https://rclone.org/install.sh | sudo bash
(snip)
rclone v1.62.2 has successfully installed.
Now run "rclone config" for setup. Check https://rclone.org/docs/ for more details.
rclone config
を実行してGoogle Cloud Storageと接続する (基本的にはdefault値を採用して進める)No remotes found, make a new one?
n) New remote
s) Set configuration password
q) Quit config
n/s/q> n
Enter name for new remote.
name> google-cloud-storage
〜〜〜〜〜〜〜〜〜〜
Option object_acl.
Access Control List for new objects.
Choose a number from below, or type in your own value.
Press Enter to leave empty.
/ Object owner gets OWNER access.
1 | All Authenticated Users get READER access.
\ (authenticatedRead)
/ Object owner gets OWNER access.
2 | Project team owners get OWNER access.
\ (bucketOwnerFullControl)
/ Object owner gets OWNER access.
3 | Project team owners get READER access.
\ (bucketOwnerRead)
/ Object owner gets OWNER access.
4 | Default if left blank.
\ (private)
/ Object owner gets OWNER access.
5 | Project team members get access according to their roles.
\ (projectPrivate)
/ Object owner gets OWNER access.
6 | All Users get READER access.
\ (publicRead)
object_acl> 4 # rclone default
〜〜〜〜〜〜〜〜〜〜
Option bucket_acl.
Access Control List for new buckets.
Choose a number from below, or type in your own value.
Press Enter to leave empty.
/ Project team owners get OWNER access.
1 | All Authenticated Users get READER access.
\ (authenticatedRead)
/ Project team owners get OWNER access.
2 | Default if left blank.
\ (private)
3 / Project team members get access according to their roles.
\ (projectPrivate)
/ Project team owners get OWNER access.
4 | All Users get READER access.
\ (publicRead)
/ Project team owners get OWNER access.
5 | All Users get WRITER access.
\ (publicReadWrite)
bucket_acl> 2 # rclone default
〜〜〜〜〜〜〜〜〜〜
Option location.
Location for the newly created buckets.
Choose a number from below, or type in your own value.
Press Enter to leave empty.
1 / Empty for default location (US)
\ ()
2 / Multi-regional location for Asia
\ (asia)
3 / Multi-regional location for Europe
\ (eu)
4 / Multi-regional location for United States
\ (us)
(snip)
location> ?? # https://cloud.google.com/storage/pricing での安いロケーションから例えばus-west1を選択
〜〜〜〜〜〜〜〜〜〜
Option storage_class.
The storage class to use when storing objects in Google Cloud Storage.
Choose a number from below, or type in your own string value.
Press Enter for the default (REGIONAL).
1 / Default
\ ()
2 / Multi-regional storage class
\ (MULTI_REGIONAL)
3 / Regional storage class
\ (REGIONAL)
4 / Nearline storage class
\ (NEARLINE)
5 / Coldline storage class
\ (COLDLINE)
6 / Archive storage class
\ (ARCHIVE)
7 / Durable reduced availability storage class
\ (DURABLE_REDUCED_AVAILABILITY)
storage_class> 4
rclone mkdir google-cloud-storage:/example
を実行し、バケットexample
を作成するexample
の「アクセス権の編集」を実行して「公開アクセス: 非公開」とするrclone lsd google-cloud-storage:/
を実行して、バケットexample
が表示されることを確認するmkdir /mnt/example
でマウントポイントを作成するrclone mount -v google-cloud-storage:/example /mnt/example
してエラーが発生しないことを確認する (実行後数秒してエラーが発生しないならば正常とみなし、Ctrl+Cで終了する)Fatal error: failed to mount FUSE fs: fusermount: exec: "fusermount3": executable file not found in $PATH
というエラーが出た場合は、apt install fuse3
してから再度実行するrclone mount --daemon google-cloud-storage:/example /mnt/example
した後、マウント状態を df -h /mnt/example
で確認する# df -h /mnt/example
Filesystem Size Used Avail Use% Mounted on
google-cloud-storage:example 1.0P 0 1.0P 0% /mnt/example
echo HELLO > /mnt/example/hello.txt
した後、ls -al /mnt/example/hello.txt
でファイルが一覧表示されることを確認するcat /mnt/example/hello.txt
でファイル内容が表示されることを確認する# cat /mnt/example/hello.txt
HELLO
rm /mnt/example/hello.txt
でファイルが削除されることを確認するumount /mnt/example
でマウントを解除するwhich rclone mount.fuse
で2つのプログラムのpathを確認する# which rclone mount.fuse
/usr/bin/rclone
/usr/sbin/mount.fuse
ln -s /usr/bin/rclone /usr/sbin/mount.rclone
するwhich mount.rclone
でmount.rcloneのpathを確認する# which mount.rclone
/usr/sbin/mount.rclone
mount -t rclone google-cloud-storage:/example /mnt/example -o config=/root/.config/rclone/rclone.conf
した後、マウント状態を df -h /mnt/example
で確認するumount /mnt/example && rm -r /mnt/example
でマウントの解除とマウントポイントの削除を実行するPVEサーバが仮想マシンのイメージをバックアップする際に、インターネット経由で利用するクラウドストレージ (Google Cloud Storage) のマウントが外れている・途中で外れる事態を想定しておく必要があるのでは……と考えた。
何らかの事故でマウントが外れた状態だと、特になんの対策もしていない場合、数十GB規模のバックアップがマウントポイントを作成しているローカルストレージに直接保存されていき、当該領域を食いつぶす可能性があり、PVEインストール時のデフォルトでは /mnt
は /
(ルートパーティション) に属しているので、最悪の事態としてはバックアップ動作がProxmox VE自体の動作に影響するかもしれない。
このような事態を発生させないためには、マウントポイントを作成する領域をPVEから隔離すれば良いはず。この方針に基づき、今回はあらかじめ、クラウドストレージ用のマウントポイントを数十MBといった容量小さめのtmpfs (オンメモリ) の中に作成しておき、クラウドストレージのマウントが意図通り行えていない場合にはVMイメージのバックアップをわざと早々に失敗させる、フェイルセーフ機構を仕込むことにした。
mkdir /mnt/tmpfs
で作成する/etc/fstab
に次の内容を追記する# CUSTOM
tmpfs /mnt/tmpfs tmpfs defaults,size=64m 0 0
mount /mnt/tmpfs
を実行した後、マウント状態を df -h /mnt/tmpfs
で確認する (/mnt/tmpfsはtmpfs (オンメモリ) に存在する最大容量64MBの領域だと分かる)# df -h /mnt/tmpfs
Filesystem Size Used Avail Use% Mounted on
tmpfs 64M 0 64M 0% /mnt/tmpfs
df -t tmpfs /mnt/tmpfs >/dev/null && mkdir /mnt/tmpfs/Google-Cloud-Storage && mount -t rclone google-cloud-storage:/example /mnt/tmpfs/Google-Cloud-Storage -o allow_other,vfs_cache_mode=writes,vfs_cache_mode=writes,config=/root/.config/rclone/rclone.conf
をワンライナーとして実行した後、2箇所のマウント状態を df -h /mnt/tmpfs /mnt/tmpfs/Google-Cloud-Storage
で確認する# df -h /mnt/tmpfs /mnt/tmpfs/Google-Cloud-Storage
Filesystem Size Used Avail Use% Mounted on
tmpfs 64M 0 64M 0% /mnt/tmpfs
google-cloud-storage:example 1.0P 0 1.0P 0% /mnt/tmpfs/Google-Cloud-Storage
# crontab -l
@reboot df -t tmpfs /mnt/tmpfs >/dev/null && mkdir /mnt/tmpfs/Google-Cloud-Storage && mount -t rclone google-cloud-storage:/example /mnt/tmpfs/Google-Cloud-Storage -o allow_other,vfs_cache_mode=writes,vfs_cache_mode=writes,config=/root/.config/rclone/rclone.conf
/mnt/tmpfs/Google-Cloud-Storage
がautomountされることを確認する初めに述べた、クラウドストレージのマウントが意図通り行えていない場合のフェイルセーフ機構としては、次の点を考慮している。
/etc/fstab
が解釈された後にcronの「@reboot」が実行されるので、今回のautomountは意図通りの順で実行されるはずmkdir /mnt/tmpfs/Google-Cloud-Storage
」が失敗したらこのディレクトリは存在しないままであるため、本ディレクトリへのPVEによるバックアップ実行は自動的に失敗するはずmkdir /mnt/tmpfs/Google-Cloud-Storage
」は成功し、次の「mount -t rclone google-cloud-storage:/example /mnt/tmpfs/Google-Cloud-Storage ...
」によるクラウド領域のマウントは失敗している場合、/mnt/tmpfs/Google-Cloud-Storage
はクラウド領域ではなくtmpfs領域 (最大容量64MB) のままということになる。この場合、PVEによるバックアップ実行は容量不足を招いて自動的に失敗するはず/mnt/tmpfs/Googlg-Cloud-Storage/
を追加する/mnt/tmpfs/Google-Cloud-Storage/dump/
(マウントしているGoogle Cloud Storage領域) にバックアップファイルが作成されていることを確認する# ls -alh /mnt/tmpfs/Google-Cloud-Storage/dump/
total 2.8G
drwxr-xr-x 1 root root 0 May 7 23:34 .
drwxr-xr-x 1 root root 0 May 7 23:25 ..
-rw-r--r-- 1 root root 2.5K May 7 23:43 vzdump-qemu-107-2023_05_07-23_42_32.log
-rw-r--r-- 1 root root 2.8G May 7 23:43 vzdump-qemu-107-2023_05_07-23_42_32.vma.zst
-rw-r--r-- 1 root root 11 May 7 23:43 vzdump-qemu-107-2023_05_07-23_42_32.vma.zst.notes
以上、オープンソースソフトウェアでかつ使い勝手の良い仮想化プラットフォーム「Proxmox VE」を活用していくための一つの情報です。ところどころ端折っているので、技術記事としては整っていない内容かもしれないと思う一方、私自身の勉強としては、Google Cloud Storage自体を今回の件で初めて使用し、フェイルセーフ機構を実現するためのtmpfsを使ったマウントポイントの工夫 (ベストかどうかは不明) を考えるのにもそれなりに頭をひねったので、このまま少しでも誰かの役に立てばいいや……という勢いで書きました。