Docker & Kubernetes完全攻略 第8編:Pod、Deployment、Service深掘り
Docker & Kubernetes Complete Guide Part 8: Pod, Deployment, and Service Deep Dive
序論:Kubernetesの三大核心リソース
Kubernetesでアプリケーションを運用する際、最も頻繁に接するリソースはPod、Deployment、Serviceです。PodはKubernetesで作成できる最小のコンピューティング単位であり、Deploymentはこれらのデプロイと管理を自動化し、Serviceはネットワークを通じてPodへのアクセス方法を提供します。
この第8編では、これら3つのリソースを深く掘り下げ、実務で活用できるレベルまで理解を深めます。
1. Pod深掘り
1.1 Podとは?
PodはKubernetesで作成・管理できる最小のデプロイ可能な単位です。1つ以上のコンテナを含み、ストレージとネットワークリソースを共有します。
- 同じPod内のコンテナは同じIPアドレスを共有します
- localhostを通じて相互に通信できます
- 同じボリュームをマウントできます
- Podは一時的(ephemeral)です - いつでも削除され再作成される可能性があります
1.2 PodのYAML構造
# pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
labels:
app: my-app
environment: production
annotations:
description: "メインアプリケーションPod"
spec:
containers:
- name: main-container
image: nginx:1.24
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
env:
- name: APP_ENV
value: "production"
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: app-config
restartPolicy: Always
1.3 Podのライフサイクル
Podは以下のフェーズを経ます:
| フェーズ | 説明 |
|---|---|
| Pending | Podが作成されましたが、まだコンテナが実行されていません |
| Running | Podがノードにバインドされ、すべてのコンテナが作成されました |
| Succeeded | すべてのコンテナが正常に終了しました(再起動なし) |
| Failed | 1つ以上のコンテナが失敗状態で終了しました |
| Unknown | Podの状態を取得できません |
1.4 マルチコンテナPodパターン
1つのPodに複数のコンテナを含める一般的なパターンがあります:
1. サイドカーパターン(Sidecar)
メインコンテナの機能を拡張または補助します。
apiVersion: v1
kind: Pod
metadata:
name: sidecar-example
spec:
containers:
- name: main-app
image: my-app:latest
ports:
- containerPort: 8080
- name: log-collector
image: fluentd:latest
volumeMounts:
- name: log-volume
mountPath: /var/log/app
volumes:
- name: log-volume
emptyDir: {}
2. アンバサダーパターン(Ambassador)
外部サービスへの接続をプロキシします。
apiVersion: v1
kind: Pod
metadata:
name: ambassador-example
spec:
containers:
- name: main-app
image: my-app:latest
env:
- name: DB_HOST
value: "localhost"
- name: DB_PORT
value: "5432"
- name: db-ambassador
image: ambassador-proxy:latest
ports:
- containerPort: 5432
3. アダプターパターン(Adapter)
メインコンテナの出力を標準化します。
1.5 ProbeによるヘルスチェックC
Kubernetesはコンテナの状態を確認するための3種類のProbeを提供します:
apiVersion: v1
kind: Pod
metadata:
name: probe-example
spec:
containers:
- name: app
image: my-app:latest
ports:
- containerPort: 8080
# livenessProbe: コンテナが正常かどうかを確認
# 失敗時コンテナを再起動
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 15
periodSeconds: 10
failureThreshold: 3
# readinessProbe: トラフィックを受け入れる準備ができているかを確認
# 失敗時Serviceのエンドポイントから除外
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
# startupProbe: アプリケーションが起動したかを確認
# 成功するまで他のProbeは実行されない
startupProbe:
httpGet:
path: /startup
port: 8080
failureThreshold: 30
periodSeconds: 10
2. ReplicaSetの理解
2.1 ReplicaSetとは?
ReplicaSetは指定された数のPodレプリカが常に実行されるように保証します。Podが削除されたりノードに障害が発生した場合、新しいPodを作成して希望するレプリカ数を維持します。
直接ReplicaSetを作成することはほとんどありません。Deploymentが内部的にReplicaSetを管理するためです。
2.2 ReplicaSetの構造
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: my-replicaset
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-container
image: nginx:1.24
ports:
- containerPort: 80
3. Deployment深掘り
3.1 Deploymentとは?
DeploymentはPodとReplicaSetに対する宣言的更新を提供します。希望する状態(desired state)を記述すると、Deployment Controllerが実際の状態を希望する状態に変更します。
Deploymentの主な機能:
- Pod数(replicas)の維持
- ローリングアップデート
- ロールバック
- スケーリング
- 一時停止と再開
3.2 DeploymentのYAML構造
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
labels:
app: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-container
image: nginx:1.24
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
revisionHistoryLimit: 10
progressDeadlineSeconds: 600
3.3 ローリングアップデート
ローリングアップデートはダウンタイムなしでアプリケーションを更新する方式です。
# イメージを更新
kubectl set image deployment/my-deployment my-container=nginx:1.25
# またはYAMLを編集
kubectl edit deployment my-deployment
# ロールアウト状態を確認
kubectl rollout status deployment/my-deployment
# ロールアウト履歴を確認
kubectl rollout history deployment/my-deployment
# 特定のリビジョンの詳細を確認
kubectl rollout history deployment/my-deployment --revision=2
# ロールバック(直前のリビジョンに)
kubectl rollout undo deployment/my-deployment
# 特定のリビジョンにロールバック
kubectl rollout undo deployment/my-deployment --to-revision=2
3.4 アップデート戦略
RollingUpdate(デフォルト)
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25% # 更新中に追加で作成可能なPod数
maxUnavailable: 25% # 更新中に使用不可のPod数
Recreate
spec:
strategy:
type: Recreate # すべてのPodを削除してから新しいPodを作成
3.5 スケーリング
# 手動スケーリング
kubectl scale deployment my-deployment --replicas=5
# HPAによる自動スケーリング
kubectl autoscale deployment my-deployment --min=2 --max=10 --cpu-percent=80
4. Service深掘り
4.1 Serviceとは?
ServiceはPod集合に対する安定したネットワークエンドポイントを提供します。PodのIPアドレスは変わる可能性がありますが、ServiceのIP(ClusterIP)と名前は固定されます。
4.2 Serviceタイプ
| タイプ | 説明 | 用途 |
|---|---|---|
| ClusterIP | クラスター内部IPを割り当て(デフォルト) | 内部通信 |
| NodePort | 各ノードの固定ポートで公開 | 外部アクセス(開発/テスト) |
| LoadBalancer | クラウドLBを通じて公開 | プロダクション外部アクセス |
| ExternalName | 外部DNS名をマッピング | 外部サービス接続 |
4.3 ClusterIP Service
# clusterip-service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-clusterip-service
spec:
type: ClusterIP # デフォルト
selector:
app: my-app
ports:
- protocol: TCP
port: 80 # Serviceポート
targetPort: 8080 # Podのコンテナポート
4.4 NodePort Service
# nodeport-service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-nodeport-service
spec:
type: NodePort
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
nodePort: 30080 # 30000-32767範囲(省略時自動割り当て)
4.5 LoadBalancer Service
# loadbalancer-service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-loadbalancer-service
annotations:
# クラウドプロバイダー固有の設定
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
spec:
type: LoadBalancer
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
4.6 ExternalName Service
# externalname-service.yaml
apiVersion: v1
kind: Service
metadata:
name: external-database
spec:
type: ExternalName
externalName: database.example.com
4.7 ヘッドレスService
ClusterIPを「None」に設定すると、ServiceのIPは割り当てられず、DNS経由で直接PodのIPを取得できます。StatefulSetと共に使用されることが多いです。
# headless-service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-headless-service
spec:
clusterIP: None
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
5. ラベルとセレクター
5.1 ラベル(Labels)
ラベルはKubernetesオブジェクトに付けるキー/値のペアです。オブジェクトを識別し、グループ化するために使用されます。
metadata:
labels:
app: my-app
environment: production
tier: frontend
version: v1.0.0
5.2 セレクター(Selectors)
セレクターはラベルに基づいてリソースを選択します。
等価ベースセレクター:
selector:
matchLabels:
app: my-app
environment: production
集合ベースセレクター:
selector:
matchExpressions:
- key: environment
operator: In
values:
- production
- staging
- key: tier
operator: NotIn
values:
- test
6. 実践例:完全なアプリケーションデプロイ
# complete-deployment.yaml
---
apiVersion: v1
kind: Namespace
metadata:
name: my-app
---
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: my-app
data:
APP_ENV: "production"
LOG_LEVEL: "info"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
namespace: my-app
labels:
app: web-app
spec:
replicas: 3
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web
image: nginx:1.24
ports:
- containerPort: 80
envFrom:
- configMapRef:
name: app-config
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 10
periodSeconds: 5
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 3
---
apiVersion: v1
kind: Service
metadata:
name: web-app-service
namespace: my-app
spec:
type: ClusterIP
selector:
app: web-app
ports:
- protocol: TCP
port: 80
targetPort: 80
# デプロイ
kubectl apply -f complete-deployment.yaml
# 確認
kubectl get all -n my-app
# ポートフォワーディングでテスト
kubectl port-forward service/web-app-service 8080:80 -n my-app
結論
この第8編では、KubernetesのコアリソースであるPod、Deployment、Serviceを詳しく学びました。
- Pod:Kubernetesの最小デプロイ単位で、1つ以上のコンテナを含みます
- Deployment:Podのデプロイと管理を自動化し、ローリングアップデートとロールバックを提供します
- Service:Podに安定したネットワークアクセスを提供し、さまざまなタイプ(ClusterIP、NodePort、LoadBalancer)をサポートします
これらのリソースの理解は、Kubernetesを効果的に活用するための基礎となります。次の第9編では、ConfigMap、Secret、Ingressについて詳しく学んでいきます。