MENU

Podmanルートレスコンテナのsystemdサービス化|ユーザーcgroup scopeの制限と本番障害切り戻し設計

目次

Podmanルートレスコンテナをsystemdで管理する背景

Podmanのルートレスモードは、root権限を持たない一般ユーザーがコンテナを起動・管理できる仕組みです。セキュリティ上のメリットは大きいものの、サーバー起動時やユーザーログアウト後もコンテナを継続稼働させるには、systemdとの連携が必要になります。

Podmanはdaemonレスアーキテクチャを採用しているため、プロセスのライフサイクル管理はsystemdに委ねる設計になっています。2024〜2025年にかけてPodman 5系がRHEL 9・Ubuntu 24.04などの主要ディストリビューションに普及し、podman generate systemdコマンドはPodman 5.0で廃止されました。現在はQuadletが標準の統合手段です。この変化を踏まえた構成手順と、本番環境における障害切り戻しの設計を整理します。

ユーザーcgroup scopeの制限を理解する

systemdには「システムスライス」と「ユーザースライス」という2つのcgroup管理階層があります。ルートレスコンテナのsystemdサービス化は、ユーザースライス(user.slice/user-<UID>.slice)配下で動作します。ここにはいくつかの制限が存在します。

リソース制限の継承と上書き

ユーザースライスには、システム管理者が/etc/systemd/system/user-.slice.d/に設定したCPU・メモリの上限が継承されます。ルートレスコンテナのサービス内でさらにリソース制限を書いても、ユーザースライスの上位制限を超えることはできません。systemctl --user show <service>でリソース設定を確認し、systemd-cglsでcgroupツリーを目視確認する習慣が重要です。

linger(ログアウト後の継続稼働)

systemdはデフォルトでは、対象ユーザーのセッションがすべて終了するとsystemd --userインスタンスを停止します。コンテナを常駐させるには以下のコマンドでlingerを有効化する必要があります。

sudo loginctl enable-linger <ユーザー名>

lingerが有効になると、ユーザーセッションが存在しなくてもsystemd –userプロセスが起動・維持されます。無効化するにはdisable-lingerを使います。本番環境では有効化の状態を構成管理ツール(Ansibleなど)で管理し、再プロビジョニング後に消失しないよう担保することが一般的です。

cgroup v2必須とdelegation設定

Podmanのルートレスcgroup機能はcgroup v2に依存しています。RHEL 9・Ubuntu 22.04以降はcgroup v2がデフォルトですが、古いVMイメージやWSL2環境では未対応のケースがあります。

また、ユーザーにcgroupの委譲(delegation)が許可されていないと、コンテナ内でcgroupを利用するサービスが起動に失敗します。/etc/systemd/system/user@.service.d/delegate.confに以下を追記することで委譲を有効化できます。

[Service]
Delegate=yes

Quadletによるsystemdサービス化の手順

Podman 4.4で導入され、5.0でpodman generate systemdの後継として位置づけられたQuadletは、.containerファイルをsystemdのユニット定義として直接認識させる仕組みです。daemon-reloadのタイミングでPodmanが内部的にsystemdユニットへ変換するため、ユニットファイルを手書きする必要がありません。

Quadletファイルの配置場所

ルートレス(一般ユーザー)の場合、Quadletファイルは以下のディレクトリに配置します。

~/.config/containers/systemd/

システムワイド(rootによる管理)の場合は/etc/containers/systemd/を使います。ルートレスとrootで管理対象が混在する場合は、ディレクトリを混同しないよう注意が必要です。

.containerファイルの記述例(想定例)

以下はnginxコンテナをルートレスで常駐させる想定例です。実際の運用ではImageタグやボリュームパスを環境に合わせて変更してください。

[Unit]
Description=Nginx rootless container
After=network-online.target

[Container]
Image=docker.io/library/nginx:stable
PublishPort=8080:80
Volume=%h/html:/usr/share/nginx/html:z
AutoUpdate=registry

[Service]
Restart=always
TimeoutStartSec=60

[Install]
WantedBy=default.target

ファイル名をnginx.containerとして保存した後、systemdのデーモンをリロードしてサービスを起動します。

systemctl --user daemon-reload
systemctl --user start nginx.service
systemctl --user enable nginx.service

Quadletが生成した実際のユニット内容はsystemctl --user cat nginx.serviceで確認できます。変換結果に予期しない設定が含まれていないかを確認する習慣を持つと、トラブル発生時の原因特定が容易になります。

稼働確認とトラブルシュートの基本操作

ステータスとログの確認

# サービス状態の確認
systemctl --user status nginx.service

# リアルタイムログ
journalctl --user -u nginx.service -f

# 起動失敗時の詳細ログ
journalctl --user -u nginx.service -e --no-pager

cgroup状態の確認

# ユーザースライス下のcgroupツリーを確認
systemd-cgls --user-unit nginx.service

# リソース使用量のリアルタイム表示
systemd-cgtop

コンテナが予期せず停止する場合、cgroupのメモリ上限によるOOMキルが原因となるケースがよくあります。journalctl --user -kでカーネルログも合わせて確認することで、メモリ関連のイベントを素早く把握できます。

本番障害時の切り戻し設計

ルートレスコンテナのsystemdサービス化を本番環境で運用する場合、障害発生時の切り戻し手順をあらかじめ設計しておくことが重要です。対応レベルを「イメージロールバック」「サービス停止」「ユニット無効化」の3段階に分けて整理しておくと、インシデント対応時に判断コストを減らせます。

イメージのロールバック

Podmanはコンテナイメージをローカルにキャッシュするため、前バージョンのイメージタグをpullし直してサービスを再起動することで、アプリケーションレベルのロールバックが可能です。

# 旧バージョンのイメージを取得(想定例)
podman pull docker.io/library/nginx:1.24

# .containerファイルのImageを旧バージョンタグに変更後
systemctl --user daemon-reload
systemctl --user restart nginx.service

AutoUpdate=registryを有効化している場合は、podman auto-update --dry-runで更新予定を事前確認し、意図しない自動更新が発生していないかを把握してから作業を進めます。

サービスの即時停止

障害が深刻で即時停止が必要な場合は以下の順序で対応します。

# サービス停止
systemctl --user stop nginx.service

# 自動起動の無効化
systemctl --user disable nginx.service

# コンテナプロセスの確認と強制削除(必要な場合)
podman ps -a
podman rm -f <コンテナID>

Quadletファイルの退避によるユニット削除

.containerファイルを削除・退避することで、次回のデーモンリロード後にQuadletが生成したsystemdユニットも消えます。ファイルを即座に削除するのではなく、.bak拡張子に変更してからデーモンリロードを行うことで、設定を残しつつサービスを無効化できます。

mv ~/.config/containers/systemd/nginx.container \
   ~/.config/containers/systemd/nginx.container.bak
systemctl --user daemon-reload

この方法はファイルが残るため、原因調査後に.bakを元の名前に戻すだけでサービスを復元できます。切り戻し後のリストアを想定した手順として有効です。

2026年の現行環境差分と注意点

Podman 5系の変更点と移行の要否

Podman 5.0(2024年リリース)でpodman generate systemdが正式に廃止されました。既存の環境でこのコマンドに依存したスクリプトや手順書が残っている場合は、Quadletへの移行が必要です。RHEL 9.4以降・Ubuntu 24.04 LTSではPodman 5系がパッケージとして提供されています。移行の際は既存のユニットファイルを.container形式に書き直し、daemon-reload後に動作確認を行います。

RHEL 10 / CentOS Stream 10の動向

2025年にリリースされたRHEL 10では、Podman 5系とQuadletの組み合わせが推奨構成として公式ドキュメントに記載されています。またSELinuxポリシーの更新によりルートレスコンテナのラベル付けルールが変更された箇所があるため、ボリュームマウント時の:zや:Zオプションの挙動を再確認することが推奨されます。一般的なつまずきとして、マウントしたボリュームへのアクセスがPermission deniedで失敗するケースがあり、SELinuxのAVCログ(ausearch -m avc)を確認する手順が有効です。

ネットワークバックエンドのslirp4netnsからpastaへの移行

Podman 5系ではルートレスコンテナのデフォルトネットワークバックエンドがslirp4netnsからpastaに移行しています。pastaはパフォーマンスと機能の面で優れていますが、カーネル5.6未満の環境では動作しない場合があります。旧来のVMイメージや一部のコンテナ基盤では問題が出ることがあるため、/etc/containers/containers.confのnetwork_backend設定とpodman info | grep networkBackendの出力で現在の状態を確認します。

Podman Desktopとの共存

開発環境でPodman Desktopを使っている場合、ユーザーセッション上のsystemd –userとPodman Desktopが管理するソケット・機能が競合することがあります。本番サーバーでsystemdサービス化を行う際はPodman Desktopの影響が入らない純粋なサーバー環境で検証し、設定を確定させることが安全です。

「コマンドは打てる。次は”現場で通用する型”を最短で身につけたい」——そんなあなたへ。

ネットの断片的なTipsをコピペするだけでは、体系的な運用スキルはなかなか積み上がりません。リナックスマスター.JPの無料メルマガ「リナマガ」では、現場で実際に使うLinuxサーバー運用の考え方を、順を追って実務目線でお届けしています。いま登録された方には、安全なサーバー構築の「型」をまとめた『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼント中です。

>> 図解60P『Linux入門マニュアル』を無料で受け取る
(メルマガ登録は10秒・いつでも解除OK)

※ 「独学の時間がもったいない」「プロから現場の技術を最短で学びたい」という本気の方には、2日で実務レベルが身につく初心者向けハンズオンセミナーもご用意しています。

PR・広告

[試して理解]Linuxのしくみ 増補改訂版(Amazon)

プロセス・権限・ファイルシステムなどLinux内部を図解で理解できる一冊。運用判断の勘所に。

Amazonで見る

※ Amazonのアソシエイトとして、当サイトは適格販売により収入を得ています。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

目次