第3章:ホスト設定とRootless環境の最適化
カーネルパラメータとシステム設定の最適化
必須カーネルパラメータ
# 現在のカーネルパラメータを確認
$ sysctl -a | grep -E 'user.max_user_namespaces|kernel.unprivileged_userns_clone'
user.max_user_namespaces = 0 # デフォルトで無効の場合が多い
kernel.unprivileged_userns_clone = 0 # Debian/Ubuntuのデフォルト
# Rootlessコンテナに必要な設定
$ cat > /etc/sysctl.d/99-rootless.conf << EOF
# ユーザー名前空間の最大数
# 各ユーザーが作成できる名前空間数を制限
user.max_user_namespaces = 15000
# 非特権ユーザーの名前空間作成を許可
kernel.unprivileged_userns_clone = 1
# PIDの最大数(大量コンテナ実行時に必要)
kernel.pid_max = 4194304
# inotify監視の上限(ファイル監視に必要)
fs.inotify.max_user_watches = 524288
fs.inotify.max_user_instances = 512
EOF
$ sysctl -p /etc/sysctl.d/99-rootless.conf
パフォーマンスを左右する設定
# I/Oスケジューラの選択(コンテナワークロード向け)
$ echo 'mq-deadline' > /sys/block/nvme0n1/queue/scheduler
# TCPパラメータの最適化(コンテナ間通信向け)
$ cat > /etc/sysctl.d/99-container-network.conf << EOF
# TIME_WAITソケットの再利用を有効化
net.ipv4.tcp_tw_reuse = 1
# コネクション追跡テーブルのサイズ
net.netfilter.nf_conntrack_max = 131072
# ARPキャッシュの拡大
net.ipv4.neigh.default.gc_thresh1 = 4096
net.ipv4.neigh.default.gc_thresh2 = 8192
net.ipv4.neigh.default.gc_thresh3 = 16384
EOF
3.1 プラットフォーム別最適インストール
RHEL/CentOS/Fedora
# システムパッケージ(最新版、SELinux統合済み)
$ sudo dnf install -y podman podman-docker buildah skopeo
# crunのインストール(runcより高速)
$ sudo dnf install -y crun
$ podman --runtime /usr/bin/crun run alpine echo "test"
# SELinuxコンテキストの確認
$ ps -eZ | grep podman
system_u:system_r:container_runtime_t:s0 12345 ? 00:00:01 podman
Ubuntu
# Ubuntu 22.04/24.04 の場合(Kubicリポジトリから最新版)
$ sudo apt update
$ sudo apt install -y ca-certificates curl gpg
$ . /etc/os-release
$ sudo install -m 0755 -d /etc/apt/keyrings
$ curl -fsSL "https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/Release.key" | \
sudo gpg --dearmor --yes --batch -o /etc/apt/keyrings/libcontainers.gpg
$ sudo chmod a+r /etc/apt/keyrings/libcontainers.gpg
$ echo "deb [signed-by=/etc/apt/keyrings/libcontainers.gpg] https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/ /" | \
sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list > /dev/null
$ sudo apt update
$ sudo apt install -y podman buildah skopeo
# AppArmorプロファイルの確認
$ sudo aa-status | grep podman
/usr/bin/podman (enforce)
バイナリ直接インストール(最新機能利用時)
# 最新バイナリのダウンロード
$ curl -L https://github.com/containers/podman/releases/download/v4.8.0/podman-remote-static-linux_amd64.tar.gz | \
tar xz -C /tmp
$ sudo install -m 755 /tmp/bin/podman /usr/local/bin/podman
# 依存関係のインストール
$ sudo dnf install -y \
conmon \
containers-common \
crun \
fuse-overlayfs \
slirp4netns \
iptables
3.2 Rootlessコンテナの詳細設定
UID/GIDマッピングの設計
# ユーザーIDマッピングの確認
$ id
uid=1000(user) gid=1000(user) groups=1000(user)
$ cat /etc/subuid
user:100000:65536
# 意味: userは100000から65536個のUIDを使用可能
# マッピングの実際の動作
$ podman run --rm alpine cat /proc/self/uid_map
0 1000 1 # コンテナ内UID 0 = ホストUID 1000
1 100000 65536 # コンテナ内UID 1-65536 = ホストUID 100000-165535
# 実際のファイル所有者確認
$ podman run -v /tmp/test:/data alpine touch /data/file
$ ls -ln /tmp/test/file
-rw-r--r-- 1 100000 100000 0 Jan 15 10:00 /tmp/test/file

2026-07-23(JST)、Ubuntu 24.04.3 LTS(WSL2)/ rootless Podman 4.9.3。host userのUID 1000がcontainer内UID 0へ、subuid rangeがcontainer内UID 1以降へ対応していることを確認します。
ストレージドライバーの選択
# rootless状態、kernel、storage driver、driver optionを同時に確認
$ podman info --format json | jq '{
rootless: .host.security.rootless,
kernel: .host.kernel,
graphDriver: .store.graphDriverName,
graphRoot: .store.graphRoot,
graphOptions: .store.graphOptions
}'
# 期待するdriver名はDockerのoverlay2ではなくoverlay
{
"rootless": true,
"kernel": "<running-kernel>",
"graphDriver": "overlay",
"graphRoot": "/home/user/.local/share/containers/storage",
"graphOptions": {}
}
graphDriverがoverlayで、graphOptionsにoverlay.mount_programがなければnative overlayを使用しています。overlay.mount_programにfuse-overlayfsが記録されていればFUSE経由です。native rootless OverlayFSはLinux 5.12.9以降が前提ですが、kernel番号だけで決めず、backing filesystemとディストリビューションのsupport policyも確認します。
fuse-overlayfsを導入しても、既存の$HOME/.config/containers/storage.confがあると自動選択されない場合があります。設定変更前に既存container/imageを退避し、変更後はpodman infoで実際に選択されたdriverとoptionを再確認してください。
network backendと設定の確認
# 現在のbackendを確認。現行Podmanの通常buildではNetavark
$ podman info --format '{{.Host.NetworkBackend}}'
netavark
# 公開CLIでnetworkを作成
$ podman network create \
--subnet 172.20.0.0/16 \
--gateway 172.20.0.1 \
custom-net
# generated fileを直接読むのではなく、公開CLIで結果を確認
$ podman network inspect custom-net | jq '.[0] | {
name, driver, network_interface, subnets, dns_enabled
}'
Netavarkのnetwork config directoryは、rootfulでは/etc/containers/networks、rootlessでは$graphroot/networksです。graphrootの既定値は$HOME/.local/share/containers/storageですが、固定pathを仮定せずpodman infoで確認します。generated JSONは内部実装として扱い、作成・変更・確認にはpodman network commandを使用します。
Podman 4以前のCNI環境から移行する場合、CNIの.conflistをNetavark directoryへcopyしません。旧networkの接続containerと設定を記録し、現行Podman上でnetworkを再作成してから切り替えます。Podman 5.0ではCNI supportが通常buildで無効化され、Podman 6.0で削除されました。現行Podmanの新規設定でCNI backendを選択する手順は対象外です。
cgroups v2の詳細設定
# cgroups v2の有効化確認
$ mount | grep cgroup
cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime)
# Rootlessでのリソース制限設定
$ podman run --memory 512m --cpus 0.5 alpine sh -c '
echo "Memory limit: $(cat /sys/fs/cgroup/memory.max)";
echo "CPU quota: $(cat /sys/fs/cgroup/cpu.max)"'
Memory limit: 536870912
CPU quota: 50000 100000
# systemdスライスでのcgroup管理
$ systemctl --user status
● user@1000.service - User Manager for UID 1000
Loaded: loaded
Active: active (running)
Main PID: 1234 (systemd)
Status: "Ready"
CGroup: /user.slice/user-1000.slice/user@1000.service
├─session.slice
│ └─podman-12345.scope # Podmanコンテナ
│ ├─12345 /usr/bin/conmon
│ └─12367 /usr/bin/crun
# ユーザー単位でのリソース制限
$ systemctl --user set-property user@1000.service \
MemoryMax=8G CPUQuota=200%
ストレージ最適化設定
native rootless OverlayFSを利用できる環境では、mount_programを設定しません。
# ~/.config/containers/storage.conf(native overlay)
[storage]
driver = "overlay"
runroot = "/run/user/1000/containers"
graphroot = "/home/user/.local/share/containers/storage"
[storage.options.overlay]
mountopt = "nodev"
kernelまたはbacking filesystemの制約でnative overlayを利用できない場合だけ、fallbackとして次を追加します。
# ~/.config/containers/storage.conf(fuse-overlayfs fallback)
[storage.options.overlay]
mount_program = "/usr/bin/fuse-overlayfs"
mountopt = "nodev"
# 選択結果とストレージ使用状況の確認
$ podman info --format json | jq '{
graphDriver: .store.graphDriverName,
graphOptions: .store.graphOptions
}'
$ podman system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 15 5 2.45GB 1.23GB (50%)
Containers 8 3 123MB 89MB (72%)
Local Volumes 3 2 456MB 123MB (27%)
# ガベージコレクション
$ podman system prune
# 影響が大きい操作(未使用イメージ/ボリュームも削除される可能性があるため注意)
# $ podman system prune --all --volumes
なぜストレージドライバーの選択が重要か
ストレージドライバーは、コンテナのパフォーマンスと機能に直接影響します。
各ドライバーの特性と用途
# ~/.config/containers/storage.conf
[storage]
driver = "overlay" # Podman / containers-storageでのdriver名
graphroot = "/home/user/.local/share/containers/storage"
runroot = "/run/user/1000/containers"
# overlay: copy-on-writeによるlayer管理
# - Copy-on-Write により効率的なレイヤー管理
# - ハードリンクによる容量節約
# - 高速な起動とビルド
[storage.options.overlay]
mountopt = "nodev"
上記はnative overlayの例です。fallbackが必要な環境だけ、別途mount_program = "/usr/bin/fuse-overlayfs"を[storage.options.overlay]へ追加します。native overlayの設定例へmount_programをcopyしないでください。
storage quotaの適用境界
size = "10G"を[storage.options.vfs]へ置く方法は現行schemaにありません。quota optionはdriverごとに異なり、backing filesystem側のproject quotaなど追加要件もあります。設定前にcontainers-storage.confの対象driver節を確認し、podman infoと実際の書き込み上限で検証します。
3.2.3 レジストリ設定
なぜレジストリ設定をカスタマイズするのか
デフォルトのレジストリ設定では、以下の問題が発生する可能性があります。
- セキュリティ: 信頼できないレジストリからの意図しないプル
- パフォーマンス: 地理的に遠いレジストリへのアクセス
- コンプライアンス: 承認されていないイメージの使用
# /etc/containers/registries.conf
unqualified-search-registries = ["docker.io", "quay.io"]
# → "nginx" のような短縮名で、どのレジストリを検索するか
# → セキュリティのため、信頼できるレジストリのみに限定すべき
[[registry]]
location = "docker.io"
insecure = false # HTTPSを強制(なぜ重要か: 中間者攻撃を防ぐ)
[[registry]]
location = "localhost:5000"
insecure = true # 開発環境のみ許可(本番では絶対に使用しない)
# ミラー設定の効果
[[registry]]
location = "docker.io"
[[registry.mirror]]
location = "mirror.gcr.io" # 地理的に近いミラーで高速化
# → グローバル企業では、各地域にミラーを配置してレイテンシを削減
3.3 ネットワーク設定
3.3.1 Netavarkとaardvark-dns
Netavarkは現行Podmanのnetwork backendです。DNSが有効なnetworkではaardvark-dnsがcontainer名とnetwork aliasを登録します。rootless containerをdefault network modeで実行するときはpastaが使われます。
# backendとrootless network toolを確認
$ podman info --format json | jq '{
backend: .host.networkBackend,
backendInfo: .host.networkBackendInfo,
rootless: .host.security.rootless,
pasta: .host.pasta
}'
# bridge networkを作成し、driver / subnet / DNSを確認
$ podman network create --subnet 10.89.10.0/24 app-net
$ podman network inspect app-net | jq '.[0] | {
name, driver, network_interface, subnets, dns_enabled
}'
# container名とaliasによるname解決を確認
$ podman run -d --name web --network app-net docker.io/library/nginx:1.28.0-alpine
$ podman run --rm --network app-net docker.io/library/busybox:1.37.0 \
nslookup web
# 演習後のcleanup
$ podman rm -f web
$ podman network rm app-net
3.3.2 ファイアウォール統合
firewalldとの連携
# Podman用ゾーン作成
sudo firewall-cmd --permanent --new-zone=containers
sudo firewall-cmd --permanent --zone=containers --add-source=10.88.0.0/16
sudo firewall-cmd --permanent --zone=containers --add-port=80/tcp
sudo firewall-cmd --reload
3.4 セキュリティ設定
3.4.1 SELinux統合
SELinuxコンテキスト
# コンテナ用SELinuxコンテキスト
ls -Z /var/lib/containers
system_u:object_r:container_var_lib_t:s0 /var/lib/containers
# ボリュームマウント時のラベル
podman run -v /host/path:/container/path:Z ... # プライベートラベル
podman run -v /host/path:/container/path:z ... # 共有ラベル
3.4.2 seccomp/AppArmor
seccompプロファイル
{
"defaultAction": "SCMP_ACT_ERRNO",
"architectures": [
"SCMP_ARCH_X86_64",
"SCMP_ARCH_X86",
"SCMP_ARCH_X32"
],
"syscalls": [
{
"names": [
"accept",
"accept4",
"access",
"alarm",
"bind",
"brk"
],
"action": "SCMP_ACT_ALLOW"
}
]
}
3.5 パフォーマンスチューニング
3.5.1 システムパラメータ
# /etc/sysctl.d/podman.conf
# ネットワークパフォーマンス
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
# ファイルディスクリプタ
fs.file-max = 1048576
fs.nr_open = 1048576
# メモリ設定
vm.max_map_count = 262144
3.5.2 ストレージ最適化
# オーバーレイファイルシステムの最適化
[storage.options.overlay]
# メタデータの非同期化
skip_sync = true
# レイヤー数の制限
force_mask = "0700"
演習問題
- Rootless Podmanをセットアップし、動作確認してください
/etc/subuidと/etc/subgidの割り当てを確認し、コンテナ内外のUID/GID対応を記録してくださいpodman network createでNetavarkのcustom networkを作成し、podman network inspectでsubnetとDNS設定を確認してください
参考資料
エンタープライズ環境での詳細な要件については、エンタープライズ要件詳細ガイドを参照してください。
- Podman rootless mode / storage
- podman network
- podman info
- Podman v5.0.0 release notes(CNI supportの通常build無効化)
- Podman v6.0.0 release notes(CNI networkingの削除)
- containers-storage.conf
まとめ
- Rootless運用に必要なカーネルパラメータと、パフォーマンスに影響する設定の観点を整理しました。
- 環境(RHEL系/Ubuntu系/バイナリ配布)ごとのインストール方法と、導入時に確認すべきポイントを確認しました。
- UID/GIDマッピングなど、Rootlessコンテナの前提となる詳細設定の考え方を扱いました。