先週末に自宅鯖(UbuntuServer 18.04)を雑に do-release-upgrade
してて、アップグレード中にうっかり Ctrl+C
してOSを破壊してしまった私です。
幸いにも自宅鯖で運用していた各サービスはLXDコンテナに乗せてあり、コンテナ用のzfsストレージプールを別ドライブに置いてあったので最悪の事態は免れました。
ただ、zfsストレージプールのみの状態から新しいホストOSのLXDに組み込むのが一苦労したのでそのメモ。
Oracle Solaris ZFS 管理ガイドはもう見飽きました。
0. 想定環境
新しい環境は以下の通りになります。
- ホストOS: Ubuntu Server 20.04.3 LTS
クリーンインストール。基本構成で追加パッケージはOpenSSHのみ - zfs-0.8.3-1ubuntu12.13
- LXD 4.0.7 (snap版)
※snap refresh
してません。4.0.8以降にしてはいけない
1. zfsストレージプールのインポート
普段ファイルシステムはext4/LVMばかり使ってるので、勝手が違うzfsに少々手こずりました。
使い慣れたら便利だと思うけど。
ホストOSクリーンインストール直後はzfsストレージプール(LVMで言うところのVGとかに当たる?)がOSの管理外にあるみたいなので、まずはストレージプールをマウントするところから始めます。
まずはzfsの管理ユーティリティが入ってないのでaptで入れます。
$ sudo apt install -y zfsutils-linux
最初の状態ではストレージプールが取得できません。
$ zpool list
no pools available
/dev/sdX として物理ドライブが認識できている場合は、以下のコマンドでインポートできます。
$ zpool import
## インポートされていないストレージプールが表示される ##
## プール名もしくはIDを確認する ##
$ zpool import <プール名もしくはID> [新しいプール名をつける際はこちらも書く]
これで再度 zpool list
するとインポートしたストレージプールが表示されます。
$ zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
pool-ssd 149G 50.3G 98.7G - - 50% 33% 1.00x ONLINE -
2. zfsボリュームのマウント
LXDは自身でzfsをよしなにしてくれるため普段はマウントなど意識しなくてもいいのですが、コンテナをインポートするときだけは一旦マウントしてLXDが探せるようにしてやる必要があります。
ここで少しつまづいたとこですが、LXDを入れたのがaptかsnapかでマウントポイントが変わるので注意が必要です。
- aptの場合
/var/lib/lxd/storage-pools
配下 - snapの場合
/var/snap/lxd/common/lxd/storage-pools
配下
参考: バックアップ - LXDドキュメント翻訳プロジェクト
Ubuntu18.04ではaptベースだったが、Ubuntu20.04ではsnapになったので、 do-release-upgrade
成功してるような人はaptの方に置き換えて読んでください。
また、snap版LXDを使っていても、バージョンによって打つコマンドが変わることに注意してください
- LXD v4.0.7以前、またはv4.16以前
lxd import
コマンドを用いてストレージの復旧を行います。
当記事ではこちらの方法を紹介します。 - LXD v4.0.8以降、またはv4.17以降
lxd recover
コマンドを用いてストレージの復旧を行います。(lxd import
はこちらに置き換えられました)
LXDは安定版を4.0.x、最新版を4.xのバージョンで提供しており、Ubuntu20.04.3では安定版のほうが初期インストールされていました。
参考: LXD 4.17 リリースのお知らせ 〜 Linux Containers - LXD - ニュース
今回は、 lxd import
を使って dev
コンテナを復旧する例で手順を説明します。
まずは、zfsストレージプール内のコンテナが保存されているボリュームを探します。
zfs list | grep containers/
NAME USED AVAIL REFER MOUNTPOINT
...
pool-ssd/containers/dev 5.73G 49.7G 5.80G none
...
基本的に <ストレージプール>/containers/<コンテナ名>
の中に保存されています。
LXDで管理されていたため、こちらのコマンドからはマウントポイントが見えず none
となっているようです。
手動でマウントするため、一時的にマウントポイントを設定してやります。
# zfs set mountpoint=<LXD格納ディレクトリ>/<コンテナ格納ボリューム> <コンテナ格納ボリューム>
zfs set mountpoint=/var/snap/lxd/common/lxd/storage-pools/pool-ssd/containers/dev pool-ssd/containers/dev
マウント先のディレクトリは掘る必要ありません。これだけでマウントできます。
# zfs mount <コンテナ格納ボリューム>
zfs mount pool-ssd/containers/dev
3. LXDの設定を調整する
あとはコンテナのインポートをすればいいだけなんですが、プロファイルやブリッジインタフェースの設定が不足しているとエラーが出るので、事前に準備します。
lxd init
で設定することもできるんですが、今回は個別に設定していきたいと思います。
まず、コンテナがどんな設定をしていたかを確認します。
# cat <格納ディレクトリ>/<コンテナ格納ボリューム>/backup.yaml
cat /var/snap/lxd/common/lxd/storage-pools/pool-ssd/containers/dev/backup.yaml
LXDのコンテナイメージの設定は backup.yaml
に入っています。ここを確認すればどんな設定をしていたかを確認することが出来ます。
lxc profile list
及び lxc network list
を確認し、違う設定がされている場合はプロファイル、ブリッジをそれぞれ作成していきます。
lxc profile create profile-dev
lxc network create lxdbr0
4. コンテナのインポート、起動
ここまで来てようやくコンテナのインポートをすることができるようになりました。
# lxd import <コンテナ名>
lxd import dev
特にエラーが無ければ、 lxc list
でコンテナが追加されていることが確認できるはずです。
コンテナを起動する前に、一時的にマウントしたボリュームをアンマウントしてやる必要があります。
# zfs unmount <コンテナ格納ボリューム>
zfs unmount pool-ssd/containers/dev
また、コンテナインポート時にブリッジインタフェースがないと起こるくせに、attachはしてくれないみたいなので、こちらも手動で行います。
# lxc network attach <ネットワーク名> <コンテナ名>
lxc network attach lxdbr0 dev
これでコンテナ起動の準備が出来ました。
# lxc start <コンテナ名>
lxc start dev
無事に起動できました。お疲れさまでした。
あとはネットワークアドレスやプロファイルなどの設定を調整したりしてやれば、以前のようにコンテナが扱えるはずです。
ホストOSをアップグレード失敗したときは心臓が10回くらい止まりましたが、無事に復旧させることが出来てよかったです。
LXDは最近のUbuntuに標準で入ってるし、今まではDocker同様LinuxディストリビューションのコンテナだけだったのがKVMやQEMUに対応してきてVMの幅も広がってきてるし、もっと広がってほしいですね。