Red Hat Certified System Administrator (RHCSA) #14 コンテナ管理: Podman、systemd integration (quadlet)

読了 9分

RHEL 実務トラック 21 編 でユーザー管理・ストレージ・systemd・SELinux を直接触ってみたなら、その次の自然なステップは その感覚を資格で検証してもらうこと です。今回の記事は RHCSA の出題領域の最後の軸である コンテナ を扱います。RHEL のコンテナエンジンは Docker ではなく Podman であり、RHCSA では単にコンテナを起動するだけでなく、そのコンテナを systemd に登録して起動時に自動実行する 作業まで手で終わらせられる必要があります。

この領域はコマンドの数は多くありませんが、rootless 実行quadlet による systemd 連携 という二つの落とし穴が合格を分けます。どちらもはまりやすいので、今回の記事では正確な手順を自分で打ち込みながら押さえます。

Podman を使う理由 #

RHEL 8 から Docker の代わりに Podman が標準のコンテナエンジンです。Podman は Docker とコマンド互換性がほぼ同じで、docker のところに podman を入れればほとんどそのまま動きます。ただし RHCSA が Podman を選んだ本当の理由は二つあります。

  • デーモンがありません。 Docker は root 権限で動く dockerd デーモンにコマンドを送る構造ですが、Podman はデーモンなしでコマンドが直接コンテナプロセスを起動します。そのためコンテナを systemd で直接管理するのに適した構造です。
  • rootless を正式にサポートします。 一般ユーザーが root なしで自分のコンテナを起動できます。RHCSA は通常 特定の一般ユーザーで rootless コンテナを動かす よう求めるので、この点が重要です。

まずパッケージがインストールされているか確認します。

# Podman のインストール (通常 RHEL 9 には標準で含まれる)
sudo dnf install -y container-tools

# バージョン確認
podman --version

レジストリログインとイメージの扱い #

RHEL が提供する公式イメージは Red Hat レジストリ にあります。認証が必要なレジストリにはまずログインします。

# Red Hat レジストリログイン (アカウント資格情報を入力)
podman login registry.access.redhat.com

# ログイン情報はユーザーごとの認証ファイルに保存される
#   $XDG_RUNTIME_DIR/containers/auth.json

ログインした後、イメージを検索して取得します。

# イメージ検索
podman search ubi9

# イメージ取得 (registry.access.redhat.com の ubi9)
podman pull registry.access.redhat.com/ubi9/ubi

# ローカルに取得したイメージの一覧
podman images

podman search は設定されたレジストリからイメージを探し、podman pull は取得したイメージをローカルに保存します。試験ではイメージ名を レジストリパスまで全部 書くほうが安全です。短い名前はレジストリの検索順序によって見当違いのイメージを取得してしまうことがあるためです。

コンテナの実行と基本コマンド #

コンテナをバックグラウンドで実行しながらポート・ボリューム・環境変数をマッピングするコマンドが RHCSA の核心です。

# バックグラウンド実行 (-d)、ポートマッピング (-p)、名前指定 (--name)
podman run -d --name web -p 8080:80 \
  registry.access.redhat.com/ubi9/httpd-24

# 実行中のコンテナ一覧
podman ps

# 停止したコンテナまですべて表示
podman ps -a

# ログ確認
podman logs web

# コンテナ内でコマンド実行 (シェルに入る)
podman exec -it web /bin/bash

# 停止と削除
podman stop web
podman rm web

-d は detached (バックグラウンド) 実行、-p ホストポート:コンテナポート はポートマッピング、--name は扱いやすいように名前を付けます。podman exec -it で実行中のコンテナに入って状態を確認できます。

ボリュームマッピング #

コンテナは削除すると内部データが消えるので、維持すべきデータは ホストディレクトリをボリュームとしてマウント します。

# ホストディレクトリの準備
mkdir -p ~/web-content
echo "hello from host" > ~/web-content/index.html

# ボリュームマッピング (-v ホストパス:コンテナパス:Z)
podman run -d --name web -p 8080:80 \
  -v ~/web-content:/var/www/html:Z \
  registry.access.redhat.com/ubi9/httpd-24

-v ホストパス:コンテナパス でマウントし、末尾の :Z が RHCSA ではまりやすい落とし穴です。RHEL は SELinux が有効なので、:Z を付けると Podman がそのホストディレクトリに container_file_t コンテキストを自動的に設定します。これを抜くとコンテナがボリュームにアクセスできず権限エラーになります。

環境変数の受け渡し #

# 環境変数の受け渡し (-e KEY=VALUE)
podman run -d --name db \
  -e POSTGRESQL_USER=appuser \
  -e POSTGRESQL_PASSWORD=secret \
  -e POSTGRESQL_DATABASE=appdb \
  -p 5432:5432 \
  registry.redhat.io/rhel9/postgresql-15

-e KEY=VALUE で環境変数を渡します。コンテナイメージは通常こうした環境変数で初期設定 (ユーザー・パスワード・DB 名) を受け取ります。どの変数を要求するかはイメージのドキュメントに書かれているので、試験では問題文が教えてくれる値をそのまま入れれば大丈夫です。

rootless コンテナ #

RHCSA はほぼ常に 一般ユーザーで rootless コンテナを動かす よう求めます。核心は単純です。そのユーザーでログインした状態で sudo なしで podman コマンドを実行 すればよいです。

# root が特定のユーザーに切り替えるときはログインシェルに入る
sudo su - appuser

# これで appuser として rootless 実行 (sudo なし)
podman run -d --name web -p 8080:80 \
  registry.access.redhat.com/ubi9/httpd-24

# appuser のコンテナだけが見える
podman ps

rootless には二つの注意点があります。

  • 1024 未満のポートをホストに直接マッピングできません。 rootless は権限のないユーザーなので、-p 80:80 のように 80 番をホストポートとして使うと失敗します。そのため上の例のように -p 8080:80 で 1024 以上のポートを使います。
  • ユーザー切り替えは必ずログインシェルで行います。 su - ユーザー のようにダッシュを付けてこそ、そのユーザーの環境変数 (XDG_RUNTIME_DIR など) が正しく設定されます。これがずれると rootless Podman が動作しません。

quadlet による systemd 連携 #

RHCSA のコンテナ領域で 合格を分ける作業 がまさにこれです。「このコンテナを systemd サービスにして起動時に自動実行せよ」という問題が定番で出ます。RHEL 9.3 からは quadlet が推奨方式です。

quadlet は .container ファイルにコンテナ定義を書いておくと、systemd がそれを読んで自動的にサービスを生成してくれる仕組みです。一般ユーザー (rootless) なら、ファイルを ~/.config/containers/systemd/ の下に置きます。

# rootless ユーザーの quadlet ディレクトリ作成
mkdir -p ~/.config/containers/systemd

これで .container ファイルを作成します。ファイル名がそのままサービス名になります。たとえば web.containerweb.service になります。

# ~/.config/containers/systemd/web.container
[Container]
Image=registry.access.redhat.com/ubi9/httpd-24
PublishPort=8080:80
Volume=%h/web-content:/var/www/html:Z
Environment=KEY=VALUE

[Install]
WantedBy=default.target

各キーの意味は次のとおりです。

  • Image=。使用するイメージ (レジストリパスまで明示するのを推奨)
  • PublishPort=。ポートマッピング (podman run -p に相当)
  • Volume=。ボリュームマッピング (-v に相当)。%h はユーザーのホームディレクトリに展開され、SELinux のため :Z を付ける
  • Environment=。環境変数 (-e に相当)
  • [Install] WantedBy=。自動起動の対象。systemd がこのサービスをどの target に接続するかを指定する

ファイルを作った後は、systemd に新しい定義を読ませてサービスを起動します。

# quadlet 定義を再度読み込んでサービスを生成 (rootless は --user)
systemctl --user daemon-reload

# サービス開始 (ファイル名 web.container → サービス名 web.service)
systemctl --user start web.service

# 状態確認
systemctl --user status web.service

ここでよく詰まる箇所が二つあります。

  • quadlet サービスは systemctl --user enable を直接実行しません。 自動起動は .container ファイルの [Install] WantedBy= で決まり、daemon-reload がそれを反映します。enable を試みると「静的 (static) サービスなので enable できない」というエラーに出会うことがあります。
  • 定義を直した後は、必ず daemon-reload をもう一度 実行しないと変更が反映されません。

loginctl enable-linger による起動時の自動起動 #

rootless ユーザーの systemd サービスは基本的に そのユーザーがログインしているときだけ 動きます。ログアウトするとユーザーサービスも一緒に終了するので、起動直後やログアウト状態でもコンテナが上がっているようにするには linger を有効にする必要があります。

# 該当ユーザーの linger 有効化 (root 権限が必要)
sudo loginctl enable-linger appuser

# またはそのユーザー自身が実行可能
loginctl enable-linger

# 状態確認 (Linger=yes であること)
loginctl show-user appuser | grep Linger

enable-linger を有効にすると、そのユーザーがログインしていなくてもそのユーザーの systemd インスタンスが起動時に開始され、そこに接続された rootless コンテナサービスも一緒に自動実行されます。rootless コンテナを起動時に自動起動せよという問題でこのステップを抜くと、再起動後にコンテナが上がらず失点します。

全体の流れの整理 #

rootless コンテナを systemd で起動時に自動実行する全体の手順を一度に見ると次のとおりです。

# 1) 対象ユーザーでログインシェルに入る
sudo su - appuser

# 2) quadlet ディレクトリと .container ファイルの作成
mkdir -p ~/.config/containers/systemd
vi ~/.config/containers/systemd/web.container

# 3) systemd に定義を反映して開始
systemctl --user daemon-reload
systemctl --user start web.service

# 4) 起動時の自動起動のために linger 有効化
loginctl enable-linger

試験ポイント #

RHCSA コンテナ領域で点数を分ける箇所を整理します。

  • rootless は su - ユーザー でログインシェルに入った後、sudo なしで podman を実行します。 ダッシュを抜かして環境変数が壊れるミスが多いです。
  • rootless は 1024 未満のホストポートを使えません。 -p 8080:80 のように 1024 以上でマッピングします。
  • ボリュームには :Z を付けます。 SELinux コンテキストのためで、抜くとコンテナがボリュームにアクセスできません。
  • quadlet ファイルは rootless なら ~/.config/containers/systemd/*.container に置きます。 ファイル名がそのままサービス名です。
  • quadlet サービスは enable しません。 自動起動は [Install] WantedBy= で決め、systemctl --user daemon-reload で反映します。
  • 起動時の自動実行には loginctl enable-linger が必須です。 この一行を抜かすと再起動後にコンテナが消えます。

特に quadlet の [Install] セクションと loginctl enable-linger の二つが RHCSA コンテナ問題の核心となる採点ポイントです。コンテナを起動するところで止めず、再起動後にもコンテナが生きているか必ず確認します。

まとめ #

今回の記事で押さえたこと:

  • Podman はデーモンなしの rootless コンテナエンジン。Docker とコマンド互換性が高く systemd 連携に自然
  • イメージの扱いpodman login registry.access.redhat.com でログイン、searchpullimages でイメージ管理
  • コンテナの実行run -d -p -v -e でバックグラウンド・ポート・ボリューム・環境変数、pslogsexecstoprm で運用
  • rootless。一般ユーザーでログインシェルに入った後 sudo なしで実行、1024 以上のポート、ボリューム :Z
  • quadlet 連携~/.config/containers/systemd/*.container[Container] 定義、systemctl --user daemon-reload + start
  • 起動時の自動起動loginctl enable-linger でログアウト後も rootless サービスを維持

コンテナの systemd 連携は RHEL 深化トラック でより広い運用の文脈につながります。RHCSA の範囲では quadlet と linger で 再起動後の自動実行 を作るところまでが目標です。

次: 試験のコツ #

これで RHCSA の出題領域を一通り回りました。ツールとスクリプト、起動と運用、ストレージとファイルシステム、パッケージとネットワーキング、ユーザーとセキュリティ、そして今回のコンテナまで手で身につけました。残るのは、これらの作業を 2.5 時間以内に正確に終わらせる運用の感覚 を磨くことです。

#15 試験のコツと時間管理、よく間違えるパターン では、問題を解く順序、永続適用を逃さない点検ルーチン、man page を素早く探す方法、そして受験者が繰り返し間違えるパターンを整理し、合格ライン 210 点を安定して超える戦略を扱います。

X