docker代替としてRHEL系OSにデフォルト搭載されたpodmanは当初、dockerを期待している他周辺ソフトウェア(docker-componseやgitlab-runnerなど)と素直に通信してくれませんでした。
しかしpodmanがバージョン3を超え、これら周辺ソフトウェアへの歩み寄りをしてくれたことで、現在では簡単な設定でほぼdockerとして動いてくれるようになりました。
前回Node.jsコンテナを動かしたpodman環境でこれらの設定を行なってみようと思います。
目次
検証環境
- AlmaLinux 8.5
- podman 3.3.1
課題と対策
dockerコンテナを使って何かをするソフトウェアの多くはdockerのUNIXドメインソケット経由で通信します。
しかしRHEL8系OSでデフォルトインストールされたpodmanのイメージは以下のような感じなので、サードパーティソフトウェアはpodmanをコンテナとして使えません。
なので、以下のように追加設定することでpodmanをdockerとして使えるようにします。
インストール、設定
RedHat公式ドキュメントを見ながら、必要そうな部分をかいつまんで行なっていきます。
podman-dockerのインストール
このパッケージをインストールすることで/usr/bin/dockerコマンド、/var/run/docker.sockが入ります。
# dnf install podman-docker
(中略)
インストール済み:
podman-docker-3.3.1-9.module_el8.5.0+2586+018f24d7.noarch
完了しました!
インストールされた/usr/bin/docker。中身はシェルで、podmanコマンドを呼び出しているだけです。
#!/bin/sh
[ -f /etc/containers/nodocker ] || \
echo "Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg." >&2
exec /usr/bin/podman "$@"
execしているのでこのシェルの実行プロセスは呼び出したpodmanコマンドで置換されます。要するに、/usr/bin/docker == /usr/bin/podmanですね。
これからはdockerと打ってもpodmanが起動してくれます。
# docker version
Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg.
Version: 3.3.1
API Version: 3.3.1
Go Version: go1.16.7
Built: Tue Nov 9 21:25:58 2021
OS/Arch: linux/amd64
一方、肝心の/var/run/docker.sockファイルもできましたが、シンボリックリンク元のpodman側UNIXドメインソケットファイル(/run/podman/podman.sock)はまだ無い状態です。
# file /var/run/docker.sock
/var/run/docker.sock: broken symbolic link to /run/podman/podman.sock
# file /run/podman/podman.sock
/run/podman/podman.sock: cannot open `/run/podman/podman.sock' (No such file or directory)
podman-remoteのインストール
/run/podman/podman.sockを作る為にインストールします。
# dnf install podman-remote
(中略)
インストール済み:
podman-remote-3.3.1-9.module_el8.5.0+2586+018f24d7.x86_64
完了しました!
podman-socketをデーモン起動
systemdでUNIXドメインソケットを起動できるようにサービス定義ファイルが作られています。そのままでいいですが、変更する場合はsystemctl daemon-reloadで設定ファイルを読み直しておきます。
# cat /usr/lib/systemd/system/podman.socket
[Unit]
Description=Podman API Socket
Documentation=man:podman-system-service(1)
[Socket]
ListenStream=%t/podman/podman.sock
SocketMode=0660
[Install]
WantedBy=sockets.target
有効化と起動。
# systemctl enable --now podman.socket
Created symlink /etc/systemd/system/sockets.target.wants/podman.socket → /usr/lib/systemd/system/podman.socket.
確認。
# systemctl status podman.socket
● podman.socket - Podman API Socket
Loaded: loaded (/usr/lib/systemd/system/podman.socket; enabled; vendor preset: disabled)
Active: active (listening) since Sun 2021-11-28 00:35:36 JST; 44s ago
Docs: man:podman-system-service(1)
Listen: /run/podman/podman.sock (Stream)
Tasks: 0 (limit: 48471)
Memory: 0B
CGroup: /system.slice/podman.socket
11月 28 00:35:36 kepler systemd[1]: Listening on Podman API Socket.
/run/podman/podman.sockファイルが作成され、/var/run/docker.sockとの疎通が確認できました。
# ls -l /var/run/docker.sock
lrwxrwxrwx. 1 root root 23 11月 28 00:15 /var/run/docker.sock -> /run/podman/podman.sock
# file /var/run/docker.sock
/var/run/docker.sock: symbolic link to /run/podman/podman.sock
# file /run/podman/podman.sock
/run/podman/podman.sock: socket
動作確認
試しにdocker.sock経由でREST APIを叩いてみます。まずはDocker API。
# curl --unix-socket /var/run/docker.sock http:/v1.41/info | jq
{
"ID": "0920805e-d127-4ac8-9836-d3fe5ced9065",
"Containers": 2,
"ContainersRunning": 2,
(中略)
続いてPodman API。
# curl --unix-socket /var/run/docker.sock http://d/v3.0.0/libpod/info | jq
{
"host": {
"arch": "amd64",
"buildahVersion": "1.22.3",
"cgroupManager": "systemd",
"cgroupVersion": "v1",
(中略)
応答が有ればdockerを期待する周辺ソフトウェアから擬似的なdocker資源経由でpodmanが使えるようになっています。
まとめ
CentOS8が出てpodmanに置き換わった当初、CentOS7にインストールしたgitlab-runnnerでdockerコンテナを立ち上げるCIをしていて、どうやってCentOS8に移行するかかなり悩んでいました。これだけdockerと互換性があるのでハックすれば動くだろうけど公式の方法が欲しかったんですよね。
そんな折にpodmanサイドはdocker-composeには対応しない声明を出していたりで「えーマジか・・・」とゲンナリしたもんですが、バージョンが上がって歩み寄ってくれたお陰で、今では上記のCI環境はCentOS8から移行したAlmaLinuxで元気に動作中です。めでたし。
次回はこのpodman環境でdocker-composeを動かしたり、GitLab CIからコンテナ起動してみたいと思います。