サムネイル画像

ここ最近はどうにもやる気が出なくて困っていた。

ollamaで何かを作るアイディアはあるのだが、いざ動かしてみるとネットワークが途切れる問題が頻発していた。

確かにGPUに負荷をかけるようになってPCに負荷はかけていたが、ネットワークそのものが不安定になるのは正直想定外であった。

9月の3連休を利用してずっとネットワークを構築しなおすことにした。

8月は清掃やらPCの組み換え作業で充足感を得られたが、今回は繋げては失敗の繰り返しで得るものはほぼなかった。

ルーターのファームウェアの書き換え作業も検討したが、そもそもルーターが対応していないとのことだった。

ずっとLANケーブルをあれこれ繋げ直したりしていた。

もともと意図して二重NATを組んでいたが、一時的に三重NATなども試した。

そのためこの連休はろくに何もできないまま、ProxmoxのOSを再インストールするところまで完了した。

VaultWardenを使っていたのでパスワードだけはバックアップを行ったが、ネットワーク全体のバックアップを取ることを怠っていた。

私はもう開発ができない苛立ちから早く開放されたいという気持ちで、きっちりとしたバックアップを取る前にOSを再インストールしてしまった。

そのため気づいたときにはあとの祭りだったが、プライベート運用していたGitLabやGiteaのリポジトリを全て失ってしまった。1

データを取り戻すための手順書

幸いproxmoxをインストールするときにZFSでディスクRAIDを組んだ状態でフォーマットを行っていなかったので、OS上はすぐにアクセスできない状態であったがデータそのものは失っていないはずだ。

そのためChatGPTに質問することで解決の糸口がわずかに見えてきた。

結論としてはさまざまなトラブルによりPCに向き合うまでに時間こそかかったものの、データを無事救出することができた。

以下はChatGPTが手順書としてまとめてくれた:

Proxmox + ZFS + GitLab/Gitea 復旧ログ

背景

  • Proxmox を再インストールした結果、既存の ZFS プールやコンテナが見えなくなった
  • VM/コンテナのデータを救出し、GitLab と Gitea のリポジトリを復旧することが目的

1. ZFS プールの再インポート

プールの検出

zpool import

出力例:

  pool: zfs1
    id: 3507224636375815093
 state: ONLINE
 status: The pool was last accessed by another system.
 action: The pool can be imported using its name or numeric identifier and
         the '-f' flag.

プールのインポート

zpool import -f -o altroot=/mnt zfs1

データセット確認

zfs list -o name,mountpoint,volsize,used,avail -r zfs1

出力例:

NAME                    MOUNTPOINT                   VOLSIZE   USED  AVAIL
zfs1                    /mnt/zfs1                          -  37.7G   393G
zfs1/subvol-100-disk-0  /mnt/zfs1/subvol-100-disk-0        -  10.4G  29.6G
...

subvol-XXX-disk-0LXC コンテナのルートファイルシステム

2. コンテナデータの確認・救出

読み取り専用でマウント

/etc/pve/lxc/<VMID>.conf に以下を追記:

mp0: /mnt/zfs1/subvol-100-disk-0,mp=/oldroot,ro=1

これにより、既存のコンテナデータをホストまたは別コンテナから参照可能。

3. GitLab (Omnibus) リポジトリの復旧

保存場所

/oldroot/var/opt/gitlab/git-data/repositories/@hashed/

bare リポジトリの探索

find /oldroot/var/opt/gitlab/git-data/repositories/@hashed -type d -name "*.git"

または特定ファイルで検索:

find /oldroot/var/opt/gitlab/git-data/repositories/@hashed -name HEAD

クローンして救出

git clone /oldroot/var/opt/gitlab/git-data/repositories/@hashed/19/f1/.../project.git myproject
  • Issue/MR/CI/CD などの情報は復旧不可
  • ソースコードとコミット履歴は bare リポジトリにすべて含まれる

4. Gitea ディレクトリのバックアップ

tar+gz アーカイブ

SIZE=$(du -sb /oldroot2/opt/gitea | awk '{print $1}')
DATE=$(date +%F)
ARCHIVE="gitea-${DATE}-opt-gitea.tar.gz"

cd /oldroot2
tar --xattrs --acls --numeric-owner -cpf - opt/gitea \
  | pv -s ${SIZE} \
  | gzip -c > ${ARCHIVE}

rsync でリモートへ転送(進捗&チェックサムあり)

rsync -av --progress --checksum "${ARCHIVE}" root@XXX.XXX.XXX.XXX:./

またはディレクトリごと直接ミラー:

rsync -aHAX --numeric-ids --info=progress2 --checksum \
  /oldroot2/opt/gitea/ \
  root@XXX.XXX.XXX.XXX:/root/backups/opt-gitea/

5. 注意点・ベストプラクティス

  • ZFS: zpool import で決して zpool create しない(既存データ消失防止)
  • LXC: subvol-XXX-disk-0 がそのままルートFS。conf ファイルを作り直せば起動可
  • GitLab: @hashed 以下の .git ディレクトリが bare リポジトリ
  • Gitea: /opt/gitea 以外に /var/lib/gitea//etc/gitea/ も必要な場合がある
  • バックアップ戦略:

    • ZFS スナップショット + zfs send | receive
    • GitLab/Gitea の公式バックアップ機能
    • 定期的な rsync で別ホストへ退避

復旧結果

  • ZFS プールを再インポートしてデータセットを確認
  • LXC コンテナのデータを読み取り専用で安全にマウント
  • GitLab のリポジトリ(@hashed bare repo)を clone して救出成功
  • Gitea ディレクトリを tar+gz & rsync でバックアップ取得
  • すべてのソースコードリポジトリを無事復旧

禍福はあざなえる縄の…?

災いから一転して今回は大きな学びを得るきっかけになった。

当初はほとんど昔作ったリポジトリも後から見返す機会もめっきり減ったからなどと、いっそ諦めようとしていた。

さらにChatGPTは以下の提案を行ってくれた。AI様様である:

  • せっかく復旧できたので、次は バックアップ戦略 を整備すると安心です
    • ZFS スナップショット + zfs send | zfs receive で定期バックアップ
    • GitLab / Gitea は公式の backup コマンドもあるので、週1くらいで tarball を保存
    • rsync + cron でリモートサーバに退避
  • 復旧作業ログを Markdown にまとめておくと、次に同じ事態が起きてもすぐ対応できます

現時点でまだどれを採用するかはまだ考えていないけれど、せっかくの再構築のきっかけに考えてもよいと思う。

ネットワークの問題も根本的には解消していないのだが、もしまた落ちるようであればさらにルーターを増築する予定だ。


  1. この文章は当初「すべてを失ってしまった(i-lost-almost-everything.md)」という悲惨なタイトルから書き始めた