podman について
Linux のコンテナ運用者向け Podman スキルです。デーモンレスおよび rootless での実行に加え、Pod、systemd 連携、イメージ管理を扱います。
主な機能
- 01デーモンレスでのコンテナ管理
- 02rootless モードでのコンテナ実行
- 03Pod の作成と管理
- 04systemd ユニットの生成と Quadlet の利用
- 05イメージ、ネットワーク、ボリュームの管理
- 06Compose ファイルと Kubernetes YAML の実行
活用シーン
- 01root 権限なしでのコンテナ実行
- 02Docker のないシステムでのコンテナ管理
- 03関連コンテナの Pod へのグループ化
- 04systemd を使ったコンテナサービスの管理
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ bagelhole/ devops-security-agent-skills --skill podmanインストール後、Claude Code で/podmanを入力して読み込まれたか確認します。
詳細
Podman
Podman のルートレスコンテナエンジンを使用して、デーモンなしでコンテナを実行、管理します。
このスキルを使用するタイミング
次の場合にこのスキルを使用します。
- root 権限なしでコンテナを実行する
- Docker がないシステムでコンテナを管理する
- Pod ベースのコンテナグループを作成する
- systemd を使用してコンテナを管理する
- セキュリティを重視する環境で作業する
前提条件
- Podman がインストールされていること(4.x+)
- ルートレスの場合:ユーザーネームスペースが有効になっていること
- コンテナの基本概念を理解していること
Docker との主な違い
| 機能 | Docker | Podman |
|---|---|---|
| アーキテクチャ | クライアントとデーモン | デーモンレス |
| root 権限の必要性 | デフォルトで必要 | 任意(ルートレス) |
| Pod のサポート | なし | あり(Kubernetes スタイル) |
| systemd 統合 | 限定的 | ネイティブ |
| ソケット | docker.sock | podman.sock(任意) |
基本コマンド
コンテナ操作
# Run container (identical to Docker)
podman run -d --name webserver -p 8080:80 nginx
# List containers
podman ps -a
# Stop and remove
podman stop webserver
podman rm webserver
# Execute command
podman exec -it webserver /bin/sh
# View logs
podman logs -f webserver
イメージ管理
# Pull image
podman pull docker.io/library/nginx:latest
# List images
podman images
# Build image
podman build -t myapp:latest .
# Push to registry
podman push myapp:latest registry.example.com/myapp:latest
# Remove image
podman rmi nginx:latest
ルートレスコンテナ
セットアップ
# Check user namespace support
cat /proc/sys/user/max_user_namespaces
# Enable if needed (as root)
echo "user.max_user_namespaces=28633" | sudo tee /etc/sysctl.d/userns.conf
sudo sysctl -p /etc/sysctl.d/userns.conf
# Configure subuid/subgid for user
sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $USER
# Verify
podman unshare cat /proc/self/uid_map
ルートレスで実行する
# Run as regular user (no sudo)
podman run -d --name myapp -p 8080:80 nginx
# Check user namespace mapping
podman unshare id
# Verify non-root
podman top myapp user
ポートに関する考慮事項
# Rootless cannot bind to ports < 1024 by default
# Use ports >= 1024
podman run -d -p 8080:80 nginx
# Or enable unprivileged ports (as root)
echo "net.ipv4.ip_unprivileged_port_start=80" | sudo tee /etc/sysctl.d/ports.conf
sudo sysctl -p /etc/sysctl.d/ports.conf
Pod
Pod の作成
# Create pod
podman pod create --name mypod -p 8080:80 -p 5432:5432
# Add containers to pod
podman run -d --pod mypod --name web nginx
podman run -d --pod mypod --name db postgres:15
# List pods
podman pod ps
# Containers share network namespace
podman exec web curl localhost:5432
Pod の管理
# Start/stop pod (affects all containers)
podman pod start mypod
podman pod stop mypod
# Remove pod and containers
podman pod rm -f mypod
# View pod details
podman pod inspect mypod
# Generate Kubernetes YAML from pod
podman generate kube mypod > mypod.yaml
systemd 統合
systemd ユニットの生成
# Generate unit file for container
podman generate systemd --new --name myapp > ~/.config/systemd/user/container-myapp.service
# For pod
podman generate systemd --new --name mypod --files
# Reload systemd
systemctl --user daemon-reload
# Enable and start
systemctl --user enable --now container-myapp.service
Quadlet(Podman 4.4+)
# ~/.config/containers/systemd/webapp.container
[Container]
Image=docker.io/library/nginx:latest
PublishPort=8080:80
Volume=webapp-data:/usr/share/nginx/html
[Service]
Restart=always
[Install]
WantedBy=default.target
# Reload to generate service
systemctl --user daemon-reload
# Start the service
systemctl --user start webapp
Compose 互換性
Podman Compose の使用
# Install podman-compose
pip install podman-compose
# Run compose file
podman-compose up -d
# Or use Docker Compose with Podman socket
systemctl --user enable --now podman.socket
export DOCKER_HOST=unix:///run/user/$UID/podman/podman.sock
docker-compose up -d
ネイティブ Podman Kube
# Play Kubernetes YAML
podman kube play deployment.yaml
# Stop and remove
podman kube down deployment.yaml
ネットワーク
ネットワーク管理
# Create network
podman network create mynetwork
# Run on network
podman run -d --network mynetwork --name app myapp
# Connect container to network
podman network connect mynetwork existing-container
# List networks
podman network ls
# Inspect network
podman network inspect mynetwork
DNS 解決
# Containers on same network can resolve by name
podman run -d --network mynetwork --name db postgres:15
podman run -d --network mynetwork --name app \
-e DATABASE_HOST=db myapp
ストレージ
ボリューム管理
# Create volume
podman volume create mydata
# Use volume
podman run -d -v mydata:/data myapp
# List volumes
podman volume ls
# Inspect volume
podman volume inspect mydata
# Rootless volumes location
ls ~/.local/share/containers/storage/volumes/
バインドマウント
# Bind mount with SELinux label
podman run -v ./data:/app/data:Z myapp
# Z = private label (single container)
# z = shared label (multiple containers)
レジストリ設定
レジストリの設定
# Edit registries.conf
# ~/.config/containers/registries.conf
unqualified-search-registries = ["docker.io", "quay.io"]
[[registry]]
prefix = "docker.io"
location = "docker.io"
[[registry.mirror]]
location = "mirror.gcr.io"
認証
# Login to registry
podman login docker.io
# Login to private registry
podman login registry.example.com
# Credentials stored in
# ~/.config/containers/auth.json
イメージのビルド
Buildah 統合
# Podman uses Buildah for builds
podman build -t myapp:latest .
# Build with specific format
podman build --format docker -t myapp .
# Multi-stage build
podman build --target production -t myapp:prod .
Buildah コマンド
# Create container from scratch
buildah from scratch
buildah copy working-container ./app /app
buildah config --entrypoint '["/app/main"]' working-container
buildah commit working-container myapp:minimal
よくある問題
問題:権限が拒否される
問題:マウントされたボリューム内のファイルにアクセスできません
解決策:SELinux 用に :Z または :z サフィックスを使用するか、所有権を確認してください
問題:コンテナに接続できない
問題:ルートレスモードでポートにアクセスできません 解決策:1024 以上のポートを使用するか、非特権ポートの開始番号を設定してください
問題:イメージのプルが遅い
問題:イメージのダウンロードが遅いです 解決策:registries.conf でレジストリミラーを設定してください
問題:systemd サービスが失敗する
問題:systemd 経由でコンテナが起動しません
解決策:リンギングを有効にしてください:loginctl enable-linger $USER
ベストプラクティス
- セキュリティを強化するためにルートレスモードを使用する
- 関連するコンテナには Pod を活用する
- 本番環境では systemd ユニットを生成する
- 宣言型のコンテナサービスには Quadlet を使用する
- バインドマウントに SELinux ラベルを設定する
- サービスを永続化するためにユーザーのリンギングを有効にする
- 自動更新には podman auto-update を使用する
- 互換性のために
dockerをpodmanのエイリアスに設定する
関連スキル
- docker-management - Docker の基礎
- kubernetes-ops - K8s オーケストレーション
- container-hardening - セキュリティ
コメント
Markdown 対応