序論:コンテナオーケストレーションの標準

これまでDockerを通じてコンテナを作成し管理する方法を学びました。しかし、実際のプロダクション環境では、数十、数百のコンテナを複数のサーバーにわたって運用する必要があります。この時、各コンテナを手動で管理することは事実上不可能です。

この第6編では、コンテナオーケストレーションの事実上の標準となったKubernetes(クーバネティス、K8s)の基礎概念とアーキテクチャを見ていきます。Kubernetesとは何か、なぜ必要なのか、そしてどのように構成されているかを理解すれば、クラウドネイティブ環境でのアプリケーション運用について全体的なイメージを描くことができます。

1. Kubernetesとは?

1.1 Kubernetesの定義

Kubernetesは、コンテナ化されたアプリケーションのデプロイ、スケーリング、管理を自動化するオープンソースプラットフォームです。ギリシャ語で「舵取り」または「パイロット」を意味し、コンテナという「貨物」を適切に運搬し管理する役割を果たします。

「K8s」という略称は、KとsのJ間に8文字(ubernete)があることに由来しています。

1.2 Kubernetesの歴史

  • 2014年:Googleが内部で使用していたBorgシステムの経験を基にKubernetesをオープンソースとして公開
  • 2015年:バージョン1.0リリース、Cloud Native Computing Foundation(CNCF)に寄贈
  • 2018年:CNCFの最初の「卒業」プロジェクト
  • 現在:コンテナオーケストレーションの事実上の標準として定着

1.3 Kubernetesが提供する機能

  • サービスディスカバリとロードバランシング:DNS名やIPアドレスでコンテナを公開し、トラフィックを分散
  • ストレージオーケストレーション:ローカルストレージ、クラウドストレージなどを自動でマウント
  • 自動化されたロールアウトとロールバック:アプリケーションの変更を段階的にデプロイし、問題時は以前のバージョンにロールバック
  • 自動ビンパッキング:リソース要求に応じてコンテナをノードに最適配置
  • 自己修復(Self-healing):失敗したコンテナを再起動し、応答しないコンテナを置き換え
  • シークレットと構成管理:機密情報を安全に保存し管理

2. なぜKubernetesが必要なのか?

2.1 Dockerだけでは不十分な理由

単一サーバーでいくつかのコンテナを運用する際はDockerだけで十分です。しかし、実際のプロダクション環境では次のような要件があります:

  • 数百のコンテナを複数のサーバーに分散デプロイ
  • トラフィック増加時に自動でコンテナ数を拡張
  • コンテナ障害時の自動復旧
  • 無停止デプロイ(Rolling Update、Blue-Green、Canary)
  • コンテナ間のネットワークおよびストレージ管理
  • リソースモニタリングとロギング

2.2 コンテナオーケストレーションの必要性

コンテナオーケストレーションとは、コンテナのデプロイ、管理、スケーリング、ネットワーキングを自動化することを意味します。オーケストラの指揮者が複数の楽器を調律するように、コンテナオーケストレーターは数多くのコンテナを調整します。

手動管理の問題点 オーケストレーションの解決策
サーバー障害時に手動復旧が必要 自動障害検知と復旧
トラフィック増加時に手動スケーリング 自動スケーリング(HPA、VPA)
デプロイ時にダウンタイム発生 無停止ローリングアップデート
コンテナ配置の最適化が困難 自動スケジューリングとビンパッキング
サービス間通信が複雑 サービスディスカバリとロードバランシング

2.3 Kubernetes vs 他のオーケストレーションツール

  • Docker Swarm:Dockerネイティブオーケストレーション、シンプルだが機能が限定的
  • Apache Mesos:汎用クラスター管理ツール、学習曲線が高い
  • Nomad:HashiCorpのオーケストレーションツール、軽量
  • Kubernetes:最も多くの機能、最大のエコシステム、事実上の標準

3. Kubernetesアーキテクチャ

Kubernetesクラスターは大きくControl Plane(コントロールプレーン)とWorker Node(ワーカーノード)で構成されます。

3.1 Control Plane(マスターノード)

Control Planeはクラスターの「頭脳」の役割を果たします。クラスターの状態を管理し、ワーカーノードで実行されるワークロードをスケジューリングします。

3.1.1 API Server(kube-apiserver)

Kubernetesのすべての通信の中心です。kubectlコマンド、他のコンポーネント、外部クライアントはすべてAPI Serverを通じてクラスターと対話します。

  • RESTful API提供
  • 認証(Authentication)、認可(Authorization)処理
  • リクエストの検証
  • etcdとの唯一の通信窓口

3.1.2 etcd

クラスターのすべての状態データを保存する分散キーバリューストアです。

  • クラスター構成、状態、メタデータを保存
  • 高可用性のため通常3つまたは5つのインスタンスで構成
  • Raft合意アルゴリズムを使用
  • クラスターバックアップ = etcdバックアップ

3.1.3 Scheduler(kube-scheduler)

新しく作成されたPodをどのノードに配置するかを決定します。

  • リソース要件(CPU、メモリ)を考慮
  • ノードの利用可能なリソースを確認
  • アフィニティ/アンチアフィニティルールを適用
  • Taint(テイント)とToleration(トレレーション)を処理

3.1.4 Controller Manager(kube-controller-manager)

クラスターの状態を望ましい状態に維持するさまざまなコントローラーを実行します。

  • Node Controller:ノード状態のモニタリング
  • Replication Controller:Pod数の維持
  • Endpoints Controller:サービスとPodの接続
  • Service Account Controller:アカウントとトークンの生成

3.1.5 Cloud Controller Manager(オプション)

クラウドプロバイダーのAPIと統合してクラウド固有の機能を管理します。

  • ロードバランサーのプロビジョニング
  • ストレージボリュームの管理
  • ノード管理(クラウドインスタンス)

3.2 Worker Node

Worker Nodeは実際にアプリケーションコンテナが実行されるサーバーです。

3.2.1 kubelet

各ノードで実行されるエージェントで、Podのライフサイクルを管理します。

  • API ServerからPod仕様(PodSpec)を受信
  • コンテナランタイムにコンテナの作成/削除を要求
  • コンテナ状態のモニタリングと報告
  • ノード状態情報をAPI Serverに報告

3.2.2 kube-proxy

各ノードでネットワークプロキシの役割を果たします。

  • Serviceの仮想IPを実際のPod IPにマッピング
  • iptablesまたはIPVSルールの管理
  • クラスター内部および外部トラフィックのルーティング
  • ロードバランシング(ラウンドロビン)

3.2.3 Container Runtime

実際にコンテナを実行するソフトウェアです。

  • containerd:Dockerから分離された業界標準ランタイム
  • CRI-O:Kubernetes専用の軽量ランタイム
  • Docker Engine:Kubernetes 1.24から直接サポート終了(dockershim削除)

3.3 アーキテクチャダイアグラム

┌─────────────────────────────────────────────────────────────────┐
│                       CONTROL PLANE                             │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐             │
│  │ API Server  │  │  Scheduler  │  │ Controller  │             │
│  │             │  │             │  │  Manager    │             │
│  └──────┬──────┘  └─────────────┘  └─────────────┘             │
│         │                                                       │
│  ┌──────┴──────┐                                               │
│  │    etcd     │                                               │
│  │ (Key-Value) │                                               │
│  └─────────────┘                                               │
└─────────────────────────────────────────────────────────────────┘
                              │
                              │ (API通信)
                              │
┌─────────────────────────────────────────────────────────────────┐
│                       WORKER NODE 1                             │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐             │
│  │   kubelet   │  │  kube-proxy │  │  Container  │             │
│  │             │  │             │  │   Runtime   │             │
│  └─────────────┘  └─────────────┘  └─────────────┘             │
│  ┌─────────┐ ┌─────────┐ ┌─────────┐                           │
│  │  Pod 1  │ │  Pod 2  │ │  Pod 3  │                           │
│  └─────────┘ └─────────┘ └─────────┘                           │
└─────────────────────────────────────────────────────────────────┘

4. Kubernetesコアオブジェクト

4.1 Pod

PodはKubernetesで作成・管理できる最小のデプロイ単位です。

Podの特徴:

  • 1つ以上のコンテナを含む
  • 同じPod内のコンテナはネットワークとストレージを共有
  • 同じPod内のコンテナはlocalhostで通信
  • 一般的に1つのメインコンテナ + 補助コンテナ(Sidecar)
  • Podは一時的(ephemeral)- いつでも削除され再作成される可能性がある
# pod-example.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.24
    ports:
    - containerPort: 80
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"

4.2 Service

ServiceはPod集合に対する安定したネットワークエンドポイントを提供します。PodのIPは変わる可能性がありますが、ServiceのIP(ClusterIP)は固定されます。

Serviceタイプ:

  • ClusterIP(デフォルト):クラスター内部からのみアクセス可能
  • NodePort:各ノードの特定ポートで外部アクセスを許可
  • LoadBalancer:クラウドロードバランサーを通じた外部アクセス
  • ExternalName:外部DNS名をクラスター内部にマッピング
# service-example.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx    # このラベルを持つPodにトラフィックを転送
  ports:
  - protocol: TCP
    port: 80        # Serviceポート
    targetPort: 80  # Podのコンテナポート
  type: ClusterIP

4.3 Deployment

DeploymentはPodの宣言的アップデートを提供します。望ましい状態を定義すると、Deployment Controllerが実際の状態を望ましい状態に合わせます。

Deploymentの機能:

  • Pod数(replicas)の管理
  • ローリングアップデートとロールバック
  • スケーリング(手動/自動)
  • Podテンプレートの管理
# deployment-example.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3    # 3つのPodを維持
  selector:
    matchLabels:
      app: nginx
  template:      # Podテンプレート
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.24
        ports:
        - containerPort: 80
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1        # ローリングアップデート時に追加作成するPod数
      maxUnavailable: 0  # ローリングアップデート時に使用不可のPod数

4.4 Namespace

Namespaceはクラスターを論理的に分離する仮想クラスターです。

デフォルトNamespace:

  • default:特に指定なく作成されるリソースのデフォルトネームスペース
  • kube-system:Kubernetesシステムコンポーネント用
  • kube-public:すべてのユーザーが読み取れる公開リソース
  • kube-node-lease:ノードハートビート情報を保存
# namespace-example.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: development
  labels:
    environment: dev
---
apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    environment: prod

Namespaceの活用:

  • 環境分離(dev、staging、production)
  • チーム別リソース分離
  • リソースクォータ(ResourceQuota)の適用
  • ネットワークポリシー(NetworkPolicy)の適用

5. kubectl基礎

kubectlはKubernetesクラスターと対話するためのコマンドラインツールです。

5.1 kubectlのインストール

# macOS (Homebrew)
brew install kubectl

# Windows (Chocolatey)
choco install kubernetes-cli

# Linux (curl)
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/

5.2 基本コマンド構造

kubectl [command] [TYPE] [NAME] [flags]

# 例
kubectl get pods                    # すべてのPodを取得
kubectl get pod nginx-pod           # 特定のPodを取得
kubectl get pods -n kube-system     # kube-systemネームスペースのPodを取得
kubectl get pods -o wide            # 詳細情報を含めて取得
kubectl get pods -o yaml            # YAML形式で出力

5.3 よく使うコマンド

リソース取得(get)

# Podリスト取得
kubectl get pods
kubectl get pods -A                 # すべてのネームスペース

# Serviceリスト取得
kubectl get services
kubectl get svc                     # 略語使用

# Deploymentリスト取得
kubectl get deployments
kubectl get deploy                  # 略語使用

# 複数リソースを同時に取得
kubectl get pods,services,deployments

# ラベルでフィルタリング
kubectl get pods -l app=nginx

# すべてのリソースを取得
kubectl get all

リソース詳細情報(describe)

# Pod詳細情報
kubectl describe pod nginx-pod

# Node詳細情報
kubectl describe node node-1

# Service詳細情報
kubectl describe service nginx-service

リソース作成(create、apply)

# YAMLファイルでリソース作成
kubectl apply -f deployment.yaml

# ディレクトリ内のすべてのYAMLファイルを適用
kubectl apply -f ./manifests/

# 命令的にリソース作成
kubectl create deployment nginx --image=nginx:1.24
kubectl create namespace my-namespace

# Dry-run(実際に作成せずにテスト)
kubectl apply -f deployment.yaml --dry-run=client

リソース修正(edit、patch、scale)

# リソースを直接編集(エディタが開く)
kubectl edit deployment nginx-deployment

# パッチで部分修正
kubectl patch deployment nginx-deployment -p '{"spec":{"replicas":5}}'

# スケール調整
kubectl scale deployment nginx-deployment --replicas=5

リソース削除(delete)

# 特定リソースを削除
kubectl delete pod nginx-pod
kubectl delete deployment nginx-deployment

# YAMLファイルで定義されたリソースを削除
kubectl delete -f deployment.yaml

# ラベルで削除
kubectl delete pods -l app=nginx

# ネームスペースとその中のすべてのリソースを削除
kubectl delete namespace development

ログとデバッグ

# Podログを取得
kubectl logs nginx-pod
kubectl logs nginx-pod -f           # リアルタイムログストリーミング
kubectl logs nginx-pod --previous   # 以前のコンテナログ

# マルチコンテナPodで特定コンテナのログ
kubectl logs nginx-pod -c sidecar

# Pod内部でコマンド実行
kubectl exec nginx-pod -- ls /usr/share/nginx/html
kubectl exec -it nginx-pod -- /bin/bash  # インタラクティブシェル

# ポートフォワーディング(ローカルからPodにアクセス)
kubectl port-forward pod/nginx-pod 8080:80
kubectl port-forward service/nginx-service 8080:80

5.4 コンテキストとネームスペース管理

# 現在のコンテキストを確認
kubectl config current-context

# 利用可能なコンテキストリスト
kubectl config get-contexts

# コンテキスト切り替え
kubectl config use-context my-cluster

# デフォルトネームスペースを変更
kubectl config set-context --current --namespace=development

5.5 便利なkubectlプラグインとツール

# kubectx - コンテキストの素早い切り替え
brew install kubectx
kubectx                  # コンテキストリストと切り替え
kubens                   # ネームスペースリストと切り替え

# k9s - ターミナルUI
brew install k9s
k9s

# kubectl自動補完(bash)
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc

# kubectlエイリアス設定
alias k='kubectl'
alias kgp='kubectl get pods'
alias kgs='kubectl get services'

6. 実習:最初のアプリケーションデプロイ

6.1 ローカルKubernetes環境設定

# Docker DesktopでKubernetesを有効化
# Settings > Kubernetes > Enable Kubernetes

# またはMinikubeを使用
brew install minikube
minikube start

# クラスター状態を確認
kubectl cluster-info
kubectl get nodes

6.2 Nginxをデプロイ

# 1. Deploymentを作成
kubectl create deployment nginx-demo --image=nginx:1.24

# 2. Deploymentを確認
kubectl get deployments
kubectl get pods

# 3. Serviceを作成(NodePortタイプ)
kubectl expose deployment nginx-demo --type=NodePort --port=80

# 4. Serviceを確認
kubectl get services

# 5. 接続テスト(Minikube)
minikube service nginx-demo

# 6. またはポートフォワーディング
kubectl port-forward service/nginx-demo 8080:80
# ブラウザで http://localhost:8080 にアクセス

6.3 スケーリングテスト

# Pod数を拡張
kubectl scale deployment nginx-demo --replicas=5

# Podを確認
kubectl get pods -o wide

# Pod数を縮小
kubectl scale deployment nginx-demo --replicas=2

6.4 ローリングアップデート

# イメージをアップデート
kubectl set image deployment/nginx-demo nginx=nginx:1.25

# ロールアウト状態を確認
kubectl rollout status deployment/nginx-demo

# ロールアウト履歴
kubectl rollout history deployment/nginx-demo

# ロールバック
kubectl rollout undo deployment/nginx-demo

6.5 クリーンアップ

# リソースを削除
kubectl delete deployment nginx-demo
kubectl delete service nginx-demo

# または一度に
kubectl delete deployment,service nginx-demo

7. Kubernetes学習リソース

7.1 公式ドキュメント

  • Kubernetes公式ドキュメント:https://kubernetes.io/docs/
  • Kubernetesチュートリアル:https://kubernetes.io/docs/tutorials/
  • kubectlチートシート:https://kubernetes.io/docs/reference/kubectl/cheatsheet/

7.2 ローカル学習環境

  • Minikube:ローカルKubernetesクラスター
  • Kind(Kubernetes in Docker):Dockerコンテナでクラスターを実行
  • Docker Desktop:内蔵Kubernetesサポート
  • k3s:軽量Kubernetesディストリビューション

7.3 オンライン実習環境

  • Katacoda:ブラウザベースKubernetes実習
  • Play with Kubernetes:無料オンラインKubernetes環境

結論

この第6編では、Kubernetesの基礎概念とアーキテクチャを見てきました。重要なポイントをまとめると:

  • Kubernetesとは:コンテナオーケストレーションの事実上の標準プラットフォーム
  • アーキテクチャ:Control Plane(API Server、etcd、Scheduler、Controller Manager)とWorker Node(kubelet、kube-proxy、Container Runtime)で構成
  • コアオブジェクト:Pod(最小デプロイ単位)、Service(ネットワークエンドポイント)、Deployment(宣言的Pod管理)、Namespace(論理的分離)
  • kubectl:Kubernetesクラスターと対話するCLIツール

Kubernetesは最初は複雑に見えますが、その設計哲学である「宣言的構成」と「望ましい状態(Desired State)」を理解すれば、非常に強力で柔軟なツールであることがわかります。

次の編ではKubernetes実践を扱います。ConfigMapとSecretによる設定管理、Ingressによる外部トラフィックルーティング、PersistentVolumeによるデータ永続性など、実際の運用に必要な応用テーマを見ていきます。