はじめに
Fedora 33をダウンロードしたので、Podmanでも触ってみることにした。
yum install podman
でインストールされたのは 2.1.1だった。
[root@fedora33 ~]# cat /etc/fedora-release Fedora release 33 (Thirty Three) [root@fedora33 ~]# uname -a Linux fedora33.localdomain 5.9.10-200.fc33.x86_64 #1 SMP Mon Nov 23 18:12:50 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux [root@fedora33 ~]# podman --version podman version 2.1.1
podman runのオプションに --read-only
というオプションを見つけた。
--read-onlyはコンテナのルートファイルシステムを読み取り専用にするオプションだそうだ。
[root@fedora33 ~]# podman run --read-only -itd fedora:33 [root@fedora33 ~]# podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 027a45af287b registry.fedoraproject.org/fedora:latest /bin/bash 5 seconds ago Up 5 seconds ago charming_murdock [root@fedora33 ~]# podman exec -it charming_murdock bash [root@027a45af287b /]# pwd / [root@027a45af287b /]# touch hoge touch: cannot touch 'hoge': Read-only file system [root@027a45af287b /]# cd /root/ [root@027a45af287b ~]# touch hoge touch: cannot touch 'hoge': Read-only file system [root@027a45af287b ~]#
確かに書き込みができない。ただこのオプションを使う場合、アプリケーションコンテナーイメージが対応している必要がある模様。 centos:8
というイメージと、fedora:33
というイメージは問題なく利用できたが、 nginx:alpine
などは使うことができなかった。
今回はFedora 33を使ったのでControl Group v2が標準になっている。 Fedoraはバージョン32でControl Group v2をデフォルトにしたので、Control Group v2に対応していない(20.10以前のバージョンの)Dockerや低レイヤーランタイムである(v1.0.0-rc93以前の)runCはControl Group v2では動かないらしい(当時はFedora 33ではいずれも該当していたため動かなかった)。
Fedora 33でインストールできるPodmanの設定をみたがデフォルト設定はrunCになっていた。おそらくPodman側がインストールされている低レイヤーランタイムでcgorupのバージョンを判定して適切な方を使っているんだろう。
[root@fedora33 ~]# podman --runtime /usr/bin/runc run --rm fedora:33 echo it works ERRO[0000] oci runtime "runc" does not support CGroups V2: use system migrate to mitigate Error: this version of runc doesn't work on cgroups v2: OCI runtime error [root@fedora33 ~]# podman --runtime /usr/bin/crun run --rm fedora:33 echo it works it works
[2/9/2021 追記] Docker 20.10以降はControl Group v2をサポートしている。
Fedora32 31以降でFedoraパッケージの(20.10以前の)moby-engineと(v1.0.0-rc93以前の)runCを使うには、カーネルオプションでControl Group v1を使うように設定すれば使える(同様にPodmanでrunCを使いたい場合も)。DockerがControl Group v2をサポートするのはDocker 20.10くらいを予定しているらしい。 -> Docker 20.10でサポートされた。
[4/5/2021 追記] runCがrunc-1.0.0-375.dev.git12644e6.fc33.x86_64
に更新されたため、Control Group v2で実行していても動作するようになった。ただし、Fedora 33のmoby-engineは更新されておらず、Fedoraのmoby-engineパッケージを使う場合はv1での利用が必要である。月末にリリース予定のFedora 34ではDcoker 20.10ベースのmoby-engineパッケージが提供される予定。
[root@localhost ~]# podman --version podman version 3.0.1 [root@localhost ~]# podman --runtime /usr/bin/runc run --rm --memory 4M fedora echo it works it works [root@localhost ~]# podman --runtime /usr/bin/crun run --rm --memory 4M fedora echo it works it works
runCとcrun
runCはいろいろなコンテナーランタイムのベースとして動いている。そのため低レイヤーランタイムなどと呼ばれるらしい。 runCはOCI仕様に基づいて、コンテナ生成・実行などを行うコンテナランタイムである。
runCはGo言語で書かれているが、crunはC言語で書き直された。crunもOCI Container Runtime仕様に準拠しているランタイムである。
高速に動き、メモリフットプリントが少ないランタイムだそうだ。ソースは公開されているため、多くのLinuxで利用できる。
ただし、runCはControl Group v2に現状は対応していないので、Fedora 33を使うと自動的にcrunを使うことになる。crunは --pids-limit 1
を指定してPIDに制限を加えても動くらしい。驚異的である。
crun開発の経緯は以下に書かれていた。
ユーザー的な立場としては、同じように動くならより軽量かつセキュアであればrunCだろうとcrunだろうと意識することはないと思う。
Podmanの設定
Podmanの設定は /usr/share/containers/containers.conf
にデフォルトのファイルがあるので、 /etc/containers/containers.conf
とかにコピーしておけば良いらしい。コンテナーイメージレジストリーの設定は /etc/containers/registries.conf
にある。デフォルトでは次のような設定がされているため、FedoraやCentOSのイメージは各プロジェクトが用意するイメージが使われる。Docker HubのイメージPull制限対策がされており、安心だ。
unqualified-search-registries = ['registry.fedoraproject.org', 'registry.access.redhat.com', 'registry.centos.org', 'docker.io']
play kube モード
Dockerにはdocker-composeという、YAMLにデプロイする内容を書いてコンテナーアプリケーションを配備する方法がある。Podmanにもサードパーティのpodman-composeというのもあるが、公式のものではない。
その一方、Podmanは名前が示すようにPodを作ることができる。そして、 play kube
モードを使うと、KubernetesのYAMLファイルを使ってPodを作ることが可能である。というわけで、まずは次のようなYAMLファイルを作って試してみることにした。
apiVersion: v1 kind: Pod metadata: name: hello-busybox spec: containers: - name: busybox image: busybox tty: true
実行するとあっという間にPodが作成される。
[root@fedora33 ~]# podman play kube bustbox-pod.yaml Pod: a996a20fb08d4adb657167b77919ec08d58c876f5a2d04e45113c62a3dfeef3c Container: daefbabc874527a2acb95440ac83d565dddc527cfdf8da76263be5ff670734fb
作成されたPodは podman pod
コマンドを使って停止、再開、再起動、削除などの操作を行う。
[root@fedora33 ~]# podman pod ls POD ID NAME STATUS CREATED # OF CONTAINERS INFRA ID a996a20fb08d hello-busybox Running 45 seconds ago 2 aac8f79420cc
作成したPodのシェルには podman container exec
(もしくは podman exec
) コマンドを使って入る。
[root@fedora33 ~]# podman container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 784d18aa0dc7 k8s.gcr.io/pause:3.2 7 seconds ago Up 7 seconds ago 0c87158becab-infra 8e3136f61680 busybox sh 7 seconds ago Up 7 seconds ago hello-busybox-busybox [root@fedora33 ~]# podman container exec -it hello-busybox-busybox sh / #
Podを削除するときは podman pod stop
した後 podman pod rm
で削除出来る。 kubectl delete -f pod.yaml
のようにはできないのでちょっとだけここら辺は違うので覚える必要がある。
では、もう少し複雑なYAMLを用意してみる。これはNGINXのコンテナーイメージを使ってPodを作る例である。 Kubernetesの場合、アプリケーションを外部公開する場合はサービスというものを使うが、PodmanのPlay kubeではhostPortでアクセスを許可するポートを指定している。
apiVersion: v1 kind: Pod metadata: name: nginx-pod spec: containers: - name: nginx-container image: nginx ports: - containerPort: 80 hostPort: 8080
これを使ってPodを作ってみる。 「http://ipaddress-or-fqdn:8080」をブラウザーやcurlコマンドを使うとNGINXのデフォルトページが表示されるはずである。
[root@fedora33 ~]# podman play kube nginx-pod.yaml [root@fedora33 ~]# curl http://172.16.131.4:8080 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
ちなみに、Deployment YAMLファイルでもplay kubeでPodを作ることはできるようだった。ただし、基本的にはPodと一緒だが、残念ながらreplicasは思ったようには動かない。それをやりたければCRI-Oをランタイムとして、Kubernetesを使うか、k3sやmicrok8sといったものを利用するべきだろう。
--- apiVersion: apps/v1 kind: Deployment metadata: name: nginxapp1 spec: replicas: 1 selector: matchLabels: app: nginxapp1 template: metadata: labels: app: nginxapp1 spec: containers: - name: nginxapp1 image: nginx:alpine ports: - containerPort: 80 hostPort: 8080
というわけで、今回はFedora 33で割と新しいPodman 2.1.1を使ってみた。
play kubeモードも割と使えるらしいのと、セキュアなコンテナー環境を目指すと「Linux capabilities」、「SELinux」、いろいろなランタイムのサポートは切っても切り離せないので、Podmanが高機能かつ色々便利になっているのが知られてよかった。
ちょっと早いけど、冬休みの宿題のその1は完了である。
追記
他のOSで試すには Podman Installation Instructionsを参照。 RHEL 8.3では Podman 2.0系のパッケージが利用可能だそうです。また、Ubuntu 20.10より、標準パッケージにPodmanが追加されています。