Podman

DevOpsコンテナPodmanrootlessセキュリティRed HatOCI準拠

DevOpsツール

Podman

概要

Podmanは、Red Hatが開発するdaemonlessコンテナエンジンです。Docker互換性を保ちながら、rootless実行、SystemdPods等の機能によりセキュリティと運用性を向上させています。

詳細

Podman(Pod Manager)は、Red Hatが開発したオープンソースのコンテナエンジンです。「Pod」「Image」「Container」を管理する頭文字から命名され、Dockerの代替として設計されました。最大の特徴は、root権限を必要としないrootlessコンテナの実行とdaemonless アーキテクチャです。従来のDockerはroot権限で動作するdaemonプロセスが必要でしたが、Podmanは各コンテナを独立したプロセスとして実行し、セキュリティリスクを大幅に軽減。OCI(Open Container Initiative)準拠で、Docker Hub等の既存コンテナレジストリとの互換性を維持。Kubernetes Podの概念をローカル環境でも利用可能にし、systemdとの統合によりサービス管理も容易。Red Hat Enterprise Linux(RHEL)8以降でデフォルト採用され、CentOS Stream、Fedora等でも標準提供。企業環境でのセキュリティ要件が厳しい場合や、Dockerからの移行先として注目されており、特にRed Hat エコシステムでの利用が拡大しています。

メリット・デメリット

メリット

  • セキュリティ: rootless実行とdaemonless アーキテクチャ
  • Docker互換性: 既存Dockerコマンドとイメージの利用可能
  • systemd統合: サービス管理とプロセス監視の簡素化
  • Pod対応: Kubernetes Podコンセプトのローカル実装
  • 軽量: デーモンプロセス不要で軽量動作
  • 企業向け: Red Hatサポートとエンタープライズ品質
  • マルチアーキテクチャ: x86_64、ARM64、s390x対応
  • OCI準拠: 標準化されたコンテナ仕様に完全準拠

デメリット

  • 学習コスト: Docker経験者でも若干の学習が必要
  • エコシステム: Dockerほどの豊富なツール群なし
  • パフォーマンス: 一部ワークロードでDockerより若干劣る場合
  • Windows/macOS: ネイティブサポートが限定的
  • GUI: Docker Desktopに相当する統合GUIなし
  • デバッグ: 新しいツールのためトラブルシューティング情報が少ない
  • プラットフォーム依存: Linux環境が前提
  • 移行コスト: 既存Docker環境からの移行作業

主要リンク

書き方の例

基本的なコンテナ操作

# Docker互換コマンド
podman run hello-world
podman pull nginx:alpine
podman images
podman ps
podman ps -a

# コンテナ実行(rootlessで安全)
podman run -d --name web-server -p 8080:80 nginx:alpine
podman logs web-server
podman exec -it web-server sh
podman stop web-server
podman rm web-server

Pod作成と管理

# Pod作成(Kubernetes風)
podman pod create --name mypod --publish 8080:80

# Pod内にコンテナ追加
podman run -dt --pod mypod --name web nginx:alpine
podman run -dt --pod mypod --name cache redis:alpine

# Pod操作
podman pod list
podman pod ps mypod
podman pod stop mypod
podman pod start mypod
podman pod rm mypod

Kubernetes YAML生成

# Pod用YAMLファイル生成
podman pod create --name webapp --publish 3000:3000
podman run -dt --pod webapp --name app nodejs:16-alpine
podman run -dt --pod webapp --name db postgres:13

# Kubernetes形式でエクスポート
podman generate kube webapp > webapp-pod.yaml

# 生成されたYAMLの例
cat webapp-pod.yaml
# webapp-pod.yaml(生成例)
apiVersion: v1
kind: Pod
metadata:
  name: webapp
spec:
  containers:
  - name: app
    image: docker.io/library/nodejs:16-alpine
    ports:
    - containerPort: 3000
      hostPort: 3000
  - name: db
    image: docker.io/library/postgres:13
    env:
    - name: POSTGRES_PASSWORD
      value: password

systemd統合

# ユーザーサービスとして登録
podman run -d --name web-service nginx:alpine
podman generate systemd --new --files --name web-service

# サービスファイルを適切な場所に配置
mkdir -p ~/.config/systemd/user
mv container-web-service.service ~/.config/systemd/user/

# systemdで管理
systemctl --user daemon-reload
systemctl --user enable container-web-service.service
systemctl --user start container-web-service.service
systemctl --user status container-web-service.service

Podman Compose(docker-compose.yml互換)

# compose.yaml
version: '3'
services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html
    depends_on:
      - app

  app:
    image: node:16-alpine
    working_dir: /app
    volumes:
      - .:/app
    command: npm start
    environment:
      - NODE_ENV=production

  db:
    image: postgres:13
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:
# Podman Composeで実行
podman-compose up -d
podman-compose ps
podman-compose logs
podman-compose down

Rootlessコンテナのセキュリティ設定

# ユーザーネームスペース確認
podman unshare id
podman unshare cat /proc/self/uid_map

# セキュリティ設定付きで実行
podman run --security-opt no-new-privileges \
  --cap-drop ALL \
  --cap-add NET_BIND_SERVICE \
  --read-only \
  --tmpfs /tmp \
  nginx:alpine

# SELinux対応
podman run --security-opt label=type:container_runtime_t \
  nginx:alpine

高度なネットワーク設定

# カスタムネットワーク作成
podman network create mynetwork

# ネットワーク指定でコンテナ実行
podman run -d --network mynetwork --name web1 nginx:alpine
podman run -d --network mynetwork --name web2 nginx:alpine

# ネットワーク情報確認
podman network inspect mynetwork
podman exec web1 ping web2

# ネットワーク削除
podman network rm mynetwork

イメージ管理とレジストリ操作

# イメージビルド
cat > Containerfile << EOF
FROM alpine:latest
RUN apk add --no-cache curl
COPY app.sh /usr/local/bin/
CMD ["/usr/local/bin/app.sh"]
EOF

podman build -t myapp:latest .

# レジストリ操作
podman login registry.example.com
podman tag myapp:latest registry.example.com/myapp:v1.0
podman push registry.example.com/myapp:v1.0

# イメージ署名検証
podman image trust set -f policy.json registry.example.com/myapp

Podman Remote(リモート実行)

# リモートPodmanサーバー設定
podman system service --time=0 unix:///tmp/podman.sock

# リモート接続設定
podman system connection add myserver \
  ssh://[email protected]/run/user/1000/podman/podman.sock

# リモートで実行
podman --remote --connection myserver ps
podman --remote --connection myserver run nginx:alpine