Red Hatでソリューションアーキテクトをしている田中司恩(@tnk4on)です。最近はPodmanやOpenShiftの良さをより簡潔に伝えられないかと日々考えながら記事の寄稿などの活動も行っています。
前回の記事では RHEL 8.4 BetaとPodman v3について紹介しましたが、 ついにRHEL 8.4 がGAになりイメージの入手が可能になりました。有効なサブスクリプションをお持ちの場合や、Red Hat Developer Programのアカウントをお持ちの場合は今すぐに入手できます。なお、評価版についてはこの記事執筆時点ではRHEL 8.3のままのようです。
今回は前回記事でも触れたPodman v3でdocker-composeを実行する方法について紹介します。 前回記事はこちらです。 rheb.hatenablog.com
(追記)この記事の続きの記事を書きました。ルートレスモードでdocker-composeを使用する場合は下記記事を参照ください。 rheb.hatenablog.com
PodmanのREST APIを確認してみる
Podman v3におけるdocker-composのサポートはDocker互換のインターフェースとしてREST API *1がサポートされたことにより実現しています。
PodmanのREST API仕様はこちら。 docs.podman.io
RHEL 8.4上でPodmanのREST APIのテストをした結果はこちらです。なおPodman APIソケットを有効にするには、後ほど紹介するpodman.socketサービスを起動する必要があります。
podman version に相当するコマンド
# curl -s --unix-socket /run/podman/podman.sock http://d/v3.0.0/libpod/info | jq .version
出力結果を開く
{
"APIVersion": "3.0.0",
"Version": "3.0.2-dev",
"GoVersion": "go1.15.7",
"GitCommit": "",
"BuiltTime": "Wed Apr 7 17:36:54 2021",
"Built": 1617784614,
"OsArch": "linux/amd64"
}
podman pull docker.io/library/hello-worldに相当するコマンド
curl -XPOST --unix-socket /run/podman/podman.sock -v 'http://d/v3.0.0/images/create?fromImage=docker.io%2Flibrary%2Fhello-world'
出力結果を開く
* Trying /run/podman/podman.sock...
* Connected to d (/run/podman/podman.sock) port 80 (#0)
> POST /v3.0.0/images/create?fromImage=docker.io%2Flibrary%2Fhello-world HTTP/1.1
> Host: d
> User-Agent: curl/7.61.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Api-Version: 1.40
< Content-Type: application/json
< Libpod-Api-Version: 3.0.0
< Server: Libpod/3.0.0 (linux)
< Date: Tue, 18 May 2021 19:42:35 GMT
< Content-Length: 198
<
{"status":"pulling image () from docker.io/library/hello-world:latest (Download complete)","progress":"","progressDetail":{},"id":"d1165f2212346b2bab48cb01c1e39ee8ad1be46b87873d9ca7a4e434980a7726"}
* Connection #0 to host d left intact
podman list imagesに相当するコマンド
# curl --unix-socket /run/podman/podman.sock -v 'http://d/v3.0.0/libpod/images/json' | jq
出力結果を開く
* Trying /run/podman/podman.sock...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to d (/run/podman/podman.sock) port 80 (#0)
> GET /v3.0.0/libpod/images/json HTTP/1.1
> Host: d
> User-Agent: curl/7.61.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Api-Version: 1.40
< Content-Type: application/json
< Libpod-Api-Version: 3.0.0
< Server: Libpod/3.0.0 (linux)
< Date: Tue, 18 May 2021 19:44:59 GMT
< Content-Length: 596
<
{ [596 bytes data]
100 596 100 596 0 0 8514 0 --:--:-- --:--:-- --:--:-- 8637
* Connection #0 to host d left intact
[
{
"Id": "d1165f2212346b2bab48cb01c1e39ee8ad1be46b87873d9ca7a4e434980a7726",
"ParentId": "",
"RepoTags": [
"docker.io/library/hello-world:latest"
],
"RepoDigests": [
"docker.io/library/hello-world@sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792",
"docker.io/library/hello-world@sha256:5122f6204b6a3596e048758cabba3c46b1c937a46b5be6225b835d091b90e46c"
],
"Created": 1614986725,
"Size": 19981,
"SharedSize": 0,
"VirtualSize": 19981,
"Labels": null,
"Containers": 0,
"Names": [
"docker.io/library/hello-world:latest"
],
"Digest": "sha256:5122f6204b6a3596e048758cabba3c46b1c937a46b5be6225b835d091b90e46c"
}
]
Podman v2でREST APIがサポートされた時の紹介記事も参考にしてください。 www.redhat.com
Podmanでdocker-composeを実行する
ここからはPodmanでdocker-composeを実行する手順を紹介します。
なお、RHEL 8.4に搭載されているPodman(v3.0.2-dev)ではルートモードによる実行しかサポートされていません。ルートレスで実行した場合にはエラーになります。ルートレスでdocker-composeを実行するには、現在開発中のPodman v3.2.0以降が必要です(2021/5/19、時点)。
docker-composeのインストール
docker-composeはpipで簡単にインストールできます。docker-composeのドキュメントでは配布バイナリを使用する方法も紹介されています。
# dnf install python3-pip # pip3 install -U pip # pip3 install docker-compose
podman-pluginsのインストール
docker-composeを使ったアプリケーションでは複数のコンテナ間の通信をコンテナ名で行うように指定されていることが多くありますが、Podmanはデフォルトでコンテナ名での通信はできません。Podmanではdnsnameプラグインを使用することでローカルDNSレコードをコンテナに割り当ててコンテナ間で通信することができます。dnsnameプラグインはpodman-pluginsという名前のパッケージでdnfコマンドで追加できます。また同時にdnsmasqも追加されます。
# dnf install podman-plugins
podman.socketサービスの起動
Podmanのインストール初期状態ではREST APIの待ち受けサービス(Podman APIソケット)が起動していませんので、下記の手順でサービスを起動します。
# systemctl enable podman.socket
Created symlink /etc/systemd/system/sockets.target.wants/podman.socket → /usr/lib/systemd/system/podman.socket.
# systemctl start 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 Wed 2021-05-19 04:35:50 JST; 17s ago
Docs: man:podman-system-service(1)
Listen: /run/podman/podman.sock (Stream)
CGroup: /system.slice/podman.socket
5月 19 04:35:50 rhel84 systemd[1]: Listening on Podman API Socket.
サービスの正常起動後、先に紹介したREST APIの確認手順で応答があれば準備完了です。
docker-compose.ymlの作成
docker-composeの実行サンプルアプリとしてWordPressを使用します。docker-composeの実行に必要なdocker-compose.ymlファイルは、Docker Hubに載っているものを流用します。
https://hub.docker.com/_/wordpress
適当なディレクトリを作成して、docker-compose.ymlファイルを配置してください。
# mkdir wordpress && cd wordpress # vi docker-compose.yml
docker-compose.yml
version: '3.1'
services:
wordpress:
image: wordpress
restart: always
ports:
- 8080:80
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: exampleuser
WORDPRESS_DB_PASSWORD: examplepass
WORDPRESS_DB_NAME: exampledb
volumes:
- wordpress:/var/www/html
db:
image: mysql:5.7
restart: always
environment:
MYSQL_DATABASE: exampledb
MYSQL_USER: exampleuser
MYSQL_PASSWORD: examplepass
MYSQL_RANDOM_ROOT_PASSWORD: '1'
volumes:
- db:/var/lib/mysql
volumes:
wordpress:
db:
DOCKER_HOST環境変数の設定
通常、docker-composeはdockerコマンドを介して実行されるため、DOCKER_HOST環境変数にはdockerデーモンのURLが指定されます。Podmanでdocker-composeを実行する場合は、podman.socketサービスで起動したPodman APIソケットを指定します。
# export DOCKER_HOST=unix:///run/podman/podman.sock
docker-composeの実行
docker-compose.ymlファイルがあるディレクトリでdocker-compose upを実行します。-dオプションをつけることでデタッチモードでの実行になります。
# docker-compose up -d Starting wordpress_db_1 ... done Starting wordpress_wordpress_1 ... done
正常にコンテナが実行されているか確認します。
# docker-compose ps
Name Command State Ports
------------------------------------------------------------------------------
wordpress_db_1 docker-entrypoint.sh mysqld Up
wordpress_wordpress_1 docker-entrypoint.sh apach ... Up :8080->80/tcp
# podman ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bd63862f4042 docker.io/library/wordpress:latest apache2-foregroun... 12 minutes ago Up 13 seconds ago 0.0.0.0:8080->80/tcp wordpress_wordpress_1
bf023e2b9b71 docker.io/library/mysql:5.7 mysqld 12 minutes ago Up 13 seconds ago wordpress_db_1
ブラウザでhttp://<ホストのIPアドレス>:8080へアクセスしてWordPressのインストール画面が表示されたらOKです。

(参考)podman network
docker-composeの実行時に自動的に専用のネットワーク(今回はwordpress_default)が作成されます。
# podman network ls NAME VERSION PLUGINS podman 0.4.0 bridge,portmap,firewall,tuning wordpress_default 0.4.0 bridge,portmap,firewall,tuning,dnsname
作成されたネットワークの設定ファイルは/etc/cni/net.d/配下にあり、中身を確認することもできます。
# cat /etc/cni/net.d/wordpress_default.conflist
出力結果を開く
# cat /etc/cni/net.d/wordpress_default.conflist
{
"args": {
"podman_labels": {
"com.docker.compose.network": "default",
"com.docker.compose.project": "wordpress",
"com.docker.compose.version": "1.29.2"
}
},
"cniVersion": "0.4.0",
"name": "wordpress_default",
"plugins": [
{
"type": "bridge",
"bridge": "cni-podman1",
"isGateway": true,
"ipMasq": true,
"hairpinMode": true,
"ipam": {
"type": "host-local",
"routes": [
{
"dst": "0.0.0.0/0"
}
],
"ranges": [
[
{
"subnet": "10.89.0.0/24",
"gateway": "10.89.0.1"
}
]
]
}
},
{
"type": "portmap",
"capabilities": {
"portMappings": true
}
},
{
"type": "firewall",
"backend": ""
},
{
"type": "tuning"
},
{
"type": "dnsname",
"domainName": "dns.podman",
"capabilities": {
"aliases": true
}
}
]
}
まとめ
RHEL 8.4から導入されたPodman v3を使ってdocker-composeを実行する方法をご紹介しました。RHEL 8.4に搭載されているPodman v3.0.1ではルートモードのみしかdocker-composeが実行できませんが、現在開発版として公開されているv3.2.0-RC1ではルートレスでdocker-composeが実行できることを確認しています。 RHEL 8.4でv3.2.0以降が使用できるようになった時は、ルートレスモードの実行方法についてもご紹介します。楽しみにしておいてください。
*1:本記事ではREST APIで統一して記載。REST APIはRESTful APIとも言います。REST APIに関するRed Hatの紹介ページはこちら。 https://www.redhat.com/ja/topics/api/what-is-a-rest-api