第11章:Kubernetesとの統合
注意(この章のスコープ)
- 本章は Podman と Kubernetes の相互運用(Kubernetes YAML の生成/簡易実行)を扱います。
- Kubernetes の設計・運用(クラスタ構成、Service/Ingress、スケジューリング、RBAC、ローリング更新等)の学習は対象外 です。
podman kube playは Kubernetes を完全再現しません(podman play kubeは同義のエイリアスです)。特に Service/Ingress、複数レプリカ、readiness/startup probe 等 は差分があるため、本番相当の挙動確認は実クラスタで実施 してください(差分は後述)。
補足: Podman 4.3 以降、Kubernetes 連携コマンドは podman kube ... 配下に整理されています。本章では podman kube play / podman kube generate / podman kube down 表記に統一し、旧コマンド(podman play kube / podman generate kube など)はエイリアスとして扱います。
本章の意義と学習目標
なぜPodmanのKubernetes連携を学ぶ必要があるのか
「開発環境と本番環境の乖離」は、多くの組織が抱える根本的な課題です。PodmanのKubernetes連携機能は、この課題に対する有効なアプローチの1つです。
- 開発サイクルの劇的な短縮: ローカルで(対応範囲の)Kubernetes YAMLを簡易実行し、即座にフィードバック
- 学習コストの削減: Kubernetes YAML(主にPod/Deployment等)の形を保ったままローカルで簡易検証
- デプロイリスクの最小化: YAML/イメージ/設定の差分を早期に減らし、本番移行時の手戻りを削減
- 段階的移行の実現: 単一ホストからクラスターへ、無理のない移行パス
本章では、PodmanをKubernetes YAMLへの「橋渡し」として活用し、移行に向けた差分を早期に洗い出す観点を扱います。
11.1 PodmanとKubernetesの関係
なぜPodmanがKubernetesと深い関係を持つのか
PodmanはKubernetes YAMLとの相互運用(podman kube generate / podman kube play)を提供し、ローカルでの簡易検証や移行の橋渡しに利用できます。これは偶然ではなく、以下の戦略的理由があります。
- 同じ概念モデル: Pod、Container、Volumeなど、Kubernetesの中核概念を共有
- 開発者体験の統一: ローカル検証から実クラスタへの移行を意識したワークフロー
- Red Hatのビジョン: OpenShiftを通じたエンタープライズKubernetesの推進
11.1.1 共通点と相違点
共通点が生む価値
- OCI標準準拠: 同じコンテナイメージを前提にでき、移行時の差分を減らす
- Pod概念のサポート: 複雑なマルチコンテナアプリケーションの開発が容易
- YAML形式での定義: Infrastructure as Codeの実践、GitOpsワークフローの実現
- 共有コンポーネント: OCI準拠と共通コンポーネント(images/storage/runtime 等)により、イメージ資産や運用ノウハウを流用しやすい
補足: Kubernetes のコンテナランタイムは CRI-O / containerd 等の CRI 実装であり、Podman 自体は CRI ではありません(CRI-O との関係は 11.5 を参照)。
相違点とその理由
| 特徴 | Podman | Kubernetes | なぜ違いが必要か |
|---|---|---|---|
| スケール | 単一ホスト | クラスター | 開発環境のシンプルさと本番のスケーラビリティの両立 |
| オーケストレーション | なし | あり | ローカルでは不要な複雑性を排除 |
| サービスディスカバリ | 基本的 | 高度 | 開発時は簡潔さを優先 |
| 永続化 | ローカル | 分散ストレージ | 開発環境のセットアップ簡素化 |
これらの違いは欠点ではなく、各環境の目的に最適化された設計の結果です。
実際のエンタープライズ運用事例
※本節の事例・数値は理解を助けるためのモデルケース(例示)です。
事例1: 金融機関での段階的移行(A銀行)
課題:
- レガシーシステムからマイクロサービスへの移行
- 厳格なセキュリティ要件とコンプライアンス
- 開発者100名のスキル移行
Podman活用アプローチ:
# 段階1: 開発環境でのPod概念の導入
podman pod create --name banking-app-pod
podman run -d --pod banking-app-pod --name web-frontend nginx:alpine
podman run -d --pod banking-app-pod --name api-backend python:3.11-alpine
# 段階2: Kubernetes YAML生成での本番環境準備
podman kube generate banking-app-pod > banking-app-k8s.yaml
# 段階3: セキュリティポリシーの検証
podman pod create --security-opt seccomp=banking-policy.json \
--name secure-banking-pod
結果:
- 移行期間: 18ヶ月 → 12ヶ月(33%短縮)
- 開発者の学習時間: 40%削減
- セキュリティインシデント: ゼロ
事例2: 製造業での IoT エッジコンピューティング(B製造会社)
要件:
- 工場の Edge デバイスでのコンテナ実行
- 低リソース環境での安定動作
- リモート管理とアップデート
Podman活用の理由:
# リソース効率: デーモンレス実行
# 1000台のエッジデバイス × 300MB節約 = 300GB削減
# rootless実行によるセキュリティ
podman run --user 1001:1001 \
--security-opt no-new-privileges \
edge-analytics:latest
# systemdとの統合
podman generate systemd --name iot-collector --files
systemctl --user enable container-iot-collector.service
※ podman generate systemd は非推奨(deprecated)です。今後の systemd 連携は Quadlet(例: .container ユニット)による管理を前提にしてください。
効果:
- メモリ使用量: 30%削減
- セキュリティインシデント: 90%削減
- 運用工数: 50%削減
事例3: SaaS企業での開発速度向上(Cスタートアップ)
課題:
- 高速な機能開発とデプロイ
- 限られた DevOps リソース
- マルチクラウド対応
Podman活用の効果:
# Kubernetes YAML(Pod/Deployment等)の簡易検証(完全再現ではない)
podman kube play production-deployment.yaml
# ローカルでの統合テスト
podman pod create --name test-environment
podman run --pod test-environment database:latest
podman run --pod test-environment api:latest
podman run --pod test-environment frontend:latest
# CI/CDパイプラインでの検証
podman build -t myapp:latest .
podman run --rm myapp:latest pytest tests/
成果:
- デプロイ頻度: 週1回 → 日5回
- 障害率: 70%削減
- 開発者満足度: 40%向上
11.1.2 アーキテクチャの比較
Podmanのアーキテクチャ
┌─────────────┐
│ podman │ ← CLI/API
├─────────────┤
│ libpod │ ← Pod/Container管理
├─────────────┤
│ containers/ │ ← ストレージ/ネットワーク
│ storage │
├─────────────┤
│ runc │ ← OCI Runtime
└─────────────┘
Kubernetesのアーキテクチャ(簡略図)
┌─────────────┐
│ API Server │
├─────────────┤
│ Scheduler │ ┌─────────────┐
├─────────────┤ │ kubelet │
│ Controller │ ├─────────────┤
│ Manager │ │ Container │
└─────────────┘ │ Runtime │
└─────────────┘
この違いが意味することは次のとおりです。
- Podman: 単一プロセスでシンプル、リソース効率的
- Kubernetes: 分散システムで高可用性、複雑だが強力
11.2 Kubernetes YAMLの実行
11.2.1 podman kube playによるYAML実行
Podmanは(対応範囲の)Kubernetes YAMLをローカルで簡易実行できます。これにより、開発環境での検証が簡単になります。
対応する kind/フィールドは Podman の man page(podman-kube-play(1))の supported kinds / fields を参照してください。
基本的な使用方法
# Kubernetes YAMLの実行
podman kube play deployment.yaml
# 実行中のPodの確認
podman pod ps
# Podの停止と削除
podman kube down deployment.yaml
※ podman kube down 実行後も、podman kube play が作成した volume は残ります。不要な場合は --force を使用するか、手動で volume を削除してください。
サポートされるリソースタイプ
- Pod
- Deployment(Podとして実行)
- DaemonSet
- Job
- PersistentVolumeClaim
- ConfigMap
- Secret
※ Service/Ingress を前提にした疎通(ClusterIP/LoadBalancer/Ingress)やルーティングは podman kube play では再現しないため、実クラスタで確認してください。
実践例: Webアプリケーションのデプロイ
apiVersion: v1
kind: Pod
metadata:
name: webapp
spec:
containers:
- name: frontend
image: nginx:alpine
ports:
- containerPort: 80
hostPort: 8080
- name: backend
image: node:alpine
command: ["node", "server.js"]
env:
- name: DB_HOST
value: "localhost"
# 実行
podman kube play webapp.yaml
# 動作確認
curl http://localhost:8080
11.2.2 制限事項と回避策
主な制限事項
- Service/Ingress未サポート: ClusterIP/LoadBalancer/Ingressは機能しない
- 回避策: hostPortを使用、またはpodman-composeで代替
- 複数レプリカの再現不可: Deploymentの
spec.replicasは指定しても無視され、実行は1レプリカ相当になる- 回避策: ローカルでは単一インスタンスで起動確認し、スケール動作は実クラスタで検証
- probeの一部未対応:
readinessProbe/startupProbeは未対応(livenessProbeは対応)- 回避策: ローカルは起動/ヘルスエンドポイントの確認に留め、プローブ前提の制御は実クラスタで検証
- ネームスペース制限: 完全な分離は提供されない
- 回避策: Pod名でのプレフィックス使用
いつ podman kube play で良いか / いつ実クラスタが必要か
podman kube play: YAMLの構文・主要フィールド、イメージ/環境変数/ボリューム/コマンド等の差分を早期に確認したい場合- 実クラスタ: Service/Ingress を前提にした疎通、複数レプリカ、readiness/startup probe に依存する制御、運用要件(RBAC/NetworkPolicy等)を確認したい場合
実用的な対処法
# 開発用と本番用でYAMLを分ける
podman kube play dev-pod.yaml # 開発用(hostPort含む)
kubectl apply -f prod-deploy.yaml # 本番用(Service使用)
11.3 Kubernetes YAMLの生成
11.3.1 podman kube generateコマンド
既存のPodmanコンテナからKubernetes YAMLを生成できます。これにより、ローカルで確認した構成をベースに、実クラスタ向けの差分を調整しやすくなります。
基本的な使用方法
# 単一コンテナから生成
podman kube generate mycontainer > pod.yaml
# Podから生成
podman kube generate mypod > pod.yaml
# Serviceも含めて生成
podman kube generate -s mypod > deployment.yaml
※ -s/--service で Service 定義も生成できますが、podman kube play は Service を再現しません。生成した Service は実クラスタ適用用の雛形として扱ってください。
生成されるYAMLの例
apiVersion: v1
kind: Pod
metadata:
labels:
app: myapp
name: myapp-pod
spec:
containers:
- image: localhost/myapp:latest
name: myapp
ports:
- containerPort: 8080
protocol: TCP
resources: {}
securityContext:
capabilities:
drop:
- CAP_MKNOD
- CAP_AUDIT_WRITE
restartPolicy: OnFailure
11.3.2 生成されたYAMLのカスタマイズ
生成されたYAMLは基本的なものなので、本番環境向けにカスタマイズが必要です。
必要な修正点
- イメージの参照先
# 変更前 image: localhost/myapp:latest # 変更後 image: registry.example.com/myapp:v1.0.0 - リソース制限の追加
resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m" - プローブの追加
livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 30 periodSeconds: 10
11.4 開発から本番への移行戦略
11.4.1 段階的移行アプローチ
フェーズ1: ローカル開発(Podman)
- 単一ホストでの開発とテスト
- podman-composeでマルチコンテナアプリケーション構築
- CI/CDパイプラインでの自動テスト
フェーズ2: Kubernetes互換性確認(Podman + YAML)
- Kubernetes YAMLでの定義
- podman kube playでの動作確認
- 設定の外部化(ConfigMap/Secret)
フェーズ3: ステージング環境(Kubernetes)
- 実際のKubernetesクラスターでのテスト
- Service/Ingressの設定
- 監視・ログ収集の確認
フェーズ4: 本番環境(Kubernetes)
- 段階的ロールアウト
- カナリアデプロイメント
- 自動スケーリングの設定
11.4.2 ベストプラクティス
1. イメージ管理
# タグ付けの標準化
podman tag myapp:latest registry.example.com/myapp:${GIT_COMMIT}
# マルチステージビルドの活用
FROM golang:1.19 AS builder
WORKDIR /app
COPY . .
RUN go build -o main .
FROM alpine:latest
COPY --from=builder /app/main /usr/local/bin/
CMD ["main"]
2. 設定の外部化
# ConfigMapの使用
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
database.url: "postgres://db:5432/myapp"
log.level: "info"
3. ヘルスチェックの実装
// Go言語でのヘルスチェックエンドポイント
http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
// データベース接続確認
if err := db.Ping(); err != nil {
w.WriteHeader(http.StatusServiceUnavailable)
return
}
w.WriteHeader(http.StatusOK)
w.Write([]byte("OK"))
})
11.5 CRI-Oとの統合
11.5.1 CRI-O概要
CRI-Oは、KubernetesのCRI実装の1つで、Podmanとコンテナ技術スタックの一部を共有します。PodmanはCLI/管理ツールであり、KubernetesのCRIランタイムではありません。
なぜCRI-Oが重要か
- Kubernetes専用設計: 不要な機能を削ぎ落とし、高速・軽量
- Podmanとの共通基盤: 同じコンテナ技術スタック
- セキュリティ: 最小権限で動作
インストールと設定
# RHEL/CentOSでのインストール
sudo dnf module enable cri-o:1.26
sudo dnf install -y cri-o
# systemd有効化
sudo systemctl enable --now crio
# 動作確認
sudo crictl version
sudo crictl info
11.5.2 Kubernetesクラスターでの使用
# kubeadmでのCRI-O使用
sudo kubeadm init \
--cri-socket=unix:///var/run/crio/crio.sock \
--upload-certs
# kubelet設定
cat > /etc/sysconfig/kubelet << EOF
KUBELET_EXTRA_ARGS=--container-runtime-endpoint=unix:///var/run/crio/crio.sock
EOF
# ワーカーノード参加
sudo kubeadm join <master-ip>:6443 \
--token <token> \
--discovery-token-ca-cert-hash sha256:<hash> \
--cri-socket=unix:///var/run/crio/crio.sock
11.6 開発環境でのKubernetes
11.6.1 Minikubeとの統合
# 注記: `minikube --driver=podman` は experimental 扱いです。再現性重視の演習やチームでの手順共有は kind を推奨します。
# Podmanドライバーでminikube起動
minikube start --driver=podman --container-runtime=cri-o
# Podmanコンテキスト設定
eval $(minikube podman-env)
# ローカルイメージの使用
podman build -t myapp:dev .
kubectl run myapp --image=myapp:dev --image-pull-policy=Never
11.6.2 Kindとの統合
# クラスター作成(rootless Podman provider; 公式推奨)
KIND_EXPERIMENTAL_PROVIDER=podman kind create cluster
# 一部環境では systemd-run が必要(公式docsの記載)
systemd-run --scope --user env KIND_EXPERIMENTAL_PROVIDER=podman kind create cluster
# まだエラーが出る場合
systemd-run --scope --user -p "Delegate=yes" env KIND_EXPERIMENTAL_PROVIDER=podman kind create cluster
# ローカルレジストリ設定
podman run -d -p 5000:5000 --name registry registry:2
※ podman.sock を docker.sock としてマウントする構成例は特殊環境向けのため、本章では標準手順として扱いません。
11.7 実践演習
演習1: マイクロサービスアプリケーションの移行
シナリオ: 3つのマイクロサービスからなるアプリケーションをPodmanからKubernetesに移行する
手順:
- Podmanでマイクロサービスを構築
- podman kube generateでYAML生成
- 生成されたYAMLをカスタマイズ
- kind(推奨)またはMinikubeでテスト
- 本番相当の設定を追加
期待される成果:
- 移行プロセスの理解
- YAML編集スキルの向上
- トラブルシューティング能力の獲得
まとめ
- PodmanとKubernetesの関係を整理し、ローカル開発〜本番移行のギャップを埋める位置づけを確認しました。
podman kube play/podman kube generateを中心に、YAMLの実行・生成・カスタマイズの流れを扱いました。- 制限事項や運用上の落とし穴を踏まえ、段階的な移行の進め方の観点を示しました。