インフラエンジニアの羅針盤

インフラエンジニア1〜3年目のための技術ガイド

AlmaLinux 9 Podman コンテナ管理

公開更新

AlmaLinux 9 ではコンテナ管理の標準ツールとして Podman が採用されています。RHEL 9 系では Docker パッケージが公式リポジトリから提供されておらず、Podman がその役割を担います。本記事では、Podman のインストールからイメージ・コンテナの基本操作、Containerfile によるイメージビルド、ボリュームやネットワークの管理、systemd 連携(Quadlet)、ルートレスコンテナの仕組み、podman-compose の概要、そして企業環境で必要となるプロキシやプライベートレジストリの設定までを、実行例つきでまとめています。入社1〜3年目のインフラエンジニアが、コンテナ運用の実務で参照できるリファレンスとして構成しました。

目次
  1. コマンド早見表
  2. 前提条件
  3. 1. Podman の基本概念
  4. 2. インストールと初期設定
    1. Podman のインストール
    2. プロキシ設定
    3. レジストリ設定
    4. レジストリへのログイン
  5. 3. コンテナの基本操作
    1. コンテナのバックグラウンド実行
    2. 対話モードでの実行
    3. コンテナ一覧の確認
    4. コンテナの停止・起動・再起動
    5. コンテナの削除
    6. ログの確認
    7. 稼働中コンテナへの接続
    8. コンテナの詳細情報
    9. コンテナ内プロセスの確認
  6. 4. イメージ管理
    1. イメージの取得
    2. イメージ一覧の確認
    3. イメージの削除
    4. ダングリングイメージの一括削除
    5. イメージの保存と読み込み(オフライン環境用)
    6. イメージへのタグ付け
  7. 5. Containerfile による自作イメージ
    1. 基本構文
    2. イメージのビルド
    3. .containerignore ファイル
    4. マルチステージビルド(概要)
  8. 6. データ永続化(ボリューム)
    1. バインドマウント
    2. 名前付きボリューム
    3. 読み取り専用マウント
  9. 7. ネットワーク
    1. ポートフォワーディング
    2. ユーザー定義ネットワーク
    3. ホストネットワークの使用
  10. 8. systemd 連携(Quadlet)
    1. .container ユニットファイルの書き方
    2. Quadlet の適用と起動
    3. レガシー方式: podman generate systemd(参考)
    4. ルートレスでの自動起動に必要な設定
  11. 9. ルートレスコンテナ
    1. ユーザー名前空間の仕組み
    2. ルートレスの制約
    3. 1024 未満ポートのバインド
    4. root 実行との使い分け
    5. loginctl enable-linger
  12. 10. podman-compose(概要)
    1. インストール
    2. 基本操作
    3. Pod の概要
  13. 11. 運用 Tips
    1. 不要リソースの一括削除
    2. リソース使用状況の確認
    3. イベントログ
  14. トラブルシューティング
    1. podman pull でタイムアウトする
    2. ボリュームマウントで Permission denied が出る
    3. ルートレスで 1024 未満のポートがバインドできない
    4. systemctl でコンテナが起動しない
    5. イメージビルドでパッケージインストールが失敗する

コマンド早見表

やりたいことコマンド
Podman インストールdnf install -y podman
バージョン確認podman –version
環境情報確認podman info
イメージ取得podman pull イメージ名
イメージ一覧podman images
イメージ削除podman rmi イメージID
コンテナ起動(バックグラウンド)podman run -d –name 名前 イメージ
コンテナ起動(対話モード)podman run -it –rm イメージ /bin/sh
コンテナ一覧podman ps / podman ps -a
コンテナ停止podman stop コンテナ名
コンテナ削除podman rm コンテナ名
ログ表示podman logs コンテナ名
コンテナに接続podman exec -it コンテナ名 /bin/sh
イメージビルドpodman build -t タグ .
ボリューム作成podman volume create 名前
ネットワーク作成podman network create 名前
不要リソース一括削除podman system prune
リソース使用状況podman stats
イメージ保存(オフライン用)podman save -o ファイル.tar イメージ
イメージ読み込みpodman load -i ファイル.tar

前提条件

項目
OSAlmaLinux 9.6(Sage Margay)
Podman5.6.0
コンテナランタイムcrun
cgroupv2
SELinuxEnforcing
実行ユーザー一般ユーザー(ルートレス)/ root(インストール・システム設定)

1. Podman の基本概念

Podman(Pod Manager)は、OCI(Open Container Initiative)準拠のコンテナを管理するツールです。AlmaLinux 9 を含む RHEL 9 系ディストリビューションでは、Docker パッケージが公式リポジトリから提供されていません。コンテナを扱う場合は Podman が標準の選択肢になります。

OCI とは、コンテナイメージの形式やランタイムの仕様を標準化する団体・規格です。OCI に準拠したツール同士であれば、同じイメージを共有して動かすことができます。Podman は OCI 準拠のため、Docker Hub で公開されているイメージをそのまま利用できます。

Docker との主な違いを以下の表にまとめます。

比較項目DockerPodman
デーモンdockerd(常駐プロセス)が必要デーモンレス(常駐プロセス不要)
デフォルト実行権限root一般ユーザー(ルートレス)
CLI 互換性docker コマンドdocker コマンドとほぼ同じ書式
イメージ形式OCI / Docker イメージOCI / Docker イメージ
systemd 連携独自のサービス管理Quadlet によるネイティブ連携
Pod サポートなし(Compose で代替)Kubernetes 由来の Pod を標準サポート

ルートレスとは、root 権限を持たない一般ユーザーがコンテナを起動・管理できる仕組みです。デーモンレスとは、バックグラウンドで常駐するプロセス(デーモン)を必要としない設計を指します。Docker では dockerd というデーモンが常駐し、すべてのコンテナ操作を仲介しますが、Podman では各コマンドが直接コンテナランタイム(crun)を呼び出します。デーモンが停止してもコンテナに影響しないため、運用上の単一障害点が減ります。

Podman の関連ツールとして、Buildah(イメージビルドに特化したツール)と Skopeo(レジストリ間のイメージ転送・検査ツール)があります。本記事では Podman 単体での運用を扱いますが、これらのツールが存在することを把握しておくと、今後の運用で選択肢が広がります。

2. インストールと初期設定

Podman のインストール

Podman は AlmaLinux 9 の AppStream リポジトリに含まれています。追加のリポジトリ設定は不要です。

実行コマンド:

# dnf install -y podman

インストール後にバージョンを確認します。

実行コマンド:

$ podman --version

実行結果:

podman version 5.6.0

環境全体の情報を確認するには podman info を使用します。

実行コマンド:

$ podman info

実行結果(主要部分を抜粋):

host:
  arch: amd64
  cgroupControllers:
  - memory
  - pids
  cgroupManager: systemd
  cgroupVersion: v2
  ociRuntime:
    name: crun
    version: crun version 1.20
version:
  APIVersion: 5.6.0
  Built: 1742252082
  BuiltTime: Tue Mar 18 02:34:42 2025
  Version: 5.6.0

cgroupVersion: v2 で cgroup v2 が使用されていること、ociRuntime: crun でコンテナランタイムが crun であることが確認できます。

プロキシ設定

企業ネットワークではインターネットアクセスにプロキシが必要な場合があります。Podman のプロキシ設定はコンテナ実行時とイメージビルド時で設定箇所が異なります。

ルートレスユーザー用の設定ファイルを作成します。コンテナ内のプロセスがインターネットにアクセスする際に、このプロキシを経由するようになります。

設定ファイル(ルートレス):

~/.config/containers/containers.conf

設定内容:

[engine]

[containers]
http_proxy = true

[containers.env]
http_proxy = "http://proxy.example.corp:8080"
https_proxy = "http://proxy.example.corp:8080"
no_proxy = "localhost,127.0.0.1,registry.example.corp"

root ユーザー用のプロキシ設定は以下のファイルに記述します。

設定ファイル(root):

/etc/containers/containers.conf

イメージビルド時(Containerfile 内の RUN で外部パッケージを取得する場合など)は、--build-arg でプロキシを渡します。

$ podman build --build-arg HTTP_PROXY=http://proxy.example.corp:8080 --build-arg HTTPS_PROXY=http://proxy.example.corp:8080 -t myapp:v1 .

切り戻し方法:containers.conf の該当セクションを削除またはコメントアウトし、podman system reset は不要でそのまま反映されます。

レジストリ設定

Podman でイメージ名を省略指定(例: alpine)した場合に、どのレジストリを検索するかを設定するファイルが /etc/containers/registries.conf です。

実行コマンド:

$ cat /etc/containers/registries.conf

デフォルト設定(主要部分):

unqualified-search-registries = ["registry.access.redhat.com", "registry.redhat.io", "docker.io"]

unqualified-search-registries は、イメージ名にレジストリを含めなかった場合の検索先をリスト順に指定します。

企業内のプライベートレジストリを追加する場合は、以下の設定を末尾に追記します。社内で独自にビルドしたイメージをプライベートレジストリから配布する運用で必要になります。

[[registry]]
prefix = "registry.example.corp"
location = "registry.example.corp"
insecure = true

insecure = true は TLS 証明書の検証をスキップする設定です。社内の自己署名証明書を使用しているレジストリに接続する場合に使用します。本番環境では正規の証明書を導入し、insecure = false にすることを推奨します。

切り戻し方法:追記した [[registry]] ブロックを削除します。

レジストリへのログイン

認証が必要なレジストリ(Docker Hub のレートリミット回避や、プライベートレジストリへのアクセス)には事前にログインします。

実行コマンド:

$ podman login registry.example.corp

ユーザー名とパスワードの入力を求められます。認証情報は ${XDG_RUNTIME_DIR}/containers/auth.json に保存されます。

3. コンテナの基本操作

コンテナのバックグラウンド実行

-d(detach)オプションでコンテナをバックグラウンドで起動します。--name で名前を付けておくと、後続の操作でコンテナ ID の代わりに名前で指定できます。

実行コマンド:

$ podman run -d --name test-alpine docker.io/library/alpine:latest sleep 3600

実行結果:

33cb48ea605e4a3b8f9c5d7e1a2b6c9d0e4f8a1b3c5d7e9f0a2b4c6d8e0f1a2b

コンテナ ID が出力されれば起動成功です。

対話モードでの実行

-it で対話シェルに接続し、--rm で終了時にコンテナを自動削除します。動作確認や一時的な検証に使用します。

実行コマンド:

$ podman run -it --rm docker.io/library/alpine:latest /bin/sh

コンテナ一覧の確認

podman ps は稼働中のコンテナを表示します。-a を付けると停止中のコンテナも含めて表示します。

実行コマンド:

$ podman ps

実行結果:

CONTAINER ID  IMAGE                            COMMAND     CREATED                 STATUS                 PORTS       NAMES
33cb48ea605e  docker.io/library/alpine:latest  sleep 3600  Less than a second ago  Up Less than a second              test-alpine

コンテナの停止・起動・再起動

実行コマンド:

$ podman stop test-alpine

実行コマンド:

$ podman start test-alpine

実行コマンド:

$ podman restart test-alpine

コンテナの削除

停止済みのコンテナを削除します。稼働中のコンテナを強制削除する場合は -f オプションを付けます。

実行コマンド:

$ podman rm test-alpine

強制削除の場合:

$ podman rm -f test-alpine

ログの確認

コンテナの標準出力・標準エラー出力を確認します。-f オプションでリアルタイムにログを追跡できます。

実行コマンド:

$ podman logs test-alpine

リアルタイム追跡:

$ podman logs -f test-alpine

稼働中コンテナへの接続

稼働中のコンテナ内でコマンドを実行します。コンテナ内部の状態確認やデバッグに使用します。

実行コマンド:

$ podman exec -it test-alpine /bin/sh

コンテナの詳細情報

podman inspect はコンテナの設定やネットワーク情報を JSON 形式で出力します。IP アドレスの確認やマウント情報の調査に使用します。

実行コマンド:

$ podman inspect test-alpine

コンテナ内プロセスの確認

podman top はコンテナ内で動作しているプロセスを表示します。意図しないプロセスが動いていないかの確認に使用します。

実行コマンド:

$ podman top test-alpine

実行結果:

USER        PID         PPID        %CPU        ELAPSED         TTY         TIME        COMMAND
root        1           0           0.000       5m30.123456s    ?           0s          sleep 3600

4. イメージ管理

イメージの取得

レジストリからイメージをダウンロードします。タグを指定しない場合は :latest が使用されます。

実行コマンド:

$ podman pull docker.io/library/alpine:latest

イメージ一覧の確認

実行コマンド:

$ podman images

実行結果:

REPOSITORY                TAG         IMAGE ID      CREATED       SIZE
docker.io/library/nginx   alpine      d5030d429039  16 hours ago  63.6 MB
docker.io/library/alpine  latest      a40c03cbb81c  8 weeks ago   8.74 MB

イメージの削除

不要になったイメージを削除してディスク容量を確保します。

実行コマンド:

$ podman rmi docker.io/library/alpine:latest

ダングリングイメージの一括削除

ダングリングイメージとは、タグが付いておらず、どのコンテナからも参照されていないイメージです。ビルドを繰り返すと蓄積されるため、定期的に削除します。

実行コマンド:

$ podman image prune

イメージの保存と読み込み(オフライン環境用)

企業の閉域網(インターネットに接続できない環境)では、イメージをファイルに保存して持ち込む運用が必要になります。podman save で tar ファイルにエクスポートし、podman load でインポートします。

保存(エクスポート):

$ podman save -o alpine-latest.tar docker.io/library/alpine:latest

読み込み(インポート):

$ podman load -i alpine-latest.tar

実行結果:

Loaded image: docker.io/library/alpine:latest

イメージへのタグ付け

プライベートレジストリに push する前など、イメージに別名(タグ)を付ける場合に使用します。

実行コマンド:

$ podman tag docker.io/library/alpine:latest registry.example.corp/base/alpine:latest

5. Containerfile による自作イメージ

Containerfile は、イメージのビルド手順を記述するファイルです。Docker における Dockerfile と同じ書式ですが、Podman では Containerfile が正式名称です。Dockerfile という名前でも認識されます。

基本構文

主要な命令を以下の表にまとめます。

命令役割
FROMベースイメージを指定する
RUNビルド時にコマンドを実行する
COPYホストからファイルをコピーする
EXPOSEコンテナがリッスンするポートを宣言する
CMDコンテナ起動時のデフォルトコマンドを指定する
ENTRYPOINTコンテナ起動時に必ず実行されるコマンドを指定する

Containerfile の例:

FROM docker.io/library/almalinux:9
RUN dnf install -y httpd && dnf clean all
COPY index.html /var/www/html/index.html
EXPOSE 80
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]

この Containerfile は、AlmaLinux 9 ベースのイメージに Apache HTTP Server をインストールし、index.html を配置して、ポート 80 で HTTP を待ち受けるコンテナを定義しています。

イメージのビルド

Containerfile が存在するディレクトリで以下のコマンドを実行します。-t でイメージ名とタグを指定します。

実行コマンド:

$ podman build -t myapp:v1 .

企業のプロキシ環境では、ビルド時に --build-arg でプロキシを渡す必要があります。Containerfile 内の RUN dnf install などが外部リポジトリにアクセスするためです。

$ podman build --build-arg HTTP_PROXY=http://proxy.example.corp:8080 --build-arg HTTPS_PROXY=http://proxy.example.corp:8080 -t myapp:v1 .

.containerignore ファイル

.containerignore(Docker の .dockerignore に相当)は、ビルドコンテキストから除外するファイルを指定します。ログファイルや認証情報をイメージに含めないために使用します。

.git
*.log
*.tmp
.env

マルチステージビルド(概要)

マルチステージビルドは、ビルド環境と実行環境を分離する手法です。Containerfile 内で複数の FROM を使い、ビルド用ステージで生成した成果物だけを実行用ステージにコピーすることで、最終イメージのサイズを削減できます。Go や Java などのコンパイル言語でアプリケーションをコンテナ化する際に有用です。

6. データ永続化(ボリューム)

コンテナは停止・削除するとコンテナ内のデータが失われます。データを永続化するには、ホストのファイルシステムをコンテナにマウントします。

バインドマウント

ホストの特定ディレクトリをコンテナにマウントします。設定ファイルやログの永続化に使用します。

実行コマンド:

$ podman run -d --name web -v /srv/html:/usr/share/nginx/html:Z docker.io/library/nginx:alpine

SELinux 環境でのボリュームマウントには :Z または :z が必要

AlmaLinux 9 では SELinux が Enforcing モードで動作しています。ボリュームマウント時に :Z または :z を付けないと、コンテナからマウント先にアクセスした際に Permission denied が発生します。:Z はそのコンテナ専用のラベルを付与し、:z は複数コンテナで共有するラベルを付与します。1 つのコンテナだけがアクセスする場合は :Z を使用してください。

名前付きボリューム

Podman が管理するボリュームを作成し、コンテナにマウントします。ホスト側のパスを意識せずにデータを永続化できるため、データベースのデータ領域などに使用します。

ボリューム作成:

$ podman volume create mydata

ボリューム一覧:

$ podman volume ls

実行結果:

DRIVER      VOLUME NAME
local       mydata

ボリュームをコンテナにマウント:

$ podman run -d --name db -v mydata:/var/lib/mysql:Z docker.io/library/mysql:8

ボリュームの詳細情報:

$ podman volume inspect mydata

ボリュームの削除:

$ podman volume rm mydata

読み取り専用マウント

設定ファイルなど、コンテナから書き込む必要がないデータは :ro を付けて読み取り専用でマウントします。意図しない変更を防止できます。

$ podman run -d --name web-ro -v /srv/config/nginx.conf:/etc/nginx/nginx.conf:ro,Z docker.io/library/nginx:alpine

7. ネットワーク

ポートフォワーディング

-p オプションでホストのポートをコンテナのポートに転送します。外部からコンテナ内のサービスにアクセスする際に使用します。

実行コマンド:

$ podman run -d --name web-test -p 8080:80 docker.io/library/nginx:alpine

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

実行コマンド:

$ podman ps

実行結果:

CONTAINER ID  IMAGE                           COMMAND               CREATED                 STATUS                 PORTS                 NAMES
2f5e9e44edf7  docker.io/library/nginx:alpine  nginx -g daemon o...  Less than a second ago  Up Less than a second  0.0.0.0:8080->80/tcp  web-test

curl で動作確認します。

実行コマンド:

$ curl -s -o /dev/null -w "%{http_code}" http://localhost:8080

実行結果:

200

HTTP ステータス 200 が返れば、nginx コンテナがポート 8080 経由で正常に応答しています。

ユーザー定義ネットワーク

複数のコンテナ間で通信する場合は、ユーザー定義ネットワークを作成します。同一ネットワーク内のコンテナは、コンテナ名で名前解決ができます。

ネットワーク作成:

$ podman network create app-net

ネットワーク一覧:

$ podman network ls

ネットワークを指定してコンテナを起動:

$ podman run -d --name app --network app-net docker.io/library/alpine:latest sleep 3600
$ podman run -d --name db --network app-net docker.io/library/alpine:latest sleep 3600

app コンテナから db コンテナにコンテナ名で通信できます。

実行コマンド:

$ podman exec app ping -c 2 db

ホストネットワークの使用

--network host を指定すると、コンテナがホストのネットワーク名前空間を直接使用します。ポートフォワーディングが不要になりネットワーク性能が向上しますが、ホストのポートと競合する可能性があるため、用途を限定して使用してください。

$ podman run -d --name web-host --network host docker.io/library/nginx:alpine

8. systemd 連携(Quadlet)

Quadlet は Podman 4.4 以降で導入された、systemd とコンテナを統合する仕組みです。従来の podman generate systemd コマンドに代わる推奨方式として位置づけられています。Quadlet を使うと、systemd のユニットファイルと同じ感覚でコンテナの起動・停止・自動起動を管理できます。

.container ユニットファイルの書き方

Quadlet では .container という拡張子のファイルにコンテナの定義を記述します。配置先は以下の通りです。

実行ユーザー配置先ディレクトリ
root/etc/containers/systemd/
一般ユーザー(ルートレス)~/.config/containers/systemd/

nginx コンテナを Quadlet で管理する例:

ファイル名:web.container

[Unit]
Description=Nginx Web Server Container
After=local-fs.target

[Container]
Image=docker.io/library/nginx:alpine
ContainerName=web
PublishPort=8080:80
Volume=/srv/html:/usr/share/nginx/html:Z

[Install]
WantedBy=default.target

[Container] セクションに Podman の run コマンドに相当するオプションを記述します。[Install] セクションの WantedBy=default.target は、自動起動を有効にするための設定です。

Quadlet の適用と起動

.container ファイルを配置したら、systemd にユニットを再読み込みさせます。

実行コマンド:

$ systemctl --user daemon-reload

コンテナを起動します。Quadlet により、.container ファイル名(拡張子なし)がサービス名になります。

実行コマンド:

$ systemctl --user start web

状態確認:

$ systemctl --user status web

自動起動を有効にします。

実行コマンド:

$ systemctl --user enable web

root で Quadlet を使う場合

root ユーザーで Quadlet を使う場合は、.container ファイルを /etc/containers/systemd/ に配置し、systemctl daemon-reload--user なし)で読み込みます。systemctl start websystemctl enable web のように --user を付けずに操作してください。

レガシー方式: podman generate systemd(参考)

podman generate systemd は、既存のコンテナから systemd ユニットファイルを自動生成するコマンドです。Podman 4.4 以降では Quadlet が推奨されており、この方式は非推奨(deprecated)です。既存環境で使われている場合の参考として記載します。

$ podman generate systemd --new --name web

--new は起動のたびにコンテナを新規作成する設定です。生成されたユニットファイルを ~/.config/systemd/user/ に配置し、systemctl --user daemon-reload で読み込みます。

ルートレスでの自動起動に必要な設定

ルートレスで systemd 管理されたコンテナは、ユーザーがログアウトすると停止します。ログアウト後もコンテナを継続稼働させるには、loginctl enable-linger を実行します。

実行コマンド:

$ loginctl enable-linger $(whoami)

この設定により、ユーザーセッションが終了しても systemd のユーザーインスタンスが維持され、コンテナが動き続けます。

切り戻し方法:

$ loginctl disable-linger $(whoami)

9. ルートレスコンテナ

ルートレスコンテナは、root 権限を持たない一般ユーザーがコンテナを実行する仕組みです。Podman ではデフォルトでルートレス実行が可能です。万が一コンテナからブレイクアウト(脱出)されても、ホスト上では一般ユーザー権限しか持たないため、被害を限定できます。

ユーザー名前空間の仕組み

ルートレスコンテナは Linux のユーザー名前空間(user namespace)を利用しています。コンテナ内の root(UID 0)は、ホスト上では一般ユーザーの UID にマッピングされます。このマッピングは /etc/subuid/etc/subgid で定義されます。

実行コマンド:

$ cat /etc/subuid

実行結果:

developer:100000:65536

この設定は「developer ユーザーに対して、UID 100000 から 65536 個の UID 範囲を割り当てる」ことを意味します。コンテナ内の UID 0(root)はホスト上では UID 100000 に、コンテナ内の UID 1 はホスト上では UID 100001 にマッピングされます。/etc/subgid も同様の形式で GID のマッピングを定義します。

ルートレスの制約

制約項目内容回避策
特権ポート1024 未満のポートにバインドできないsysctl で ip_unprivileged_port_start を変更
ファイルシステム一部のマウントオプションが使用できないroot 実行に切り替える
ネットワークping が ICMP ソケットの権限で失敗する場合があるsysctl で net.ipv4.ping_group_range を設定
コンテナ数subuid/subgid の範囲に依存/etc/subuid の範囲を拡大

1024 未満ポートのバインド

ルートレスでポート 80 や 443 にバインドしたい場合は、カーネルパラメータを変更します。

実行コマンド(root):

# sysctl -w net.ipv4.ip_unprivileged_port_start=80

永続化するには /etc/sysctl.d/ に設定ファイルを作成します。

# echo "net.ipv4.ip_unprivileged_port_start=80" > /etc/sysctl.d/99-unprivileged-port.conf
# sysctl --system

切り戻し方法:作成した設定ファイルを削除し、sysctl --system を再実行します。

# rm /etc/sysctl.d/99-unprivileged-port.conf && sysctl --system

root 実行との使い分け

企業運用での判断基準を以下にまとめます。

条件推奨
開発・検証用途ルートレス
本番 Web サーバー(ポート 80/443)ルートレス + sysctl 設定、または root
ホストデバイスへのアクセスが必要root
セキュリティ要件が厳しい環境ルートレス
既存の Docker 運用からの移行まずルートレスで検証し、制約に当たれば root

loginctl enable-linger

ルートレスでコンテナを常時稼働させる場合、ユーザーがログアウトしても systemd のユーザーインスタンスを維持する必要があります。第 8 章でも触れましたが、この設定はルートレス運用の前提条件です。

実行コマンド:

$ loginctl enable-linger $(whoami)

設定確認:

$ loginctl show-user $(whoami) --property=Linger

実行結果:

Linger=yes

10. podman-compose(概要)

podman-compose は、Docker Compose 形式の YAML ファイル(docker-compose.yml)を読み取り、Podman でコンテナを起動するツールです。複数のコンテナを 1 つの YAML ファイルで定義・管理する用途で使用します。

インストール

podman-compose は EPEL(Extra Packages for Enterprise Linux)リポジトリから提供されています。EPEL の有効化についてはパッケージ管理編を参照してください。

実行コマンド:

# dnf install -y podman-compose

基本操作

docker-compose.yml が存在するディレクトリで以下のコマンドを実行します。

バックグラウンドで起動:

$ podman-compose up -d

停止・削除:

$ podman-compose down

podman-compose の互換性について

podman-compose は Docker Compose v1 形式との互換性が中心であり、Docker Compose v2 の一部機能(profiles、service dependencies の高度な制御など)には対応していない場合があります。複雑な構成を扱う場合は、事前に動作検証を行ってください。

Pod の概要

Podman には Pod(ポッド)という概念があります。Pod は Kubernetes 由来の仕組みで、複数のコンテナを 1 つのグループとしてまとめ、ネットワーク名前空間を共有します。Pod 内のコンテナは localhost で相互に通信できます。podman pod createpodman pod lspodman pod rm で管理します。本記事では概要の紹介にとどめます。

11. 運用 Tips

不要リソースの一括削除

停止中のコンテナ、ダングリングイメージ、未使用のネットワークを一括で削除します。ディスク容量の確保に使用します。

実行コマンド:

$ podman system prune

本番環境での prune は慎重に実行する

podman system prune は未使用のリソースをすべて削除します。本番環境では、一時停止中のコンテナや意図的に保持しているイメージが削除される可能性があるため、podman ps -apodman images で対象を確認してから実行してください。

リソース使用状況の確認

コンテナごとの CPU・メモリ・ネットワーク I/O の使用状況をリアルタイムで表示します。

実行コマンド:

$ podman stats

実行結果:

ID            NAME        CPU %       MEM USAGE / LIMIT  MEM %       NET IO      BLOCK IO    PIDS        CPU TIME      AVG CPU %
2f5e9e44edf7  web-test    0.00%       3.855MB / 8.229GB  0.05%       0B / 0B     0B / 0B     3           24.694ms      0.00%

イベントログ

Podman のイベント(コンテナの作成・起動・停止・削除など)を時系列で表示します。トラブル発生時の操作履歴の調査に使用します。

実行コマンド:

$ podman events --since 1h

トラブルシューティング

podman pull でタイムアウトする

企業のプロキシ環境で podman pull がタイムアウトする場合、プロキシ設定が漏れている可能性があります。

確認箇所:

  • ~/.config/containers/containers.conf のプロキシ設定(ルートレスの場合)
  • /etc/containers/containers.conf のプロキシ設定(root の場合)
  • シェルの環境変数(http_proxyhttps_proxy

環境変数で一時的にプロキシを指定して動作確認します。

$ https_proxy=http://proxy.example.corp:8080 podman pull docker.io/library/alpine:latest

ボリュームマウントで Permission denied が出る

SELinux が Enforcing モードの環境で、ボリュームマウント時に :Z または :z を付けていない場合に発生します。

エラー例:

Error: open /usr/share/nginx/html/index.html: permission denied

対処方法:-v オプションのマウント指定に :Z を追加します。

$ podman run -d --name web -v /srv/html:/usr/share/nginx/html:Z docker.io/library/nginx:alpine

既にマウントしたディレクトリのラベルを手動で修正する場合は、以下のコマンドを使用します。

$ chcon -Rt container_file_t /srv/html

ルートレスで 1024 未満のポートがバインドできない

ルートレスでポート 80 にバインドしようとすると、以下のエラーが発生します。

Error: rootlessport listen tcp 0.0.0.0:80: bind: permission denied

対処方法:カーネルパラメータ net.ipv4.ip_unprivileged_port_start を変更します(第 9 章参照)。

# sysctl -w net.ipv4.ip_unprivileged_port_start=80

systemctl でコンテナが起動しない

Quadlet の .container ファイルを配置した後に systemctl start が失敗する場合、以下の原因が考えられます。

  • systemctl --user daemon-reload を実行していない
  • ルートレスで loginctl enable-linger を設定していない
  • .container ファイルの記述にエラーがある

確認手順:

$ systemctl --user daemon-reload
$ systemctl --user status web
$ loginctl show-user $(whoami) --property=Linger

Linger=no と表示された場合は、loginctl enable-linger $(whoami) を実行してください。

イメージビルドでパッケージインストールが失敗する

Containerfile 内の RUN dnf install でパッケージのダウンロードが失敗する場合、ビルド時にプロキシが渡されていない可能性があります。

対処方法:--build-arg でプロキシを指定してビルドします。

$ podman build --build-arg HTTP_PROXY=http://proxy.example.corp:8080 --build-arg HTTPS_PROXY=http://proxy.example.corp:8080 -t myapp:v1 .
前の記事
次の記事