Windows版と書きましたが、MacOSもLinuxも流れとコマンドは一緒かもしれません。先日導入しました、Podman.exeのコマンドで遊んでいます。
Podman開発のスタート地点が、docker互換だった影響でしょうか。コンテナのリストの表示コマンドが4つもあります。
- podman ps ←おそらくdockerとの互換
- podman container ps
- podman container list
- 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でポッドを動かす、マイグレーションを行うために。
イメージ、ポッド、コンテナのバックアップ・リストア系のコマンドを見てみたいと思います。
バックアップの全体的な流れ
データを含めたポッド・コンテナをバックアップする手順は次の流れになるようです。
- イメージのバックアップ
- ポッド作成yamlのバックアップ
- コンテナをイメージに変換しバックアップ(ボリューム以外のデータのバックアップ)
- コンテナからボリュームをバックアップ(ボリュームに入っているデータのバックアップ)
- データベースは、別途ダンプ
リストアは次の手順になります。
- イメージのリストア
- yamlを再生してポッドとコンテナ作成
- イメージからコンテナをリストア(ボリューム以外のデータのリストア)
- コンテナからボリュームをリストア(ボリュームに入っているデータのリストア)
- データベースは、別途リストア
バックアップ・リストアともに順番に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
# 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種類になりました。
- イメージのtarファイル
- ポッド生成yamlファイル
- コンテナイメージのtarファイル
- ボリュームのバックアップtar.gzファイル
そう、あとこれも保存しておきます。
- Podmanのインストーラー
- データベースのダンプ
理由は、Podmanのバージョンが違うとyamlファイルの仕様が変わり、ポッドを作れなくなるためです。yamlファイルを作成したPodmanと同じバージョンのインストーラーを保管しておきましょう。(Windows版は有利かもしれませんね
これで災害や故障に備えながら、ポッドを運用できそうです。
お疲れ様でした!
以上で、Podmanコマンドでポッドをバックアップするためのコマンドをざーっと見てみました。
コンテナのエクスポートは、失敗しましたが。チェックポイントの実装の問題でしょうか。Docker流の手順は問題なく動作しましたので、実用上は問題無さそうです。
データが入ったボリュームのバックアップは、何か外部ツールのようなものを使うパターンもあるかもしれませんが。本当に実用的でしょうか?
原理的なところは単純(コンテナからボリュームをマウントしているだけ)ですし、どのイメージがどこをマウントしているのか正確に把握していないと、後で痛い目を見る(バックアップできてない、リストアできない)可能性がありますので、そこはしっかり理解しておかないと、実用にならないと思います。
ポッドのバックアップ・リストアが可能とわかりましたので、実際にPodmanでポッドを運用してみようかな?という気持ちが大きくなりました。
こちらはすべて、Windows版で試したということで、Windowsでの運用も問題無い事がよくわかりました。
よろしければ、ポッドの運用にお役立て下さいませ。