こんにちは。サイオステクノロジー OSS サポート担当 Y です。
今回は、Podman の検証実施してみました。(※以下の内容は CentOS 7.6/Podman 1.3.2 にて検証しています。)
■はじめに
先日リリースされた Red Hat Enterprise Linux 8 では、コンテナ管理ツールとして Docker ではなく Podman が同梱されています。今回は、この Podman を試してみました。
■Podman のインストール (CentOS)
今回は CentOS 7.6 で検証を行うため、まずは Podman をインストールします。
以下の通り、extras リポジトリにパッケージが用意されているため、yum でインストールします。
[root@podman-test ~]# yum list podman Loaded plugins: fastestmirror, langpacks Loading mirror speeds from cached hostfile * base: ftp.iij.ad.jp * extras: ftp.iij.ad.jp * updates: ftp.iij.ad.jp Available Packages podman.x86_64 1.3.2-1.git14fdcd0.el7.centos extras [root@podman-test ~]#
[root@podman-test ~]# yum install -y podman Loaded plugins: fastestmirror, langpacks Loading mirror speeds from cached hostfile * base: ftp.iij.ad.jp * extras: ftp.iij.ad.jp * updates: ftp.iij.ad.jp Resolving Dependencies --> Running transaction check ---> Package podman.x86_64 0:1.3.2-1.git14fdcd0.el7.centos will be installed ~(中略)~ Installed: podman.x86_64 0:1.3.2-1.git14fdcd0.el7.centos Dependency Installed: atomic-registries.x86_64 1:1.22.1-26.gitb507039.el7.centos container-selinux.noarch 2:2.99-1.el7_6 containernetworking-plugins.x86_64 0:0.7.5-2.el7.centos containers-common.x86_64 1:0.1.35-2.git404c5bd.el7.centos criu.x86_64 0:3.9-5.el7 libnet.x86_64 0:1.1.6-7.el7 protobuf-c.x86_64 0:1.0.2-3.el7 python-pytoml.noarch 0:0.1.14-1.git7dea353.el7 runc.x86_64 0:1.0.0-59.dev.git2abd837.el7.centos Complete! [root@podman-test ~]#
[root@podman-test ~]# podman version Version: 1.3.2 RemoteAPI Version: 1 Go Version: go1.10.3 OS/Arch: linux/amd64 [root@podman-test ~]#
以上でインストールは完了です。
■動作検証
では、さっそく Podman を使ってコンテナを起動してみます。
以下の様に、podman コマンドには様々なサブコマンドが用意されていますが、見たところ docker コマンドとほぼ同じ雰囲気で使えそうです。
[root@podman-test ~]# podman help manage pods and images Usage: podman [flags] podman [command] Available Commands: attach Attach to a running container build Build an image using instructions from Dockerfiles commit Create new image based on the changed container container Manage Containers cp Copy files/folders between a container and the local filesystem create Create but do not start a container diff Inspect changes on container's file systems events Show podman events exec Run a process in a running container export Export container's filesystem contents as a tar archive generate Generated structured data healthcheck Manage Healthcheck help Help about any command history Show history of a specified image image Manage images images List images in local storage import Import a tarball to create a filesystem image info Display podman system information init Initialize one or more containers inspect Display the configuration of a container or image kill Kill one or more running containers with a specific signal load Load an image from container archive login Login to a container registry logout Logout of a container registry logs Fetch the logs of a container mount Mount a working container's root filesystem pause Pause all the processes in one or more containers play Play a pod pod Manage pods port List port mappings or a specific mapping for the container ps List containers pull Pull an image from a registry push Push an image to a specified destination restart Restart one or more containers rm Remove one or more containers rmi Removes one or more images from local storage run Run a command in a new container save Save image to an archive search Search registry for image start Start one or more containers stats Display a live stream of container resource usage statistics stop Stop one or more containers system Manage podman tag Add an additional name to a local image top Display the running processes of a container umount Unmounts working container's root filesystem unpause Unpause the processes in one or more containers unshare Run a command in a modified user namespace version Display the Podman Version Information volume Manage volumes wait Block on one or more containers Flags: --cgroup-manager string Cgroup manager to use (cgroupfs or systemd, default systemd) --cni-config-dir string Path of the configuration directory for CNI networks --config string Path of a libpod config file detailing container server configuration options --conmon string Path of the conmon binary --cpu-profile string Path for the cpu profiling results --default-mounts-file string Path to default mounts file --help Help for podman --hooks-dir strings Set the OCI hooks directory path (may be set multiple times) --log-level string Log messages above specified level: debug, info, warn, error, fatal or panic (default "error") --namespace string Set the libpod namespace, used to create separate views of the containers and pods on the system --network-cmd-path string Path to the command for configuring the network --root string Path to the root directory in which data, including images, is stored --runroot string Path to the 'run directory' where all state information is stored --runtime string Path to the OCI-compatible binary used to run containers, default is /usr/bin/runc --storage-driver string Select which storage driver is used to manage storage of images and containers (default is overlay) --storage-opt strings Used to pass an option to the storage driver --syslog Output logging information to syslog as well as the console --tmpdir string Path to the tmp directory --trace Enable opentracing output --version Version for podman Use "podman [command] --help" for more information about a command. [root@podman-test ~]#
試しに DockerHub で公開されている hello-world コンテナを起動してみます。
[root@podman-test ~]# podman run docker.io/hello-world:latest Trying to pull docker.io/hello-world:latest...Getting image source signatures Copying blob 1b930d010525 done Copying config fce289e99e done Writing manifest to image destination Storing signatures Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker ID: https://hub.docker.com/ For more examples and ideas, visit: https://docs.docker.com/get-started/ [root@podman-test ~]# [root@podman-test ~]# podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4a830faa1d48 docker.io/library/hello-world:latest /hello 11 seconds ago Exited (0) 10 seconds ago boring_bose [root@podman-test ~]# [root@podman-test ~]# podman rm boring_bose 4a830faa1d48f8a0436d9fdc8be840a99810a7d683340cfccfac66435fce4590 [root@podman-test ~]# [root@podman-test ~]# podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [root@podman-test ~]# [root@podman-test ~]# podman image ls REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/library/hello-world latest fce289e99eb9 5 months ago 6.14 kB [root@podman-test ~]#
すると、上記の通り hello-world の Image を Pull して実行することができました。Image がローカルに Pull されていることも確認できます。
次に、NGINX のコンテナを起動してみます。サブコマンドだけでなく、”-d” や “-p” のオプションについても、docker コマンドと同じ感覚で使えるようです。
[root@podman-test ~]# podman run -d -p 8080:80 docker.io/nginx:latest Trying to pull docker.io/nginx:latest...Getting image source signatures Copying blob fc7181108d40 done Copying blob 780053e98559 done Copying blob c4277fc40ec2 done Copying config 719cd2e3ed done Writing manifest to image destination Storing signatures f7df535966a52ea10194521076c04ff20e3a814ed3390d34494bd4da797a2bbc [root@podman-test ~]# [root@podman-test ~]# podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f7df535966a5 docker.io/library/nginx:latest nginx -g daemon o... 5 seconds ago Up 4 seconds ago 0.0.0.0:8080->80/tcp unruffled_jones [root@podman-test ~]#
[root@podman-test ~]# podman run --help | grep "publish" -p, --publish strings Publish a container's port, or a range of ports, to the host (default []) -P, --publish-all Publish all exposed ports to random ports on the host interface [root@podman-test ~]# [root@podman-test ~]# podman run --help | grep "detach" -d, --detach Run container in background and print container ID --detach-keys [a-Z] Override the key sequence for detaching a container. Format is a single character [a-Z] or `ctrl-` where ` ` is one of: `a-z`, `@`, `^`, `[`, `\`, `]`, `^` or `_` [root@podman-test ~]#
引数 “-p” で指定した 8080 port でリクエストを LISTEN していることも確認でき、リクエストを実行すると、NGINX からのレスポンス (デフォルトの index.html ファイルの内容) が返ってきます。
[root@podman-test ~]# netstat -tnlp | grep 8080 tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 5967/conmon [root@podman-test ~]# [root@podman-test ~]# curl -XGET https://localhost: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="https://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="https://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html> [root@podman-test ~]#
また、podman exec を使ってコンテナ内でコマンドを実行 (今回はコンテナ内で bash コマンドを実行し、検証のために index.html の内容を書き替え) することもできました。
[root@podman-test ~]# podman exec -it unruffled_jones /bin/bash root@f7df535966a5:/# root@f7df535966a5:/# echo "Podman Test" > /usr/share/nginx/html/index.html root@f7df535966a5:/# root@f7df535966a5:/# cat /usr/share/nginx/html/index.html Podman Test root@f7df535966a5:/# root@f7df535966a5:/# exit exit [root@podman-test ~]# [root@podman-test ~]# curl -XGET https://localhost:8080/ Podman Test [root@podman-test ~]#
コンテナの停止/削除等も docker と同じ様に stop/rm サブコマンドで実行できました。
[root@podman-test ~]# podman stop unruffled_jones f7df535966a52ea10194521076c04ff20e3a814ed3390d34494bd4da797a2bbc [root@podman-test ~]# [root@podman-test ~]# podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [root@podman-test ~]# [root@podman-test ~]# podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f7df535966a5 docker.io/library/nginx:latest nginx -g daemon o... 26 seconds ago Exited (0) 7 seconds ago 0.0.0.0:8080->80/tcp unruffled_jones [root@podman-test ~]# [root@podman-test ~]# podman rm unruffled_jones f7df535966a52ea10194521076c04ff20e3a814ed3390d34494bd4da797a2bbc [root@podman-test ~]#
■まとめ
今回は、Podman を利用した基本的なコンテナ操作を実行してみました。
Podman はリリースされて間もない新しい OSS ではありますが、今回検証を行なった範囲では docker コマンドとほぼ同じ感覚で使うことができたので、既に Docker を利用している場合は、ある程度学習コストを抑えて Podman を利用することができるのではないでしょうか。
今回の記事では触れませんでしたが、Podman には (Docker と違って) daemon を起動する必要がない、等の特徴もあるらしいので、そのあたりの動作についても少し検証してみようと思います。