Podmanをコンテナ内で動かす「Podman in Podman」の2つのポイント

Red Hatでソリューションアーキテクトをしている田中司恩(@tnk4on)です。

Podmanはコンテナを実行するツールであることはよく知られてますが、そのPodmanを「コンテナ内で実行する」ことができるのはご存知でしょうか?今回はこの「Running Podman within a container」のポイントを2つピックアップしてご紹介します。 Podmanをコンテナ内で動かす取り組みにはPodman上で動かす「Podman in Podman(PINP)」やKubernetes上のPod内で動かす方法などがありますが、今回は前者を対象として取り上げたいと思います。

さて、本題に入る前に余談。Podmanのロゴのキャラクターは何なのか?と、まれに話題になりますが、答えは前回記事で紹介した「Podman in Action」の中にありました。

Podmanのロゴ
Podmanのロゴ

The Podman logo in figure 1.2 is a group of Selkies, the Irish concept of a mermaid. Groups of Selkies are called pods.

図1.2のPodmanロゴは、アイルランドの人魚の概念であるセルキーのグループです。セルキーのグループはポッドと呼ばれます。

ここで出てくるセルキーはWikipediaによると「ふだんは海中で生活しているが、陸にあがるときは「アザラシの皮」を脱いで人間と化すると言われている。」と書かれています。よく言われる「Podmanはアザラシ」というのもあながち間違っていないような気もしますね。*1

-目次-


Podmanをコンテナ内で動かす目的

コンテナの実行環境自体をコンテナ内で動かす取り組み自体は目新しい技術ではありません。Dockerは公式イメージとして「Docker-in-Docker(DIND)」のコンテナイメージを以前から公開しています

docker - Official Image | Docker Hub

主要な目的の1つはコンテナ実行ツール自体の開発に利用できる、というものです(DockerならDocker、PodmanならPodmanの開発)。コンテナの特性を活用することで、開発途中のバージョンを迅速かつ簡単に実行することができます。これにより、継続的な開発がより便利になります。

このことはツールの開発だけでなく、一般的なPodmanの利用にも活かすことができます。 例えばPodmanのバージョンアップのテストに使用することができます。コンテナ内でPodmanを動かすことで、ホストマシンに影響を与えることなく、異なるバージョンのPodmanをテストすることができます。これにより、アプリケーションが互換性のあるPodmanバージョンを使用していることを確認できます。

また、Podmanをコンテナ内で動かすことは、CI(継続的インテグレーション)での使用にも役立ちます。CIシステムは、アプリケーションをビルド、テスト、デプロイするために、複数の環境を使用する必要があります。コンテナ内でPodmanを実行することにより、CIシステムは同じ環境を再現することができ、アプリケーションの品質と安定性を維持することができます。

つまり、Podmanをコンテナ内で動かすことは、アプリケーションの開発やテストをスムーズに行うための重要な手段の一つであり、効果的なCIプロセスの実現にも不可欠です。

参考となるリソース

コンテナ内でPodmanを実行するために役立つリソースが2つあります。

この2つがカバーしている範囲は少し異なるので両方を合わせて確認することをお勧めします。

上記2つのリソースからポイントとなる点を2つピックアップしてみました。

  • Podmanコンテナイメージ
  • セキュリティオプションの組み合わせ

これらの内容についてご紹介します。

Podmanコンテナイメージ

Dockerと同様に、Podmanもコンテナ内で動かすコンテナイメージが公式から提供されています。

podman/stable · Quay

このコンテナイメージのビルドの元になったContainerfilecontainers.confがPodmanのGitHubリポジトリで公開されています。

podman/contrib/podmanimage/stable at main · containers/podman · GitHub

ブログ記事 ではこのContainerfileの各プロセスについて詳細な解説があります。中身を見ていくとベースイメージはPodmanの開発やテスト版のパッケージのリリースに使われるFedoraが使われていることが分かります。また、1つのコンテナイメージでルートフルとルートレスの2つのモードに対応できるように、事前定義済みのcontainers.confを利用したり、適切なUIDの設定(主にルートレス向け)やコンテナ内でfuse-overlayfsを実行する工夫が行われています。これらの工夫は普段のContainerfileの作成にも役立てるのではないでしょうか。

公開されているコンテナイメージのバージョンはv3.3.0が最も古く、そこからPodmanのリリースごとのバージョンが揃っています。特定のPodmanのバージョンのイメージを使ってテストするなんて場合にも便利ですね。またQuay.ioのリポジトリ上で定期的なコンテナイメージのスキャンが行われており、コンテナイメージの脆弱性情報も確認できるので安心して使うことができます。

Podmanコンテナイメージ自体の解説や使用方法について、リポジトリのREADMEにも記載があるのでそちらも是非参考にしてください。

セキュリティオプション

もう一つのポイントがPodmanコンテナイメージを実行する時に付与するセキュリティオプションです。コンテナ内でコンテナ実行ツールを動かすためには強い権限が必要となります。いくつかの工夫はPodmanコンテナイメージで対応されていますが、実際にはコンテナ実行時(podman run)にも適切なセキュリティオプションの付与が必要です。一番簡単な解決方法は--privilegedフラグをつけて実行することです。ほとんどの場合はこれで事足りるはずです。ですが--privilegedは不必要な権限も与えてしまう恐れがあります。そこでブログ記事Podman in Actionでは--privilegedを使わずに必要なセキュリティオプションのみを与える解説が行われています。Podmanではルートフル、ルートレスの2つのモードがあるので実行するホスト、モードの組み合わせは下記のようになります。

<ホストモード - コンテナモード>

  • ルートフル - ルートフル
  • ルートフル - ルートレス
  • ルートレス - ルートフル
  • ルートレス - ルートレス

これらのモードの組み合わせで必要なセキュリティオプションをまとめた表が下記になります(Podman in Actionより、転載)。

ホストモード コンテナモード セキュリティオプション 解説
ルートフル ルートフル CAP_SYS_ADMIN ホストユーザーのネームスペースへのフルアクセス権を持つ
ルートフル ルートレス CAP_SETUID, CAP_SETGID コンテナ内の/etc/subuidと/etc/subgidに基づく別のユーザーのネームスペースで実行される
ルートレス ルートフル Namespaced CAP_SYS_ADMIN ユーザーのユーザーネームスペースへのフルアクセス権を持つ
ルートレス ルートレス Namespaced CAP_SETUID, CAP_SETGID コンテナ内の /etc/subuid と /etc/subgid に基づく別のユーザーネームスペースで実行される。ユーザーネームスペースは、Podmanコマンドを実行しているユーザーネームスペースのサブセットである必要がある。

これらの詳細な解説はご紹介した2つの参考リソースにお任せするとして、ポイントをまとめるとこのようになります。

  • Podmanでは実行するモードの組み合わせにより4つのパターンがあり、それぞれに適切なセキュリティオプションを付与して実行する(Podman in Actionの表 8.1を参照)

まとめ

今回ご紹介した2つの参考リソースはPodmanをコンテナ内で実行する際に必要となる情報がしっかりと記載されていますので是非参考にしてください。また、セキュリティオプションについては、--privilegedを使わない場合のコンテナ実行の仕組みはどうなっているのかということを考えるのに良い機会だと思います。さらに、PodmanコンテナイメージはPodmanだけでなくDockerやKubernetes上でも実行できます(PINP、PIND、PINK...)。参考リソースを活用してさまざまな場面でコンテナ内でPodmanを実行することに挑戦してみてください。

*1:今回記事のサムネ絵はセルキーをイメージしてBing Image Creatorに書いてもらいました。

* 各記事は著者の見解によるものでありその所属組織を代表する公式なものではありません。その内容については非公式見解を含みます。