Engineer Quiz

← 記事一覧

Kubernetes基礎 - Pod, Service, Deployment

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:#ffd43b

ClusterIP 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. リソース制限の設定

常に requestslimits を設定しましょう。

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クラスタを構築し、アプリケーションをデプロイしてみましょう!


推奨リソース: