ども。nodamushiです。
さて、前々からプロジェクトのビルドにDockerを使うと、Root権限またはdockerグループに所属する必要があったり、デーモンが必要だったり、なんだかんだ結構不満がありました。
とはいえ、忙しいし、困ってはないということでずっとDockerでやってきてたんですが、いい加減 Podman や Buildah も使えない老害がデブい顔してるのはヤバイと思ってはいたのでちょっと勉強してきました。
Podman って何
Podman (Pod Manager) は ダグトリオかウミトリオの近縁種 Dockerと互換性のあるコンテナランタイムで、Linuxシステムでコンテナを操作・管理するためのツール。
Podmanは、Dockerの代替として開発されていて、特徴としては以下のような物があるらしい。
- デーモンレス: Podmanはデーモンプロセスを必要とせず、コンテナ操作はコマンドラインから直接行われる
- ルートレス: Podmanは、ルート権限を持たないユーザーでもコンテナを操作可能。Podmanが気になってたのはだいたいこれ。
- OCI準拠: Podmanは、Open Container Initiative(OCI)に準拠したコンテナイメージをサポートしており、Dockerイメージと互換性があるっていうか、コマンド体型からして大体Docker
あとはその名前からわかるように Pod (複数のコンテナの塊) を管理する機能もついてるみたいで、 Kubernetes を使ってる人とかには刺さるのかもしれない。今のところ私は Pod が必要な場面に出くわしたことがないので今回は無視。
ていうか、今更なんだけど Docker も数年前からルートレスで実行することができるようになってるらしい。
いや、まじで今日まで知らなかった。ホント、とんだ老害だよね………流石に反省。とはいえ、Rootless用のDockerを入れないといけないみたいなので、簡単には使えないのかな?
Ubuntu 20.04 にインストール
とりあえず、サクッと用意できる環境が Ubuntu 20.04 だったので、Ubuntu20.04 でやろうとしたんだけど、 apt install でサクッと入らなかった。どうにも Ubuntu 20.10 以上じゃないと登録されていないらしい。
ひとまずは、リポジトリのGPGキーをインポートし、リポジトリを追加すれば Ubuntu 20.04 でもインストールできるようだ。とはいえ、これ、公式のインストール方法に書いてない(消されたらしい)し、 Docker に比べてこの点はかなりマイナスかな。。
curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_20.04/Release.key | sudo apt-key add - sudo apt-add-repository 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_20.04/ /'
そしたらあとは普通にインストール。Ubuntu 22.04 などは以下の手順からだけで行けた。
sudo apt update -qq sudo apt install -y podman
podman --version
を実行してバージョン情報が表示されれば成功。
$ podman -v podman version 3.4.2
Buildah って何?
Buildah は、コンテナイメージを作成・変更・ビルドするためのツールで、どうにも Podman と同じ文脈でよく語られてるっぽいけど、なんぞこれ?
まずは読み方。 Buildah と書いて ビルダー と読むらしい……。ボストン訛のbuilder だそうですよ。 あのさぁ、 nginx (んぎっくす と発音する) とかもそうだけど読めない名前つけるのやめてもらっていいですか? なお、私の中では びるだっち になりました。
Buildahの説明を見るとDockerfileの代わりにスクリプトを使ってイメージを作成するものとか、デーモンレスですとか、非rootで実行できますとか、全然意味わからなかった。デーモンレスとか非rootがどうのだったら、前述の Podman でビルドできるんだよね。
あれこれ悩んで、最終的に個人的には以下の理解で納得しました。
イメージ作成 | Java ビルド | 説明 |
---|---|---|
Dockerfile, Containerfile | Ant, Maven | 設定ファイルベースのビルド |
Buildah | Gradle | スクリプトベースのビルド |
Java がわからない人には意味不明な対比ですまない。しかし、私はこれで納得してしまったんだ。Dockerfileだってスクリプトじゃないかって?いや、まぁ、そりゃそうだけどさ。
BuildahはShellスクリプトのif文やfor文でより柔軟性の高いイメージビルドが可能。一方で、Dockerfileは RUN とか COPY 自体をループすることはできないし、そもそもシンプルに書くことが求められている。そういう意味で、設定ファイルベースに近いと感じたのだ。
むろん、上記の対比は Buildah のすべてを表す対比ではないけど、極端に間違った対比でもないと思います。
Ubuntu 20.04 にインストール
Buildahのインストール方法は以下のコマンドを実行すればOKでした。 Podmanのインストール後だとこのコマンド一発で普通に入ったけど、Ubuntu 20.04の場合はGPGキー登録が必要かも。 その場合はさっきの Podman の GPGキー登録を先にやってください。
sudo apt install -y buildah
Ubuntu 20.04 の問題なのかどうなのかはよくわからないけど、私の環境では WSL でも Ubuntuマシンでも以下の警告が毎回出力されました。
WARN[0000] Failed to decode the keys ["machine"] from "/usr/share/containers/containers.conf".
よくわからないが、このイシュー によると、とりあえず /usr/share/containers/containers.conf
の [machine]
をコメントアウトすれば消える模様。とりあえず、私はコメントアウトしておいたけど、いいんかね?
コンテナイメージの作成と実行
Podmanを使ってコンテナイメージを取得・実行する方法と、Buildahで作成したイメージをPodmanで実行する方法をやってみた。
Podman を使ったイメージの取得と実行
Podmanはなんと普通に Dockerfile が扱える。びっくりだ。すごいね。
コマンド体型もほとんど Docker と同じ感覚で扱えるし、何なら docker
コマンドを podman のエイリアスにしてしまう podman-docker なんてのもある。(私は入れないけど)
以下のrunを実行するとお馴染みの 「Hello from Docker!」が表示される。お馴染みのimage rm でイメージ削除できる。
podman run --rm hello-world podman image rm hello-world
ちなみに、WSLの環境だと以下のようなメッセージが表示されちゃった。
WARN[0000] "/" is not a shared mount, this could cause issues or missing mounts with rootless containers
これはなんだかよくわかんない。このイシューによると、sudo mount --make-rshared /
やwsl.exe -u root -e mount --make-rshared /
とすれば良いようだけど。
とりあえず、上記のコマンドを実行したあとに、マウントを試してみる。
$ mkdir hoge $ podman run --rm -it -v ./hoge:/hoge alpine / # ls bin etc home media opt root sbin sys usr dev hoge lib mnt proc run srv tmp var / # cd hoge /hoge # touch piyo.txt /hoge # exit $ ls -al hoge total 12 drwxr-xr-x 2 nodamushi nodamushi 4096 Apr 4 11:33 . drwxr-xr-x 3 nodamushi nodamushi 4096 Apr 4 11:32 .. -rw-r--r-- 1 nodamushi nodamushi 5 Apr 4 11:33 piyo.txt
普通にボリュームをマウントできて、ファイルも出力できてるっぽいですね。(mountのコマンドの効果なのかはよくわかんない)
あと、何よりも嬉しいのがこれ。
-rw-r--r-- 1 nodamushi nodamushi 5 Apr 4 11:33 piyo.txt
piyo.txt のファイルの権限が root じゃなくて、 nodamushi なんですよ。Dockerで同じ操作をすると、権限が root になりますよね。ひゃっほい😀
というわけで、ほとんど Docker と変わらない感じでコンテナの実行とかはできるみたい。実際にはポートとかの扱いとか細かいところはやっぱり異なるみたいだけど、プロジェクトをビルドするとかの用途では気にする必要なさそう。
Buildahで作成したイメージをPodmanで実行
Buildah でイメージを作成する手順は主に以下。
- 作業用コンテナを作成する
- Dockerfileでいう RUNやCOPY、ENV などの設定
- Dockerfile でいう CMD や ENTRYPOINT などの設定
- 作業コンテナからイメージの作成
以下のShellスクリプトを適当に保存して実行してみよう。
#!/bin/bash # 作業用コンテナの作成。 alpine イメージから作成 container=$(buildah from alpine) # 環境変数を設定する場合は config env buildah config --env MESSAGE="Hello World!" $container # Dockerfileでいう CMD は config --cmd。 ENTRYPOINT は config --entrypoint buildah config --cmd "/bin/sh -c 'echo \$MESSAGE'" $container # 作業コンテナから Image を作成 buildah commit $container my-hello-world # 作業コンテナがもういらないなら削除 buildah rm $container
上のスクリプトには書く場面がなかったけど Dockerfile でいう COPY と RUN は以下のように書くみたい。
# COPY buildah copy $container コピー元ファイル コピー先 # RUN buildah run $continer -- コマンド
作成したイメージは Podman からすぐに実行できる。Dockerから実行しようとするなら、 Docker Hub か、Private Registory を立ち上げてそこに push するしかないのかな。
$ podman run --rm my-hello-world
Hello World!
まとめ
とりあえず、初 Podman と Buildah (びるだっち) を試してみました。 Podman はデーモンレスで、 コンテナ内で root 権限のままボリュームにファイル生成してもホスト側ではユーザー権限になるのがとっても良い。
Buildah は現状そこまで必要という感じはしないかなぁ。別に Dockerfile(Containerfile)で簡単にかける範囲なら、 Dockerfile を使えばいいと思う。ループや分岐がしたくなったら、 Buildah +Podman という選択になるのかな。
以上、まぁ、ちょっとは老害を脱せたのではないでしょうか。。。