Podmanでコンテナ分離

Posted by 雅楽斎 on Tuesday, October 22, 2019

TOC

DockerとPodmanの違い

大雑把に違いを挙げるとすると、Dockerはdaemonが常駐してCUIから実行したコマンドはDockerのdaemon経由で実行されます。また、daemonはroot権限で実行されます。

片やPodmanはdaemonとして常駐せず、コンテナを実行するにあたってroot権限が必要とされることがないことが特徴です。

今回の実行環境は以下の通りです。

  • Ubuntu MATE 19.10 amd64

Podmanのインストール(追記:Kubic projectがビルドしたパッケージをインストール)

(以前とはインストール方法が変わりました)

containers/libpod

libpod is a library used to create container pods. Home of Podman. - containers/libpod

Ubuntu向けのPodmanパッケージはKubic projectがビルドしたものを使用します。/etc/os-releaseファイルからディストロ名とリリースを取得してapt-lineを追加しています。

$ . /etc/os-release

この部分は手元のamd64/eoan環境では以下と同じ処理になります。

$ export NAME="Ubuntu"
$ export VERSION_ID="19.10"

続けて公開鍵のインポートとパッケージのインストールをします。個人的にsudoは極力使わない主義なのでrootユーザーで以下をまるごと実行します。

# export NAME="Ubuntu"
# export VERSION_ID="19.10"
# echo "deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/x${NAME}_${VERSION_ID}/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
# wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/x${NAME}_${VERSION_ID}/Release.key -O Release.key
 
2020-01-20 08:52:27 URL:https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_19.10/Release.key [1094/1094] -> "Release.key" [1]
# apt-key add - < Release.key
OK
# apt-get update -qq
# apt-get install podman
$ podman --version
podman version 1.7.0
WARN[0000] unable to find /home/hogehoge/.config/containers/registries.conf. some podman (image shortnames) commands may be limited 

これを書いている時点ではKubic projectを使用して以下のディストロ用のパッケージが公開されているようです。

  • Ubuntu 16.04(amd64)
  • Ubuntu 18.04(amd64)
  • Ubuntu 19.04(amd64)
  • Ubuntu 19.10(amd64/armhf/arm64)
  • Debian 10(amd64/armhf/arm64/ppc64el)
  • Debian Testing(amd64/armhf/arm64/ppc64el)
  • Debian Unstable(amd64/armhf/arm64/ppc64el)
  • Raspbian 9.0(armhf)
  • Raspbian 10(armhf)

podmanパッケージがなぜかdockerのmanを持っているので仕方なく上書きインストールする

最近のバージョンのpodmanパッケージはなぜかdockerのmanを内包していて、docker-ceをインストールした状態でpodmanをインストールしようとすると競合します。

# apt-get install podman
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
以下のパッケージが新たにインストールされます:
  podman
アップグレード: 0 個、新規インストール: 1 個、削除: 0 個、保留: 0 個。
20.1 MB 中 0 B のアーカイブを取得する必要があります。
この操作後に追加で 89.2 MB のディスク容量が消費されます。
以前に未選択のパッケージ podman を選択しています。
(データベースを読み込んでいます ... 現在 264565 個のファイルとディレクトリがインストールされています。)
.../podman_1.7.0~3_amd64.deb を展開する準備をしています ...
podman (1.7.0~3) を展開しています...
dpkg: アーカイブ /var/cache/apt/archives/podman_1.7.0~3_amd64.deb の処理中にエラーが発生しました (--unpack):
 '/usr/share/man/man1/docker-attach.1.gz' を上書きしようとしています。これはパッケージ docker-ce-cli 5:19.03.3~3-0~ubuntu-disco にも存在します
dpkg-deb: エラー: ペースト subprocess was killed by signal (Broken pipe)
処理中にエラーが発生しました:
 /var/cache/apt/archives/podman_1.7.0~3_amd64.deb
E: Sub-process /usr/bin/dpkg returned an error code (1)

manが重複するというよくわからない理由で共存できないのもおかしな話なので、強制的にインストールします。やってみると競合するのは実は57ファイルです。

centos-8: packaging podman-manpages in conflict with docker-ce · Issue #4791 · containers/libpod

This is clearly linked to https://bugs.centos.org/view.php?id=16892 see file /usr/share/man/man1/docker-attach.1.gz from install of podman-manpages-1.4.2-5.module_el8.1.0+237+63e26edc.noarch confli...

Same issue in debian + ubuntu packages work around is sudo apt install -o Dpkg::Options::="--force-overwrite" podman

# apt install -o Dpkg::Options::="--force-overwrite" podman
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
以下のパッケージが新たにインストールされます:
  podman
アップグレード: 0 個、新規インストール: 1 個、削除: 0 個、保留: 0 個。
20.1 MB 中 0 B のアーカイブを取得する必要があります。
この操作後に追加で 89.2 MB のディスク容量が消費されます。
(データベースを読み込んでいます ... 現在 264565 個のファイルとディレクトリがイン
ストールされています。)
.../podman_1.7.0~3_amd64.deb を展開する準備をしています ...
podman (1.7.0~3) を展開しています...
dpkg: 警告: --force が有効なので、問題を無視します:
dpkg: 警告: '/usr/share/man/man1/docker-attach.1.gz' を上書きしようとしています
。これはパッケージ docker-ce-cli 5:19.03.3~3-0~ubuntu-disco にも存在します
(略)
dpkg: 警告: --force が有効なので、問題を無視します:
dpkg: 警告: '/usr/share/man/man1/docker.1.gz' を上書きしようとしています。これは
パッケージ docker-ce-cli 5:19.03.3~3-0~ubuntu-disco にも存在します
podman (1.7.0~3) を設定しています ...
man-db (2.8.7-3) のトリガを処理しています ...

まずはhello-world

$ podman container run hello-world
Error: unable to pull hello-world: image name provided is a short name and no search registries are defined in the registries config file.

実行できません。docker.ioからイメージを借りてきましょう。

$ podman container run docker.io/hello-world
Trying to pull docker.io/hello-world...
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/

docker.ioにあるdockerのコンテナはOCIというコンテナの標準化規格に沿って作成されています。

片やPodmanで利用できるコンテナもOCIコンテナであるため、docker.ioにあるコンテナ自体はそのままPodmanで利用可能です。

上の実行コマンドで、podman runの引数に「docker.io/hello-world」と指定することで、docker.ioに登録されているhello-worldを実行することができます。

1回取得したPodman imageは次回以降はそのまま実行できます。取得したイメージはpodman image lsで確認できます。

$ podman image ls -a
REPOSITORY                      TAG      IMAGE ID       CREATED        SIZE
docker.io/library/hello-world   latest   fce289e99eb9   9 months ago   6.14 kB

コンテナ一覧はpodman container ls

$ podman container ls -a
CONTAINER ID  IMAGE                                 COMMAND  CREATED         STATUS                     PORTS  NAMES
c34087f92f99  docker.io/library/hello-world:latest  /hello   28 seconds ago  Exited (0) 27 seconds ago         goofy_wing

削除はpodman image rmでできます。

$ podman image rm fce
Untagged: docker.io/library/hello-world:latest
Deleted: fce289e99eb9bca977dae136fbe2a82b6b7d4c372474c9235adc1741675f587e

このあたりのコマンドもdocker互換になっています。

とはいえ毎回引数にdocker.ioって入れるのも面倒なので

dockerの場合はデフォルトでdocker.ioを参照していますが、Podmanの場合は手動で管理します。手動で管理することで、サードパーティーのコンテナレジストリの管理も同様に行なえます。

記述するファイルは/etc/containers/registries.confです。記述はtomlで行います。

[registries.search]
registries = ['docker.io']

[registries.insecure]
registries = []

[registries.block]
registries = []

設定値としてはsearch、insecure、blockを記載します。今の所は検索用としてdocker.ioを追加するだけの設定です。

これを記載することで、podman runやpodman pull等の際にdocker.io/を追加する必要がなくなります。

例:nginx:latestを取得・実行する

$ podman image pull nginx:latest
Trying to pull docker.io/library/nginx:latest...
Getting image source signatures
Copying blob 047cb16c0ff6 done
Copying blob 8d691f585fa8 done
Copying blob b0bbed1a78ca done
Copying config 5a9061639d done
Writing manifest to image destination
Storing signatures
5a9061639d0aeca4b13f8e18b985eea79e55168969d069febdb6723993ebba7d

取得したイメージからコンテナの作成をします。

$ podman container create --name demo-nginx -p 8080:80 5a9061639d0
7259d3f19d17e55056e31b3c0b7d9b70ed58ee7f35ec9bbe4c0ca53d1b5aa2bb

コンテナの確認をします。

$ podman container ls -a
CONTAINER ID  IMAGE                                 COMMAND               CREATED        STATUS                    PORTS                 NAMES
7259d3f19d17  docker.io/library/nginx:latest        nginx -g daemon o...  5 minutes ago  Created                   0.0.0.0:8080->80/tcp  demo-nginx

起動してみましょう。

$ podman container start 725
7259d3f19d17e55056e31b3c0b7d9b70ed58ee7f35ec9bbe4c0ca53d1b5aa2bb

ブラウザから http://localhost:8080 へアクセスしてnginxが実行されることを確認。

コンテナを停止します。

$ podman container stop 725
7259d3f19d17e55056e31b3c0b7d9b70ed58ee7f35ec9bbe4c0ca53d1b5aa2bb

コンテナを削除します。

$ podman container rm 725
7259d3f19d17e55056e31b3c0b7d9b70ed58ee7f35ec9bbe4c0ca53d1b5aa2bb

削除の確認。

$ podman container ls -a
CONTAINER ID  IMAGE                                 COMMAND  CREATED        STATUS                    PORTS  NAMES

docker-composeがない

定型的なコンテナの実行をする場合、Dockerでは複数コンテナの起動順などをYAMLに書いて運用を容易にするdocker-composeという補助コマンドがありますが、現状Podmanでこの用途に使われる補助コマンドは提供されていません。

pipでインストール可能なpodman-composeをサードーパーティーで提供する開発者はいます。

containers/podman-compose

a script to run docker-compose.yml using podman. Contribute to containers/podman-compose development by creating an account on GitHub.

まとめ

他にもswarmやKubernetesでの運用など、Dockerを中心としたエコシステムが巨大なため、すでに広くDockerで運用している場合は置換対象にならないかもしれませんが、一般ユーザーで実行できることや単発でコンテナを実行したい場合など、コマンド実行感覚で手軽に実行できるコンテナ仮想化としてPodman。いかがでしょうか。


comments powered by Disqus