TOC
Ubuntu 22.04から24.04でのPodmanを概観
Ubuntuに収録されているPodmanのバージョンをざっくりと振り返ります。
- Ubuntu 22.04 Jammy Jellyfish → 3.4.4
- Ubuntu 23.04 Lunar Lobster → 4.3.1
- Ubuntu 23.10 Mantic Minotaur → 4.3.1
- Ubuntu 24.04 Noble Numbat → 4.9.3
Quadletが使えるように
Podman 4.4でマージされたQuadletというものがUbuntu収録のPodmanでも使えるようになったので、今回は手元にあるけど用途を失ったRaspberry Pi 3Bで使い方を確認します。
諸々のバージョンやストレージドライバーは以下の通りです。
$ uname -a
Linux ubuntu 6.8.0-1004-raspi #4-Ubuntu SMP PREEMPT_DYNAMIC Sat Apr 20 02:29:55 UTC 2024 aarch64 aarch64 aarch64 GNU/Linux
kernelが6.8なので5.13以降で使えるネイティブのOverlayが使えます。
$ podman --version
podman version 4.9.3
$ podman info | grep -E '(graphDriverName|Native)'
graphDriverName: overlay
Native Overlay Diff: "true"
Quadletの実態→podman generate systemdを簡単にしたもの?
podmanはpodというコンテナを運用します。複数のコンテナ起動をコントロールするDocker composeと同じ仕組みとしてpodman-composeもありますが、OS再起動を含めた制御はsystemdのユニットファイルを生成するというスタンスで、podmanのサブコマンドpodman generate systemd
で半自動的にユニットファイルを生成できます。
Nginxを題材に、Docker Compose風運用をPodmanでする
で、このpodman genetare systemd
がPodman 4.7で非推奨になりました。
Release v4.7.0 · containers/podman · GitHub
非推奨になったとはいえ単にsystemdをキックするユニットファイルを生成するだけなので、これまでの運用がすぐに無効化されるわけではないはずですが、Quadletを使うことでsystemdのユニットファイルを操作する必要がなくなるという触れ込みなので使ってみます。
Quadletとは→拡張されたsystemdとpodman-system-generatorコマンドによるsystemdユニットとしてのコンテナ管理
QuadletではQuadletファイルで定義されたコンテナをsystemdユニットとして登録・管理し、そのためのヘルパーコマンドとして/usr/lib/systemd/system-generators/podman-system-generator
があります。これが/usr/libexec/podman/quadlet
という実行ファイルのシンボリックリンクになっていて、あえて言うならこれがQuadletと呼ぶしかないと思います。
ただ、実際にQuadletを動かす段になるとこの実行ファイルはなりを潜めて、あくまでsystemdがQuadletファイルをsystemdユニットとして動かす形になっています。
内部で実際にsystemdユニットとして動かしている内容は参照できますが(後述)、[X-Container]
という見たことのないセクションが反映されていて、systemdの拡張部分としてQuadletが裏で動いているということの様です。
適当にコンテナを立てて試してみる
今回、とりあえずUbuntu 24.04環境としてRaspberry Pi 3BにHTTPサーバーとしてnginxコンテナを立てて動かすコンテナをQuadletで管理する、という例を試します。なお、HTTPサーバーで表示するのは先ごろ発売されたWEB+DB PRESSの最後の総集編のISOイメージをOS起動時にマウントしたパスをnginxでホームディレクトリとして公開することにします。
HTTPサーバーとしてのnginxコンテナは基本は以前のものと同じです。
Nginxを題材に、Docker Compose風運用をPodmanでする
systemdでISOイメージをOS起動時にマウントする
- ISOの置き場所 /var/isoimg/webdb_sp.iso
- ISOのマウント先 /mnt/webdb
マウントはroot権限で、nginxコンテナの起動は一般ユーザーでやることにします。
マウント用のユニットファイル
/etc/systemd/system/mnt-webdb.mount
を作成
[Unit]
Description=WEBDB+PRESS PDF
Before=local-fs.target
[Mount]
What=/var/isoimg/webdb_sp.iso
Where=/mnt/webdb
Type=iso9660
Options=ro,user,noauto,unhide
[Install]
WantedBy=local-fs.target
# mkdir /mnt/webdb
systemdでOS起動時にマウント
# systemctl daemon-reload
# systemctl start mnt-webdb.mount
# systemctl status mnt-webdb.mount
● mnt-webdb.mount - WEBDB+PRESS PDF
Loaded: loaded (/etc/systemd/system/mnt-webdb.mount; disabled; vendor pres>
Active: active (mounted) since Sun 2024-04-21 18:07:41 JST; 6s ago
Where: /mnt/webdb
What: /dev/loop0
Tasks: 0 (limit: 18525)
Memory: 48.0K
CGroup: /system.slice/mnt-webdb.mount
Apr 21 18:07:41 ubuntu systemd[1]: Mounting WEBDB+PRESS PDF...
Apr 21 18:07:41 ubuntu systemd[1]: Mounted WEBDB+PRESS PDF.
# systemctl enable mnt-webdb.mount
Created symlink /etc/systemd/system/local-fs.target.wants/mnt-webdb.mount → /etc/systemd/system/mnt-webdb.mount.
# ls -l /mnt/webdb/
total 395813
-r-xr-xr-x 1 root root 405298538 Aug 25 2023 index.pdf
-r-xr-xr-x 1 root root 2501 Aug 25 2023 readme.txt
dr-xr-xr-x 1 root root 228 Aug 25 2023 search
-r-xr-xr-x 1 root root 401 Aug 25 2023 search.pdx
dr-xr-xr-x 1 root root 9408 Aug 25 2023 webdb_pdf
httpサーバーとしてnginxコンテナを実行(動作確認)
- nginxコンテナのdocker-compose.ymlの場所
/home/hogehoge/podmancompose/nginx-webdb
- nginxコンテナが使用する物理ポート番号
50000
- コンテナ名
nginx-webdb
- ボリュームマウント
/var/containers/nginx_webdb/default.conf:/etc/nginx/conf.d/default.conf
と/mnt/webdb:/usr/share/nginx/html
docker-compose.yml
/home/hogehoge/podmancompose/nginx-webdb/docker-compose.yml
version: "3"
services:
nginx:
image: docker.io/library/nginx:stable
container_name: nginx-webdb
ports:
- "50000:80"
restart: unless-stopped
volumes:
- /var/containers/nginx_webdb/default.conf:/etc/nginx/conf.d/default.conf
- /mnt/webdb:/usr/share/nginx/html
ボリュームマウントするnginx設定ファイル
# install -d -o hogehoge -g hogehoge /var/containers/nginx_webdb
/var/containers/nginx_webdb/default.conf
server {
listen 80;
listen [::]:80;
server_name localhost;
location / {
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
root /usr/share/nginx/html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
podman-composeで動作確認
docker-compose.ymlのあるディレクトリで
$ podman-compose up -d
systemd管理用のユニットファイル生成
$ podman generate systemd --new --files --name nginx-webdb
/home/hogehoge/podmancompose/nginx-webdb/container-nginx-webdb.service
ISOイメージのマウントを依存ユニットに追加するので書き換え
$ diff -u container-nginx-webdb.service{.org,}
--- container-nginx-webdb.service.org 2024-04-21 18:07:59.660681476 +0900
+++ container-nginx-webdb.service 2024-04-21 18:12:42.686308562 +0900
@@ -6,7 +6,8 @@
Description=Podman container-nginx-webdb.service
Documentation=man:podman-generate-systemd(1)
Wants=network-online.target
-After=network-online.target
+Requires=mnt-webdb.mount
+After=network-online.target mnt-webdb.mount
RequiresMountsFor=%t/containers
[Service]
コンテナを落としてsystemdに登録して動作確認
$ podman-compose down
$ cp container-nginx-webdb.service ~/.config/systemd/user/
$ systemctl --user enable container-nginx-webdb.service
Created symlink /home/hogehoge/.config/systemd/user/default.target.wants/container-nginx-webdb.service → /home/hogehoge/.config/systemd/user/container-nginx-webdb.service.
$ systemctl --user start container-nginx-webdb.service
$ systemctl --user status container-nginx-webdb.service
● container-nginx-webdb.service - Podman container-nginx-webdb.service
Loaded: loaded (/home/hogehoge/.config/systemd/user/container-nginx-webdb.>
Active: active (running) since Sun 2024-04-21 18:21:20 JST; 29s ago
Docs: man:podman-generate-systemd(1)
Process: 163768 ExecStartPre=/bin/rm -f /run/user/1001/container-nginx-webd>
Main PID: 164618 (conmon)
CGroup: /user.slice/user-1001.slice/user@1001.service/app.slice/container->
├─164516 /usr/bin/fuse-overlayfs -o ,lowerdir=/var/containers/stor>
├─164595 /usr/sbin/dnsmasq -u root --conf-file=/run/user/1001/cont>
├─164596 containers-rootlessport
├─164606 containers-rootlessport-child
├─164618 /usr/bin/conmon --api-version 1 -c 52261826a3879b5bfab150>
├─164621 "nginx: master process nginx -g daemon off;"
├─164641 "nginx: worker process"
├─164642 "nginx: worker process"
├─164643 "nginx: worker process"
├─164644 "nginx: worker process"
├─164645 "nginx: worker process"
├─164646 "nginx: worker process"
├─164647 "nginx: worker process"
└─164648 "nginx: worker process"
Apr 21 12:21:20 ubuntu conmon[164618]: 2024/04/21 18:21:20 [notice] 1#1: getrli>
動作を確認できたらコンテナを落とします。
$ podman-compose down
この後Quadletを使ってsystemdに登録するので、今回はsystemdから削除します。
$ systemctl --user stop container-nginx-webdb.service
$ systemctl --user disable container-nginx-webdb.service
Quadletに触れる
今の時点では日本語の情報がびっくりするほどないですが、以下のサイトにかなりまとまっているので参考にします。
PodmanのQuadletでコンテナのsystemdサービス化を行う
Quadlet以前と以後の違い
以前のやり方では
- docker-compose.ymlを作ってpodman-composeでサービス起動を確認
- podman-composeでコンテナが起動した状態で
podman generate systemd --new
でsystemdのユニットファイルを作成 - 作成したsystemdのユニットファイルを登録
の手順でしたが、Quadletを使った場合は
- Quadletファイルを作る
- 所定の場所にQuadletファイルを配置して
systemctl daemon-reload
(一般ユーザーの場合はsystemctl --user daemon-reload
)でsystemdユニットとして反映
となります。今までdocker-compose.ymlを作って起動してという流れでしたが、Quadletファイルを直接書ける場合はこの辺が綺麗サッパリなくなります。
とはいえ、これまで長くdocker-composeで管理してきたので、今回は試しにpodman-composeで動かしていた状態からQuadletファイルを作る手順で今回は勧めます。
なお、Podman公式に書かれているQuadletファイルはあまり現実的ではないサンプルなのでどこまで意味があるか謎ですがこんな感じです。
podman-systemd.unit — Podman documentation
[Unit]
Description=A minimal container
[Container]
# Use the centos image
Image=quay.io/centos/centos:latest
# Use volume and network defined below
Volume=test.volume:/data
Network=test.network
# In the container we just run sleep
Exec=sleep 60
[Service]
# Restart service when sleep finishes
Restart=always
# Extend Timeout to allow time to pull the image
TimeoutStartSec=900
# ExecStartPre flag and other systemd commands can go here, see systemd.unit(5) man page.
ExecStartPre=/usr/share/mincontainer/setup.sh
[Install]
# Start by default on boot
WantedBy=multi-user.target default.target
Podlet
Quadletファイルをdocker-compose.ymlから作るためのプロジェクトとしてpodletというものがあります(docker-compose.yml以外にもpodmanコマンド、実行中のpodmanコンテナからも作成できるという触れ込みです)
podlet - crates.io: Rust Package Registry
とりあえずダウンロードしようと思ったものの
https://github.com/containers/podlet/releases
- podlet-aarch64-apple-darwin.tar.xz
- podlet-x86_64-apple-darwin.tar.xz
- podlet-x86_64-pc-windows-msvc.zip
- podlet-x86_64-unknown-linux-gnu.tar.xz
- podlet-x86_64-unknown-linux-musl.tar.xz
LinuxのARMがない!
ということでしかたなくamd64なLinux上で実行することにします。一応dockerhubにはamd64とarm64のコンテナがあるので、arm64のバイナリをインストールできるようになるまではこれを使う感じになるんですかね。
$ wget https://github.com/k9withabone/podlet/releases/download/v0.2.4/podlet-x86_64-unknown-linux-gnu.tar.xz
$ tar Jxvf podlet-x86_64-unknown-linux-gnu.tar.xz
podlet-x86_64-unknown-linux-gnu/
podlet-x86_64-unknown-linux-gnu/podlet
podlet-x86_64-unknown-linux-gnu/LICENSE
podlet-x86_64-unknown-linux-gnu/README.md
podlet-x86_64-unknown-linux-gnu/CHANGELOG.md
podletはbusyboxスタイルのサブコマンドで入力を指定するようで、docker-compose.ymlからQuadletファイルを生成する場合はpodlet compose
コマンドを実行します。
$ podlet-x86_64-unknown-linux-gnu/podlet -h
Generate podman quadlet files from a podman command, compose file, or existing
object
Usage: podlet [OPTIONS] <COMMAND>
Commands:
podman Generate a podman quadlet file from a podman command
compose Generate podman quadlet files from a compose file
generate Generate a podman quadlet file from an existing container,
network, volume, or image
help Print this message or the help of the given subcommand(s)
Options:
-f, --file [<FILE>]
Generate a file instead of printing to stdout
-u, --unit-directory
Generate a file in the podman unit directory instead of printing to
stdout [aliases: unit-dir]
-n, --name <NAME>
Override the name of the generated file (without the extension)
--overwrite
Overwrite existing files when generating a file
--skip-services-check
Skip the check for existing services of the same name
-p, --podman-version <PODMAN_VERSION>
Podman version generated quadlet files should conform to [default:
4.8] [aliases: compatibility, compat] [possible values: 4.4, 4.5, 4.6,
4.7, 4.8]
-a, --absolute-host-paths [<RESOLVE_DIR>]
Convert relative host paths to absolute paths
-d, --description <DESCRIPTION>
Add a description to the unit
--wants <WANTS>
Add (weak) requirement dependencies to the unit
--requires <REQUIRES>
Similar to --wants, but adds stronger requirement dependencies
--before <BEFORE>
Configure ordering dependency between units
--after <AFTER>
Configure ordering dependency between units
-i, --install
Add an [Install] section to the unit
--wanted-by <WANTED_BY>
Add (weak) parent dependencies to the unit
--required-by <REQUIRED_BY>
Similar to --wanted-by, but adds stronger parent dependencies
-h, --help
Print help (see more with '--help')
-V, --version
Print version
$ podlet-x86_64-unknown-linux-gnu/podlet compose -h
Generate podman quadlet files from a compose file
Usage: podlet compose [OPTIONS] [COMPOSE_FILE]
Arguments:
[COMPOSE_FILE] The compose file to convert
Options:
--pod <POD> Create a Kubernetes YAML file for a pod instead of separate
containers
-h, --help Print help (see more with '--help')
$ podlet-x86_64-unknown-linux-gnu/podlet --version
podlet 0.2.4
で、今回のnginxコンテナのdocker-compose.ymlから生成したQuadletファイルは以下。まぁかなりシンプルなんでエラーも出ずに出力されます。
$ podlet-x86_64-unknown-linux-gnu/podlet compose docker-compose.yml
# nginx.container
[Container]
ContainerName=nginx-webdb
Image=docker.io/library/nginx:stable
PublishPort=50000:80
Volume=/var/containers/nginx_webdb/default.conf:/etc/nginx/conf.d/default.conf
Volume=/mnt/webdb:/usr/share/nginx/html
[Service]
Restart=always
RequiresとAfterを指定しましょう。最終的にこのコマンド実行はOS起動時の自動起動を設定するために変更しています。記事の末尾を参照ください。
$ podlet-x86_64-unknown-linux-gnu/podlet --requires "mnt-webdb.mount" --after "network-online.target mnt-webdb.mount" compose docker-compose.yml
# nginx.container
[Unit]
Requires=mnt-webdb.mount
[Container]
ContainerName=nginx-webdb
Image=docker.io/library/nginx:stable
PublishPort=50000:80
Volume=/var/containers/nginx_webdb/default.conf:/etc/nginx/conf.d/default.conf
Volume=/mnt/webdb:/usr/share/nginx/html
[Service]
Restart=always
Afterがないんだが…バグだそうです。0.3がリリースされたらおそらくAfterが追加されるんでしょう。
–after option not working · Issue #64 · containers/podlet · GitHub
--file .
でカレントディレクトリに出力します。
$ podlet-x86_64-unknown-linux-gnu/podlet --file . --requires "mnt-webdb.mount" --after "network-online.target mnt-webdb.mount" compose docker-compose.yml
Wrote to file: ./nginx.container
Quadletを使う
この.container
ファイルを下の候補の中のどこかに格納します。
- /etc/containers/systemd/
- /usr/share/containers/systemd/
- $XDG_CONFIG_HOME/containers/systemd/ または ~/.config/containers/systemd/
- /etc/containers/systemd/users/$(UID)
- /etc/containers/systemd/users/
今回はpodman実行ユーザーから管理する場所という意味で~/.config/containers/systemd/
に格納します。で、このディレクトリがないので作ります。
$ mkdir ~/.config/containers/systemd
さっきpodletのバグで付与してくれなかったAfter行を追加します。
$ diff -u nginx.container{.org,}
--- nginx.container.org 2024-05-01 19:15:45.173014110 +0900
+++ nginx.container 2024-05-01 19:16:25.446989802 +0900
@@ -1,5 +1,6 @@
[Unit]
Requires=mnt-webdb.mount
+After=network-online.target mnt-webdb.mount
[Container]
ContainerName=nginx-webdb
これをQuadletでsystemdのユニットファイルに変換します。--dryrun
を指定すると生成する中身を表示するだけみたいなので、とりあえず実行します。
$ /usr/lib/systemd/system-generators/podman-system-generator --user --dryrun
quadlet-generator[20549]: Error occurred resolving path "/etc/containers/systemd/users/1000": lstat /etc/containers/systemd/users/1000: no such file or directory
quadlet-generator[20549]: Loading source unit file /home/hogehoge/.config/containers/systemd/nginx.container
---nginx.service---
[Unit]
Requires=mnt-webdb.mount
After=network-online.target mnt-webdb.mount
SourcePath=/home/hogehoge/.config/containers/systemd/nginx.container
RequiresMountsFor=%t/containers
RequiresMountsFor=/var/containers/nginx_webdb/default.conf
RequiresMountsFor=/mnt/webdb
[X-Container]
ContainerName=nginx-webdb
Image=docker.io/library/nginx:stable
PublishPort=50000:80
Volume=/var/containers/nginx_webdb/default.conf:/etc/nginx/conf.d/default.conf
Volume=/mnt/webdb:/usr/share/nginx/html
[Service]
Restart=always
Environment=PODMAN_SYSTEMD_UNIT=%n
KillMode=mixed
ExecStop=/usr/bin/podman rm -v -f -i --cidfile=%t/%N.cid
ExecStopPost=-/usr/bin/podman rm -v -f -i --cidfile=%t/%N.cid
Delegate=yes
Type=notify
NotifyAccess=all
SyslogIdentifier=%N
ExecStart=/usr/bin/podman run --name=nginx-webdb --cidfile=%t/%N.cid --replace --rm --cgroups=split --sdnotify=conmon -d -v /var/containers/nginx_webdb/default.conf:/etc/nginx/conf.d/default.conf -v /mnt/webdb:/usr/share/nginx/html --publish 50000:80 docker.io/library/nginx:stable
- 思ったより長い
- ユニットファイルを格納する候補の4番目の場所(
/etc/containers/systemd/users/$(UID)
)がないというエラーが出ているが知ったこっちゃないのでこのメッセージを出さなくしてほしい
ということで、実際に反映するならsystemctl --user daemon-reload
を実行します。
$ systemctl --user daemon-reload
$ systemctl --user list-unit-files -t service | grep nginx
nginx.service generated -
nginx.service
という名前で登録されました。
$ systemctl --user status nginx.service
○ nginx.service
Loaded: loaded (/home/hogehoge/.config/containers/systemd/nginx.container;>
Active: inactive (dead)
まだ死んでいるので起動します。
$ systemctl --user start nginx.service
$ systemctl --user status nginx.service
● nginx.service
Loaded: loaded (/home/hogehoge/.config/containers/systemd/nginx.container;>
Active: active (runこning) since Wed 2024-05-01 19:44:47 JST; 5s ago
Main PID: 20649 (conmon)
Tasks: 22 (limit: 940)
Memory: 22.5M (peak: 22.9M)
CPU: 1.491s
CGroup: /user.slice/user-1000.slice/user@1000.service/app.slice/nginx.serv>
├─libpod-payload-a9e1c6d5179f3d9908cda97df8e4125bac8d25cd7118dd37a>
│ ├─20651 "nginx: master process nginx -g daemon off;"
│ ├─20669 "nginx: worker process"
│ ├─20670 "nginx: worker process"
│ ├─20671 "nginx: worker process"
│ └─20672 "nginx: worker process"
└─runtime
├─20630 /usr/bin/slirp4netns --disable-host-loopback --mtu=65520>
├─20633 rootlessport
├─20639 rootlessport-child
└─20649 /usr/bin/conmon --api-version 1 -c a9e1c6d5179f3d9908cda>
May 01 19:44:48 ubuntu nginx-webdb[20649]: 2024/05/01 10:44:48 [notice] 1#1: us>
May 01 19:44:48 ubuntu nginx-webdb[20649]: 2024/05/01 10:44:48 [notice] 1#1: ng>
May 01 19:44:48 ubuntu nginx-webdb[20649]: 2024/05/01 10:44:48 [notice] 1#1: bu>
May 01 19:44:48 ubuntu nginx-webdb[20649]: 2024/05/01 10:44:48 [notice] 1#1: OS>
May 01 19:44:48 ubuntu nginx-webdb[20649]: 2024/05/01 10:44:48 [notice] 1#1: ge>
May 01 19:44:48 ubuntu nginx-webdb[20649]: 2024/05/01 10:44:48 [notice] 1#1: st>
May 01 19:44:48 ubuntu nginx-webdb[20649]: 2024/05/01 10:44:48 [notice] 1#1: st>
May 01 19:44:48 ubuntu nginx-webdb[20649]: 2024/05/01 10:44:48 [notice] 1#1: st>
May 01 19:44:48 ubuntu nginx-webdb[20649]: 2024/05/01 10:44:48 [notice] 1#1: st>
May 01 19:44:48 ubuntu nginx-webdb[20649]: 2024/05/01 10:44:48 [notice] 1#1: st>
HTTPサーバーが起動しているか確認します。
$ curl http://localhost:50000/
<html>
<head><title>Index of /</title></head>
<body>
<h1>Index of /</h1><hr><pre><a href="../">../</a>
<a href="search/">search/</a> 24-Aug-2023 15:00 -
<a href="webdb_pdf/">webdb_pdf/</a> 24-Aug-2023 15:00 -
<a href="index.pdf">index.pdf</a> 24-Aug-2023 15:00 387M
<a href="readme.txt">readme.txt</a> 24-Aug-2023 15:00 2501
<a href="search.pdx">search.pdx</a> 24-Aug-2023 15:00 401
</pre><hr></body>
</html>
ということでQuadletの動作確認ができました。
Quadletを使った場合のOS起動時の自動起動について
Quadletファイルをsystemdで実行する場合、
[Service]
Restart=always
が設定されているので、OSの再起動をした場合に自動的にPodmanコンテナが起動するように思えますが、実際には自動起動することはありません。
かと言ってsystemctl enableで自動起動するようにすれば良いのかというとそういうことではなく、enableとdisableによる制御自体ができません。
$ systemctl --user enable nginx.service
Failed to enable unit: Unit /run/user/1000/systemd/generator/nginx.service is transient or generated.
$ systemctl --user disable nginx.service
The unit files have no installation config (WantedBy=, RequiredBy=, UpheldBy=,
Also=, or Alias= settings in the [Install] section, and DefaultInstance= for
template units). This means they are not meant to be enabled or disabled using systemctl.
Possible reasons for having these kinds of units are:
• A unit may be statically enabled by being symlinked from another unit's
.wants/, .requires/, or .upholds/ directory.
• A unit's purpose may be to act as a helper for some other unit which has
a requirement dependency on it.
• A unit may be started when needed via activation (socket, path, timer,
D-Bus, udev, scripted systemctl call, ...).
• In case of template units, the unit is meant to be enabled with some
instance name specified.
また、OS起動時に自動起動されるユニットの一覧を確認しても入っていません。
$ systemctl --user list-dependencies default.target
default.target
● └─basic.target
● ├─paths.target
● ├─sockets.target
● │ ├─dbus.socket
● │ ├─dirmngr.socket
● │ ├─gpg-agent-browser.socket
● │ ├─gpg-agent-extra.socket
● │ ├─gpg-agent-ssh.socket
● │ ├─gpg-agent.socket
● │ ├─keyboxd.socket
● │ ├─pk-debconf-helper.socket
● │ └─snapd.session-agent.socket
● └─timers.target
● └─launchpadlib-cache-clean.timer
で、podmanのQuadletファイルの例は最終行に以下の記述があり、
[Install]
# Start by default on boot
WantedBy=multi-user.target default.target
説明もあります。
Enabling unit files The services created by Podman are considered transient by systemd, which means they don’t have the same persistence rules as regular units. In particular, it is not possible to “systemctl enable” them in order for them to become automatically enabled on the next boot.
To compensate for this, the generator manually applies the [Install] section of the container definition unit files during generation, in the same way systemctl enable does when run later.
このInstall行でOS起動時に実行されるターゲットを指定することでOS起動時の自動起動を実現するのがセオリーみたいですが、systemdの流儀から外れるので将来的に回収してほしいところ。Podletのオプションとしても--install --wanted-by "default.target"
が必要です(実際にはAfter
も追記する必要があります)
$ podlet-x86_64-unknown-linux-gnu/podlet --requires "mnt-webdb.mount" --after "network-online.target mnt-webdb.mount" --install --wanted-by "default.target" compose docker-compose.yml
# nginx.container
[Unit]
Requires=mnt-webdb.mount
[Container]
ContainerName=nginx-webdb
Image=docker.io/library/nginx:stable
PublishPort=50000:80
Volume=/var/containers/nginx_webdb/default.conf:/etc/nginx/conf.d/default.conf
Volume=/mnt/webdb:/usr/share/nginx/html
[Service]
Restart=always
[Install]
WantedBy=default.target
$ podlet-x86_64-unknown-linux-gnu/podlet --file . --requires "mnt-webdb.mount" --after "network-online.target mnt-webdb.mount" --install --wanted-by "default.target" compose docker-compose.yml
Wrote to file: ./nginx.container
OS起動時に実行される対象に入っているかを確認します。
$ systemctl --user list-dependencies default.target
default.target
○ ├─nginx.service
● └─basic.target
● ├─paths.target
● ├─sockets.target
● │ ├─dbus.socket
● │ ├─dirmngr.socket
● │ ├─gpg-agent-browser.socket
● │ ├─gpg-agent-extra.socket
● │ ├─gpg-agent-ssh.socket
● │ ├─gpg-agent.socket
● │ ├─keyboxd.socket
● │ ├─pk-debconf-helper.socket
● │ └─snapd.session-agent.socket
● └─timers.target
● └─launchpadlib-cache-clean.timer
また、(ssh等で)ログインしていない場合に止まるのはPodmanに限らず起こることなので、コンテナの実行ユーザーはlingerを有効にします。
# loginctl enable-linger hogehoge
雑感
良さそうなこと
- docker-compose/podman-compose依存を脱却(ソラでQuadletファイルを書けるなら完全に不要)
- docker/podman外のsystemd管理のサービスとの依存関係を作りやすい
良くないかもしれないこと
- [X-Container]のImageにタグ付きでコンテナレジストリが入るので、おそらくsystemdからの実行が走る度にコンテナレジストリへのチェックが入る。普段は問題ないが、非互換の更新がコンテナレジストリに入った場合に更新されるとまずそうなので、イメージのlatest指定はやめたほうが良さそう
- コンテナレジストリに繋がらない場合にはサービスが起動しないという動作になりそうな気がする(インターネットに繋がっていることは
network-online.target
をAfterに指定すれば担保できそうな気はする)- 実行するコンテナがdocker-compose/podman-compose pullでできた方が管理の都合は良いかもしれない(その場合はQuadletは使えない?)
- Quadletファイルを直接書ける場合を除くと手間的には
podman generate systemd
でユニットファイルを作って登録するのとあまり変わらない
こんなところでしょうか。systemdが動く環境であれば移行するのは正統性があるのかなと感じるので、簡素なサービスであればじゃんじゃん使うべきかなと思います。
スポンサーリンク
comments powered by Disqus