Windows版Podman.exeのポッドのバックアップ・リストア手順

Windows版と書きましたが、MacOSもLinuxも流れとコマンドは一緒かもしれません。先日導入しました、Podman.exeのコマンドで遊んでいます。

Podman開発のスタート地点が、docker互換だった影響でしょうか。コンテナのリストの表示コマンドが4つもあります。

  1. podman ps ←おそらくdockerとの互換
  2. podman container ps
  3. podman container list
  4. podman container ls

Podmanの場合、マシン・ポッド・コンテナ・イメージ・ボリュームに渡って共通なのは「list」または「ls」なのかなと思います。

そのような形で、コマンドを整理しつつ、Podmanのバックアップ・リストア手順を調べてみようと思います。


Podmanのコマンドマニュアル

コマンドの正式なマニュアルはこちらのようです。

ちなみに、日本語マニュアル無いかな?と思い、URLのen部分をjaに変えてアクセスしたところ、404エラーページが少し面白かったです。ローグで遊びたくなりました。

2022年10月現在、Podmanの最新バージョンは4.3.0のため、この記事はこちらを対象としています。

Podman 4.0.0系列は、podman system serviceコマンドによるRESTful APIをサポートしたところが、大きな特徴のようです。こちらのAPIは、Docker互換のようです。というわけでAPIマニュアルも充実しております。がここではAPIは扱いません。

ポッドの構築~作成等、運用~停止や再起動、保守~バックアップやマイグレーションあたりのコマンドを摘ませて頂こうと思います。


ポッドの構築系コマンド

WordPressやNextcloud等、ポッドの作成につきましては、こちらを御覧ください。

ただし、-vオプションは、必要に応じて使用して下さい。ローカルのファイルシステムをマウントする場合や、名前付きボリュームをマウントする場合に使用します。

この記事では-vオプションは使用せず、匿名ボリュームにデータを格納しています。バックアップする際、inspectコマンドでボリュームを使用しているかどうか調べられます。

また、この記事はWordPressのポッドをサンプルとして使用します。

rem WordPress用ポッド作成
"%ProgramFiles%\RedHat\Podman\podman.exe" pod create ^
--name wp-pod -p 8091:80
rem Mariadbコンテナ作成
"%ProgramFiles%\RedHat\Podman\podman.exe" run ^
-d --restart=always ^
--pod=wp-pod ^
--name=wp-db ^
-e MYSQL_ROOT_PASSWORD="myrootpass" ^
-e MYSQL_DATABASE="wp" ^
-e MYSQL_USER="wordpress" ^
-e MYSQL_PASSWORD="w0rdpr3ss" ^
docker.io/library/mariadb:latest
rem WordPressコンテナ作成
"%ProgramFiles%\RedHat\Podman\podman.exe" run ^
-d --restart=always ^
--pod=wp-pod ^
--name=wp-web ^
-e WORDPRESS_DB_NAME="wp" ^
-e WORDPRESS_DB_USER="wordpress" ^
-e WORDPRESS_DB_PASSWORD="w0rdpr3ss" ^
-e WORDPRESS_DB_HOST="127.0.0.1" ^
docker.io/library/wordpress:latest

ポッド名はwp-pod、コンテナはwp-webとwp-dbになります。

正常に起動すると、WordPressはポート番号8091で動作しています。

http://localhost:8091

ポッドの運用系コマンド

ポッドの一覧表示、起動・停止、削除、コマンドの実行など。

運用系のコマンドは、こちらの記事からコピペで実行が便利です。

運用系コマンドは、上述の記事。

バックアップやリストア等の保守系コマンドは、引き続きこの記事で追ってご紹介します。


マイグレーションを前提としたバックアップ・リストア手順

コンテナの中身のデータを定期的にバックアップして履歴を残したり。

他のPCや、故障・再構築後に復旧したPCでポッドを動かす、マイグレーションを行うために。

イメージ、ポッド、コンテナのバックアップ・リストア系のコマンドを見てみたいと思います。

バックアップの全体的な流れ

データを含めたポッド・コンテナをバックアップする手順は次の流れになるようです。

  1. イメージのバックアップ
  2. ポッド作成yamlのバックアップ
  3. コンテナをイメージに変換しバックアップ(ボリューム以外のデータのバックアップ)
  4. コンテナからボリュームをバックアップ(ボリュームに入っているデータのバックアップ)
  5. データベースは、別途ダンプ

リストアは次の手順になります。

  1. イメージのリストア
  2. yamlを再生してポッドとコンテナ作成
  3. イメージからコンテナをリストア(ボリューム以外のデータのリストア)
  4. コンテナからボリュームをリストア(ボリュームに入っているデータのリストア)
  5. データベースは、別途リストア

バックアップ・リストアともに順番に1つずつ進めて行きたいと思います。

正しくバックアップ・マイグレーションできているか確認できるように、WordPressの初期画面から。

構築を少し進めて、このような画面を作っておきました。

ポッドの内容がすべてバックアップされていれば、ポッド・ボリュームをすべて初期化・リストア後に同じ画面が表示されるはずです。

では具体的にバックアップを進めたいと思います。

イメージのバックアップ・リストア

イメージはコンテナの作成に使用します。

こちらもdocker互換のためでしょうか。saveとloadコマンドは、image saveとimage loadと同じようです。

ここではimage saveとimage loadと表記することにします。

イメージのセーブ

イメージをtarファイルに保存してみました。

rem セーブはイメージの保存
podman image ls
podman image save -o wordpress-image.tar docker.io/library/wordpress:latest
podman image save -o mariadb-image.tar docker.io/library/mariadb:latest

保存したイメージを使用することで、インターネットからダウンロードする必要無く、コンテナを作成が可能になります。

イメージのロード

いちどすべてのイメージを削除してから、実際に保存したイメージをロードしてみました。標準入力にファイルをひょいっと。

rem ロードはイメージの読み込み
podman image ls
podman image load < wordpress-image.tar
podman image load < mariadb-image.tar

ふむふむ。正しく読み込まれて、リポジトリ欄、タグ欄、イメージID欄ともに同じ値になっていることがわかります。

保存したイメージは、ポッドを動かす環境に必要なファイルの1つ、という位置づけのように思えますので、定期的なバックアップに含めたほうが安全な気がします。


ポッドのバックアップ・リストア

別のPodman実行環境に、先程保存したイメージを読み込ませた後。

もちろん、こちらの記事と同様に

createコマンドでポッドを作成後、runコマンドでコンテナを作成しても良いのですが。

ポッドのkubernetes yamlファイルを生成・バックアップしておき、新しい環境で再生したほうが楽だと思います。

ポッド設定yaml生成

rem ポッドとコンテナ設定yamlの生成
podman generate kube wp-pod > wp-pod.yaml

生成されたyamlファイルの内容はこのような感じです。

# Save the output of this file and use kubectl create -f to import
# it into Kubernetes.
#
# Created with podman-4.2.1
apiVersion: v1
kind: Pod
metadata:
  annotations:
    io.kubernetes.cri-o.ContainerType/wp-db: container
    io.kubernetes.cri-o.ContainerType/wp-web: container
    io.kubernetes.cri-o.SandboxID/wp-db: b3f05d467ba2b7a3e5a06de9aa362a2c8476059c1a1bff585bdfc50ef4d0a2b
    io.kubernetes.cri-o.SandboxID/wp-web: b3f05d467ba2b7a3e5a06de9aa362a2c8476059c1a1bff585bdfc50ef4d0a2b
    io.kubernetes.cri-o.TTY/wp-db: "false"
    io.kubernetes.cri-o.TTY/wp-web: "false"
    io.podman.annotations.autoremove/wp-db: "FALSE"
    io.podman.annotations.autoremove/wp-web: "FALSE"
    io.podman.annotations.init/wp-db: "FALSE"
    io.podman.annotations.init/wp-web: "FALSE"
    io.podman.annotations.privileged/wp-db: "FALSE"
    io.podman.annotations.privileged/wp-web: "FALSE"
    io.podman.annotations.publish-all/wp-db: "FALSE"
    io.podman.annotations.publish-all/wp-web: "FALSE"
  creationTimestamp: "2022-10-30T04:34:03Z"
  labels:
    app: wp-pod
  name: wp-pod
spec:
  containers:
  - args:
    - mariadbd
    env:
    - name: MYSQL_DATABASE
      value: wp
    - name: MYSQL_USER
      value: wordpress
    - name: MYSQL_PASSWORD
      value: w0rdpr3ss
    - name: MYSQL_ROOT_PASSWORD
      value: myrootpass
    image: docker.io/library/mariadb:latest
    name: wp-db
    ports:
    - containerPort: 80
      hostPort: 8091
    resources: {}
    securityContext:
      capabilities:
        drop:
        - CAP_MKNOD
        - CAP_NET_RAW
        - CAP_AUDIT_WRITE
    volumeMounts:
    - mountPath: /var/lib/mysql
      name: 66afa6038f13800532057e5bb56e92b6b0d3c766ec546480c26c36ff709b3182-pvc
  - args:
    - apache2-foreground
    env:
    - name: WORDPRESS_DB_NAME
      value: wp
    - name: WORDPRESS_DB_HOST
      value: 127.0.0.1
    - name: WORDPRESS_DB_USER
      value: wordpress
    - name: WORDPRESS_DB_PASSWORD
      value: w0rdpr3ss
    image: docker.io/library/wordpress:latest
    name: wp-web
    resources: {}
    securityContext:
      capabilities:
        drop:
        - CAP_MKNOD
        - CAP_NET_RAW
        - CAP_AUDIT_WRITE
    volumeMounts:
    - mountPath: /var/www/html
      name: aa81215dcd119ecf81889cf528e37399414f43a2df5edd59547f3d7feecf8b38-pvc
  hostname: wp-pod
  restartPolicy: Always
  volumes:
  - name: 66afa6038f13800532057e5bb56e92b6b0d3c766ec546480c26c36ff709b3182-pvc
    persistentVolumeClaim:
      claimName: 66afa6038f13800532057e5bb56e92b6b0d3c766ec546480c26c36ff709b3182
  - name: aa81215dcd119ecf81889cf528e37399414f43a2df5edd59547f3d7feecf8b38-pvc
    persistentVolumeClaim:
      claimName: aa81215dcd119ecf81889cf528e37399414f43a2df5edd59547f3d7feecf8b38
status: {}

いちどポッドとコンテナを削除して、作成したyamlファイルから作り直してみましょう。

rem ポッドとコンテナをすべて削除
podman pod ls
podman pod stop --all
podman pod rm --all
podman pod ls

すべて削除されました。

ポッドyaml再生

続いてyamlファイルからポッドを生成してみます。

rem ポッドとコンテナの再生
podman play kube wp-pod.yaml
podman pod ls
podman container ls

ポッドが作成されました。先程、保存しておいたイメージをロードしておいたため、インターネットからイメージをダウンロードすること無く、さらっとポッドが作成されました。

またコンテナを確認すると、確かに削除前と同じコンテナが生成されています。(名前が変わってますが後述

以上から、ポッドとコンテナのバックアップは、yamlファイルを1つ保存しておけば良いことがわかります。

とはいえ、yamlを保存したときのPodmanのバージョンと、実行するときのPodmanのバージョンは合わせる必要があります!昔それで痛い目を見ましたので・・・

yamlファイルだけではなく、その時に使用したPodmanのインストーラーを一緒に保存したほうが良いと思います。

再生したポッドのリネーム

それと、yamlファイルを再生すると、コンテナ名が「wp-web」ではなく「wp-pod-wp-web」に変わるようです。長くて冗長のため、リネームしておきました。

rem yamlファイルから起動したコンテナの名前を変更
podman container rename wp-pod-wp-web wp-web
podman container rename wp-pod-wp-db wp-db
podman container ls


コンテナのバックアップ・リストア

コンテナの中身のエクスポートとインポートを行いたいと思います。

データは、コンテナとボリュームの2箇所に入っています。

このうちのコンテナに入ったデータのバックアップ手順、ということになります。

方法1:ポッドを動かしたままのチェックポイントは今は待ち?

チェックポイントをエクスポートしようと思ったのですが、ファイルサイズが0バイトになりました。あれー?そもそもチェックポイントの生成に失敗している感じです。※22.10.30現在

このあたりは、Podmanの開発進捗待ちなのかと思っています。cgroup v2のマウントの問題な気もするのですが。根が深そうですので、今のところ大人しく諦めて、別の方法でコンテナをバックアップします。

方法2:コンテナのエクスポート・インポート・・・も微妙?

チェックポイント機能が正しく動くようになるまでは、エクスポート機能を使用してみたいと思います。

rem コンテナをエクスポート
podman stop wp-pod
podman container export --output="wp-web.tar" wp-web
podman container export --output="wp-db.tar" wp-db

ファイルサイズを確認すると、正しくエクスポートされているように思えます。

次にリストアですが。ポッド、コンテナ、ボリュームをすべて削除した状態から。

先程保存しておいたyamlファイルから、空のWordPressのポッドを起動しました。

rem yamlファイルからポッドを起動
podman play kube wp-pod.yaml
rem コンテナをリネーム
podman container rename wp-pod-wp-web wp-web
podman container rename wp-pod-wp-db wp-db
podman pod ls
podman container ls

初期状態に戻っているため、WordPressは構築前の画面になっています。

コンテナを停止して、先程エクスポートしたtarファイルを読み込みます。

rem コンテナのリストア・・・は失敗※22.10.29現在
podman container stop wp-web
podman container rm wp-web
podman container restore --import wp-web.tar --name wp-web
podman container stop wp-db
podman container rm wp-db
podman container restore --import wp-db.tar --name wp-db

失敗しました!

チェックポイントが邪魔をしておりますね。リストアに失敗していまいます。

エクスポート時のオプションは特に無いため、エクスポートの失敗では無いと思います。

試しに、同じコンテナをエクスポート後、すぐインポートしましたが、同じエラーが表示されます。

なにかオプションの指定方法が誤っている可能性がありますが、チェックポイント機能の影響の可能性もあります。

さらに別の方法・・・コンテナをイメージ化してsave、loadしようと思います。


方法3:docker流のコンテナのcommitとsave、load

commitコマンドでイメージ作成後saveで保存

docker流の方法、いちどコンテナの内容をイメージ化した後、ファイルに保存する方法を試してみました。

rem コンテナのイメージ化と保存
podman container commit wp-web wp-web-image
podman image save -o wp-web-image.tar wp-web-image
podman container commit wp-db wp-db-image
podman image save -o wp-db-image.tar wp-db-image

特に問題なくイメージ作成とファイル保存ができています。

loadで読み込み後run

逆の手順で、loadでイメージを読み込後、コンテナを生成します。

rem イメージの読み込み
podman image load -i wp-web-image.tar
podman image load -i wp-db-image.tar
podman image ls
podman run -d --restart=always --pod=wp-pod wp-web-image
podman run -d --restart=always --pod=wp-pod wp-db-image

このような感じで、ロードしたイメージからコンテナを再現することができました。

しかし。実際のWordPressのコンテンツは、ボリュームに入っています。

コンテナを保存→削除→読み込みましたが、肝心のボリュームはそのままのため、コンテンツは一切バックアップ・リストアされていません。

最後に、コンテナ内のボリュームのバックアップを行いたいと思います。


ボリュームのバックアップとリストア

この記事では、wp-webとwp-dbコンテナを作成しました。

2つのコンテナが、それぞれ匿名ボリュームをマウントしている状態のようです。

確認してみましょう。

ボリュームを使用しているかどうかの確認

inspectコマンドで、コンテナのマウント状態を確認します。

rem コンテナがボリュームをどこでマウントしているか確認
podman container inspect wp-web |more
podman container inspect wp-db |more

それぞれ”Mounts”セクションを確認します。

  • wp-webコンテナは
    • /var/www/htmlディレクトリに
    • 244c・・・から始まる匿名ボリュームをマウントしています

  • wp-dbコンテナは
    • /var/lib/mysqlディレクトリに
    • 8eca・・・・から始まる匿名ボリュームをマウントしています

このような感じで、バックアップ対象のコンテナについて、ボリュームのマウントポイントを確認できました。

※22.11.3追記:こちらのコマンドで調べたほうが見やすそうです。

rem コンテナ名を追加して下さい
podman container inspect --format {{.Mounts}}

ボリュームのバックアップ

ボリュームのバックアップ手順は、次のDockerの資料に基づきます。

podman run –rmコマンドでバックアップ用の一時的なコンテナを作成、–volumes-from オプションで対象のコンテナを指定、あとはコマンドで対象のマウントポイントをアーカイブします。

次のコマンドになります。

rem wp-podポッドのボリュームバックアップ
podman container stop wp-web wp-db
podman run --rm --volumes-from wp-web  -v .:/backup fedora tar zcvf /backup/html.tar.gz /var/www/html
podman run --rm --volumes-from wp-db  -v .:/backup fedora tar zcvf /backup/mysql.tar.gz /var/lib/mysql
podman container start wp-web wp-db

アーカイブはtar zcvfコマンドで、カレントディレクトリ(.)を/backupにマウントして、そこに出力しています。

Podmanのベアメタルがfedoraのため、同じくfedoraで実行してみました。(ubuntuでも何でも

このような感じで、tar.gzファイルが2つ生成されました。

mariadbとwordpressのコンテンツが入っている一番大切なデータが、このtar.gzファイルになると思います。

以上で、ポッドを構成するすべての設定やデータがバックアップできたと思います。

※22.11.20追記:データベースに関しては、ボリュームのバックアップのみではリストアできない場合がありました。

検証のためボリュームを削除

検証のため、コンテナ・ポッド・ボリュームをいちど削除して作り直しました。

rem コンテナ・ポッド・ボリュームを削除
podman container stop --all
podman container rm --all
podman pod stop --all
podman pod rm --all
podman volume rm --all
rem wp-pod再生
podman play kube wp-pod.yaml
rem コンテナをリネーム
podman container rename wp-pod-wp-web wp-web
podman container rename wp-pod-wp-db wp-db

ボリュームをすべて削除したため、WordPressは初期状態に戻りました。

ボリュームのリストア

ボリュームをリストアしてみます。次のコマンドになります。

# wp-podポッドのボリュームをリストア
podman container stop wp-web wp-db
podman run --rm --volumes-from wp-web -v .:/backup fedora bash -c "cd / && tar zxvf /backup/html.tar.gz"
podman run --rm --volumes-from wp-db -v .:/backup fedora bash -c "cd / && tar zxvf /backup/mysql.tar.gz"
podman container start wp-web wp-db

wordpress.tar.gzをwp-webコンテナのルートディレクトリに展開同じくmysql.tar.gzも展開完了後、コンテナを起動無事、バックアップしたボリュームがコンテナに書き戻されました。

以上でバックアップしたポッドのマイグレーションが完了しました!

※22.11.20追記:データベースに関しては、ボリュームのバックアップのみではリストアできない場合がありました。別途、データをダンプする必要があると思います。


ポッドのバックアップコマンドまとめ

rem wp-podのバックアップ
rem イメージをバックアップ
podman image save -o wordpress-image.tar docker.io/library/wordpress:latest
podman image save -o mariadb-image.tar docker.io/library/mariadb:latest
rem ポッドとコンテナ設定yamlの生成
podman generate kube wp-pod > wp-pod.yaml
rem コンテナのイメージ化と保存
podman container commit wp-web wp-web-image
podman image save -o wp-web-image.tar wp-web-image
podman container commit wp-db wp-db-image
podman image save -o wp-db-image.tar wp-db-image
rem wp-podポッドのボリュームバックアップ
podman container stop wp-web wp-db
podman run --rm --volumes-from wp-web -v .:/backup fedora tar zcvf /backup/html.tar.gz /var/www/html
podman run --rm --volumes-from wp-db -v .:/backup fedora tar zcvf /backup/mysql.tar.gz /var/lib/mysql
podman container start wp-web wp-db
rem ※22.11.20追記:データベースは別途ダンプが必要です

※22.11.20追記:データベースに関しては、ボリュームのバックアップのみではリストアできない場合がありました。別途データベースのダンプが必要のため、内容を変更しました。

生成されたバックアップファイルは、次の5種類になりました。

  1. イメージのtarファイル
  2. ポッド生成yamlファイル
  3. コンテナイメージのtarファイル
  4. ボリュームのバックアップtar.gzファイル

そう、あとこれも保存しておきます。

  1. Podmanのインストーラー
  2. データベースのダンプ

理由は、Podmanのバージョンが違うとyamlファイルの仕様が変わり、ポッドを作れなくなるためです。yamlファイルを作成したPodmanと同じバージョンのインストーラーを保管しておきましょう。(Windows版は有利かもしれませんね

これで災害や故障に備えながら、ポッドを運用できそうです。

お疲れ様でした!


以上で、Podmanコマンドでポッドをバックアップするためのコマンドをざーっと見てみました。

コンテナのエクスポートは、失敗しましたが。チェックポイントの実装の問題でしょうか。Docker流の手順は問題なく動作しましたので、実用上は問題無さそうです。

データが入ったボリュームのバックアップは、何か外部ツールのようなものを使うパターンもあるかもしれませんが。本当に実用的でしょうか?

原理的なところは単純(コンテナからボリュームをマウントしているだけ)ですし、どのイメージがどこをマウントしているのか正確に把握していないと、後で痛い目を見る(バックアップできてない、リストアできない)可能性がありますので、そこはしっかり理解しておかないと、実用にならないと思います。

ポッドのバックアップ・リストアが可能とわかりましたので、実際にPodmanでポッドを運用してみようかな?という気持ちが大きくなりました。

こちらはすべて、Windows版で試したということで、Windowsでの運用も問題無い事がよくわかりました。

よろしければ、ポッドの運用にお役立て下さいませ。

スポンサーリンク

フォローする

スポンサーリンク