Kubernetes基礎 - Pod, Service, Deployment
📚 概要
Kubernetes(K8s)は、コンテナ化されたアプリケーションのデプロイ、スケーリング、管理を自動化するオープンソースのコンテナオーケストレーションプラットフォームです。
この記事では、Kubernetesの核となる3つのリソース(Pod、Service、Deployment)を詳しく解説します。
🕰️ 歴史的背景
コンテナオーケストレーションの必要性
2010年代初頭、Dockerの登場によりコンテナ技術が普及しました。しかし、本番環境で数百〜数千のコンテナを管理するには、手動では限界がありました。
課題:
- コンテナの自動配置とスケジューリング
- 障害時の自動復旧
- 負荷分散
- ローリングアップデート
- サービスディスカバリ
Kubernetesの誕生 - 2014年
- 開発元: Google(Borgシステムの経験を基に開発)
- オープンソース化: 2014年6月
- CNCF管理下: 2015年7月
- v1.0リリース: 2015年7月
Googleは10年以上にわたりコンテナ技術を本番環境で運用しており、その知見を Kubernetes に注ぎ込みました。
主要な競合:
- Docker Swarm(2014年)
- Apache Mesos(2009年)
- HashiCorp Nomad(2015年)
しかし、Kubernetesが事実上の標準となり、現在では最も広く使われています。
🔧 技術解説
Kubernetesのアーキテクチャ
graph TB
subgraph ControlPlane[Control Plane]
API[API Server]
ETCD[etcd Database]
SCHED[Scheduler]
CTRL[Controller Manager]
end
subgraph Node1[Worker Node 1]
KUBELET1[Kubelet]
PROXY1[kube-proxy]
POD1[Pods]
end
subgraph Node2[Worker Node 2]
KUBELET2[Kubelet]
PROXY2[kube-proxy]
POD2[Pods]
end
API --> ETCD
API --> SCHED
API --> CTRL
API --> KUBELET1
API --> KUBELET2
KUBELET1 --> POD1
KUBELET2 --> POD2
style ControlPlane fill:#4dabf7
style Node1 fill:#51cf66
style Node2 fill:#51cf66コンポーネント:
- Control Plane: クラスタ全体を管理
- API Server: すべての操作の入り口
- etcd: クラスタの状態を保存
- Scheduler: Podをどのノードに配置するか決定
- Controller Manager: 各種コントローラを実行
- Worker Node: 実際にコンテナが動くサーバー
- Kubelet: Podのライフサイクルを管理
- kube-proxy: ネットワークルールを管理
- Container Runtime: Docker/containerd など
1. Pod - 最小のデプロイ単位
Podは、1つ以上のコンテナをグループ化したものです。
特徴:
- 同じPod内のコンテナは同じノードで動く
- IPアドレスを共有
- ストレージを共有可能
- 一緒にスケールする
基本的なPod定義:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
複数コンテナのPod:
apiVersion: v1
kind: Pod
metadata:
name: web-app
spec:
containers:
- name: app
image: myapp:1.0
ports:
- containerPort: 8080
- name: sidecar-logger
image: fluentd:latest
volumeMounts:
- name: logs
mountPath: /var/log
volumes:
- name: logs
emptyDir: {}
2. Service - ネットワーク抽象化
Serviceは、Podへのネットワークアクセスを提供する抽象化レイヤーです。
なぜ必要?
- Podは一時的(作り直されるとIPアドレスが変わる)
- 複数のPodに負荷分散したい
- 外部からアクセスしたい
Serviceのタイプ:
graph TB
A[Service Types] --> B[ClusterIP]
A --> C[NodePort]
A --> D[LoadBalancer]
A --> E[ExternalName]
B --> F[Internal access only]
C --> G[Access via Node IP + Port]
D --> H[Cloud LB integration]
E --> I[DNS CNAME record]
style B fill:#4dabf7
style C fill:#51cf66
style D fill:#ff6b6b
style E fill:#ffd43bClusterIP Service(デフォルト):
apiVersion: v1
kind: Service
metadata:
name: backend-service
spec:
selector:
app: backend
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: ClusterIP
NodePort Service(開発環境向け):
apiVersion: v1
kind: Service
metadata:
name: frontend-service
spec:
selector:
app: frontend
ports:
- protocol: TCP
port: 80
targetPort: 3000
nodePort: 30001
type: NodePort
LoadBalancer Service(本番環境向け):
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: web
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: LoadBalancer
3. Deployment - 宣言的なアップデート
Deploymentは、Podのレプリカセットを管理し、ローリングアップデートやロールバックを提供します。
基本的なDeployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
ローリングアップデート:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
spec:
replicas: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:2.0
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi
ローリングアップデートの流れ:
graph LR
A[v1.0 Pods] --> B[Create v2.0 Pod]
B --> C[Wait Ready]
C --> D[Terminate v1.0 Pod]
D --> E{All Updated?}
E -->|No| B
E -->|Yes| F[Complete]
style A fill:#ff6b6b
style F fill:#51cf66💡 実践例
例1: Webアプリケーションのデプロイ
1. Deployment作成:
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp
spec:
replicas: 3
selector:
matchLabels:
app: webapp
template:
metadata:
labels:
app: webapp
spec:
containers:
- name: webapp
image: mywebapp:1.0
ports:
- containerPort: 8080
env:
- name: DATABASE_URL
value: "postgresql://db:5432/mydb"
2. Service作成:
apiVersion: v1
kind: Service
metadata:
name: webapp-service
spec:
selector:
app: webapp
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: LoadBalancer
3. デプロイ:
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
# 確認
kubectl get deployments
kubectl get pods
kubectl get services
例2: スケーリング
# 手動スケーリング
kubectl scale deployment webapp --replicas=5
# オートスケーリング
kubectl autoscale deployment webapp --min=3 --max=10 --cpu-percent=70
例3: ローリングアップデート
# イメージを更新
kubectl set image deployment/webapp webapp=mywebapp:2.0
# ロールアウト状況確認
kubectl rollout status deployment/webapp
# ロールバック
kubectl rollout undo deployment/webapp
📊 リソース管理
CPU とメモリの制限
resources:
requests:
cpu: "100m" # 0.1 CPU core
memory: "128Mi" # 128 MiB
limits:
cpu: "200m" # 0.2 CPU core
memory: "256Mi" # 256 MiB
requests vs limits:
| requests | limits | |
|---|---|---|
| 意味 | 最低保証リソース | 最大使用可能リソース |
| スケジューリング | これを満たすノードに配置 | 影響しない |
| 超過時 | なし | コンテナが強制終了される可能性 |
🎯 ベストプラクティス
1. ヘルスチェックの設定
spec:
containers:
- name: myapp
image: myapp:1.0
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
Liveness vs Readiness:
- Liveness: コンテナが生きているか(死んでいたら再起動)
- Readiness: トラフィックを受ける準備ができているか
2. リソース制限の設定
常に requests と limits を設定しましょう。
3. ラベルとセレクタの活用
metadata:
labels:
app: myapp
env: production
version: v2.0
4. ConfigMap と Secret の使用
# ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
database.host: "db.example.com"
database.port: "5432"
---
# Secret
apiVersion: v1
kind: Secret
metadata:
name: app-secret
type: Opaque
data:
password: cGFzc3dvcmQxMjM= # base64エンコード
🔍 関連する問題
この記事に関連するクイズ問題:
- Q2: Kubernetesの基本概念
- Q19: Deploymentとスケーリング
📝 まとめ
- Pod: コンテナをグループ化する最小単位
- Service: Podへのネットワークアクセスを抽象化
- Deployment: 宣言的なアップデートとスケーリング
- Control Plane: クラスタ全体を管理
- Worker Node: 実際にコンテナが動く場所
次のステップ: 実際にKubernetesクラスタを構築し、アプリケーションをデプロイしてみましょう!
推奨リソース:
- Kubernetes公式ドキュメント
- minikube - ローカル環境でK8sを試す
- kind - Docker上でK8sクラスタを構築