0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【書評】Kubernetes Patterns, 2nd Edition

0
Posted at

はじめに

「Kubernetes Patterns, 2nd Edition」(O'Reilly)は、Kubernetesを使ったクラウドネイティブアプリケーション設計における、繰り返し現れる問題とその解決策を「パターン」という形で体系化した一冊です。

コンテナのライフサイクル管理からセキュリティ設計、オペレータパターンまで、6つのパートに分けて30以上のパターンが解説されています。本書の最大の価値は、Kubernetesの各機能を「なぜ必要か」という問題意識から説明している点にあります。チームでの設計議論に使える共通言語を得られる一冊です。


本書の構成

本書は6部構成になっています。

パート テーマ
Part I 基礎パターン
Part II 行動パターン
Part III 構造パターン
Part IV 構成パターン
Part V セキュリティパターン
Part VI 高度なパターン

Part I:基礎パターン

第1章 はじめに——クラウドネイティブへの道

本書はまず、優れたクラウドネイティブアプリケーションを作るために必要なスキル層を整理します。

  • コードレベル:クリーンコード、継続的リファクタリング
  • ドメイン駆動設計:境界付きコンテキスト、集約
  • ヘキサゴナルアーキテクチャ:コアビジネスロジックとインフラの分離
  • マイクロサービス / Twelve-Factor App:変化に強い分散アプリケーションの原則
  • コンテナ:パッケージングと実行の標準

本書はこれらのうち「コンテナオーケストレーションのパターン」のみに絞って論じており、前提として内部設計の整備が必要であると明言しています。

分散プリミティブとJVMの対比

本書が面白いのは、KubernetesのプリミティブをJVMの世界と対比させている点です。

コンセプト JVM(ローカル) Kubernetes(分散)
動作のカプセル化 クラス コンテナイメージ
インスタンス オブジェクト コンテナ
再利用単位 .jar コンテナイメージ
構成 クラスの組み合わせ サイドカーパターン
デプロイ単位 .jar / .war Pod
定期タスク ScheduledExecutorService CronJob
バックグラウンドタスク デーモンスレッド DaemonSet
設定管理 System.getenv() ConfigMap / Secret

この対比を見るだけでも、Kubernetesが単なる「デプロイツール」ではなく、分散アプリケーションのランタイムプラットフォームであることがよくわかります。

Podとサービスの役割

  • Pod:コンテナグループのスケジューリング・デプロイメント・ランタイム分離の単位。ビルド時はコンテナイメージがマイクロサービスを表しますが、実行時はPodがその単位になります。
  • Service:Podの短命さ(スケールアップ・ダウン・再スケジュール)を吸収し、サービス名をIPとポートに永続的にバインドします。
  • ラベル:Podを論理的にグループ化し、ReplicaSetのセレクターやアフィニティルールの基盤となります。
  • Namespace:クラスターを論理的なリソースプールに分割し、ResourceQuotaと組み合わせてリソース消費を制限できます。

第2章 予測可能な需要

コンテナのリソースプロファイル(requestslimits)を適切に宣言することで、スケジューラが最適なノードを選べるようになります。QoSレベル(Guaranteed / Burstable / BestEffort)の考え方も解説されており、ノードのメモリ不足(OOMKill)への対処にも繋がります。

第3章 宣言的なデプロイメント

RollingUpdate・Recreate・Blue-Greenなどのデプロイ戦略を、Kubernetesの宣言的APIでどう表現するかを扱います。maxSurgemaxUnavailableの組み合わせによる細かな制御が可能です。


Part I:基礎パターン(続き)

第4章 ヘルスプローブ

アプリケーションの健全性をKubernetesに伝えるためのAPIです。

プロセスが生きていても、アプリケーションが機能していないケースは多くあります(デッドロック、OutOfMemoryErrorなど)。ヘルスプローブはこれを検出するための仕組みです。

4種類のプローブ

spec:
  containers:
  - name: app
    startupProbe:      # 起動完了を通知(起動に時間がかかるアプリ向け)
      exec:
        command: ["stat", "/var/run/ready"]
      failureThreshold: 15
      periodSeconds: 60
    livenessProbe:     # 生死確認。失敗するとコンテナを再起動
      httpGet:
        path: /actuator/health
        port: 8080
      initialDelaySeconds: 30
    readinessProbe:    # トラフィック受付可否を通知。失敗するとEndpointから除外
      exec:
        command: ["stat", "/var/run/random-generator-ready"]
プローブ 役割 失敗時のアクション
Startup 起動完了の通知 再起動
Liveness 生死確認 再起動
Readiness トラフィック受付可否 Endpointから除外

Readiness Gateの活用

外部ロードバランサーの準備完了もPodの準備完了条件に組み込めるreadinessGatesは、高度な制御が必要な場合に有効です。

第5章 管理されたライフサイクル

アプリケーションがKubernetesからのライフサイクルイベントにどう応答すべきかを定義します。

シグナルとフック

イベント 説明
SIGTERM シャットダウンの通知。この時点で速やかに終了処理を開始する
SIGKILL SIGTERMから(デフォルト)30秒後に強制終了
postStart コンテナ起動直後に非同期実行。ウォームアップや前提条件チェックに使う
preStop コンテナ終了前のブロッキング呼び出し。正常シャットダウン処理に使う
lifecycle:
  postStart:
    exec:
      command: ["sh", "-c", "sleep 30 && echo 'ready' > /tmp/postStart_done"]
  preStop:
    httpGet:
      path: /shutdown
      port: 8080

postStartは「少なくとも1回」のセマンティクスを持ちます。重複実行を考慮した実装が必要です。

Init ContainerとLifecycle Hookの使い分け

観点 Lifecycle Hook Init Container
粒度 コンテナレベル Podレベル
起動時アクション postStart(非同期) 順次・完了まで実行
シャットダウン preStop 対応なし
再利用性 コンテナと密結合 コンテナイメージとして再利用可

Part I:基礎パターン(続き)

第6章 自動配置

KubernetesスケジューラがどのようにノードにPodを割り当てるか、そしてそれをどう制御するかを解説します。

スケジューリングの制御手段(比較)

手段 用途 強度
nodeSelector ラベルによるシンプルなフィルタ Hard
Node Affinity 演算子を使った柔軟な条件指定 Hard / Soft
Pod Affinity 他のPodとの相対的な配置 Hard / Soft
Pod Anti-Affinity 他のPodとの分離 Hard / Soft
Topology Spread Constraints ゾーン/ノード間の均等分散 Hard / Soft
Taints & Tolerations ノード側からの制御(オプトイン) Hard / Soft / Evict
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: numberCores
            operator: Gt
            values: ["3"]
  topologySpreadConstraints:
  - maxSkew: 1
    topologyKey: topology.kubernetes.io/zone
    whenUnsatisfiable: DoNotSchedule
    labelSelector:
      matchLabels:
        app: bar

過度なスケジューリング制約はクラスターリソースの断片化を招きます。まずリソースプロファイルとラベルを適切に設定し、スケジューラに任せるところから始めるのが推奨です。


Part II:行動パターン

Podを「どのように実行するか」を管理するコントローラーの選び方を扱います。

パターン 使うコントローラー
バッチジョブ 第7章 Job(完了まで1回実行)
定期ジョブ 第8章 CronJob
デーモンサービス 第9章 DaemonSet(全ノードで1Pod)
シングルトンサービス 第10章 StatefulSet + Leader Election
ステートレスサービス 第11章 Deployment + ReplicaSet
ステートフルサービス 第12章 StatefulSet + PersistentVolume
サービス検出 第13章 Service / Headless Service
自己認識 第14章 Downward API

第14章の「自己認識」パターンでは、PodがDownward APIを通じて自身のIPアドレス、Namespace、リソース制限などのメタデータを取得できます。外部サービスレジストリへの登録や、ログへのコンテキスト付与に役立ちます。


Part III:構造パターン

第15章 初期化コンテナ

アプリケーションコンテナが起動する前に、前提条件を整えるために使います。データのダウンロード、設定ファイルの生成、依存サービスの待機など、順次・完了まで実行される保証があります。

第16章 サイドカー

メインコンテナと同じPod内でヘルパーコンテナを実行するパターンです。

Pod
├── Main Container(アプリケーション)
└── Sidecar Container(ログ収集・プロキシ・設定同期など)

責務を分離し、メインコンテナを変更せずに横断的な機能を追加できます。サービスメッシュ(Envoyなど)はこのパターンの典型例です。

第17章 アダプタ / 第18章 大使

  • アダプタ:外部から見るインターフェースを標準化します(例:独自フォーマットのメトリクスをPrometheus形式に変換するサイドカー)。
  • 大使:メインコンテナの代わりに外部サービスへのプロキシとして機能します(例:ローカルキャッシュ、サービスディスカバリの抽象化)。

Part IV:構成パターン

第20章 構成リソース(ConfigMap / Secret)

環境変数・ボリュームマウントを通じて、設定とコードを分離します。

第21章 不変の設定

バージョン付きConfigMapを作成し、変更時は新しいリソースとして作り直すアプローチです。ローリングアップデートと組み合わせることで、設定変更の追跡とロールバックが容易になります。

第22章 構成テンプレート

HelmやKustomizeを使って、テンプレートから環境ごとに異なるKubernetesマニフェストを生成するパターンです。

第23章 プロセスの包含

ビルドパイプラインや設定生成のロジックをコンテナ化し、Kubernetesのリソースとして定義します。


Part V:セキュリティパターン

第24章 ネットワークセグメンテーション

NetworkPolicyを用いて、Namespace間・Pod間の通信を制御します。デフォルトでは名前空間をまたいだ通信が許可されるため、明示的な制限が重要です。

第25章 セキュアな構成

Secretの適切な管理(外部シークレット管理システムとの統合、Sealed Secretsなど)と、Pod Security StandardsによるPodレベルのセキュリティ制約を扱います。

第26章 アクセス制御

RBAC(Role-Based Access Control)によるAPIアクセスの制限と、ServiceAccountを用いた最小権限の原則を解説します。


Part VI:高度なパターン

第27章 コントローラー

Kubernetesの制御ループ(Reconciliation Loop)の仕組みを理解し、カスタムコントローラーを実装する方法を扱います。「期待する状態」と「現在の状態」を継続的に比較し、差分を埋める設計思想がKubernetesの根幹です。

第28章 オペレーター

カスタムリソース(CRD)とカスタムコントローラーを組み合わせた「オペレーター」パターンです。ステートフルなアプリケーション(データベース、メッセージブローカーなど)の運用知識をコードとして表現します。

CRD(Custom Resource Definition)
    ↕
Custom Controller(Reconciliation Loop)
    ↕
Kubernetes API

第29章 弾性スケール

HPA(Horizontal Pod Autoscaler)・VPA(Vertical Pod Autoscaler)・KEDA(イベント駆動スケーリング)を組み合わせたスケーリング戦略を解説します。

第30章 イメージビルダー

KanikoやBuildahを用いた、Kubernetes内でのコンテナイメージビルドパターンです。CI/CDパイプラインとの統合に役立ちます。


本書から得られる設計の視点

「問題→解決」の思考フレーム

本書の各パターンは必ず「問題」セクションから始まります。「なぜこの機能が必要か」という問いへの答えを先に示すことで、機能の理解が深まります。Kubernetesの機能を「使い方」ではなく「なぜ使うか」から理解できる構成になっています。

コンテナ設計の原則

本書が繰り返し強調するコンテナ設計の原則をまとめると次のようになります。

良いコンテナの特性

  • 単一の問題に対処する機能の単位
  • 単一のチームが所有し、独自のリリースサイクルを持つ
  • 自己完結型(ランタイム依存関係を定義・保持する)
  • 不変(一度ビルドしたら変更しない、設定で制御する)
  • リソース要件と外部依存関係を宣言する
  • 明確に定義されたAPIで機能を公開する
  • 一時的(スケールアップ・ダウンをいつでも安全に行える)

クラウドネイティブのスタック全体像

本書が示す「クラウドネイティブへの道」は、Kubernetesを使いこなすだけでは不十分であることを示しています。クリーンコード → DDD → ヘキサゴナルアーキテクチャ → マイクロサービス → コンテナ設計 → Kubernetesパターン、というスタック全体を意識することで、初めてクラウドネイティブの恩恵を最大限に活かせます。


まとめ

「Kubernetes Patterns, 2nd Edition」は、Kubernetesの各機能をパターンとして体系化することで、設計上の意思決定に使える共通語彙を提供してくれます。

特に印象的だったのは次の3点です。

  1. 問題→解決の構成:機能の「なぜ」から入ることで、適材適所の判断ができるようになります
  2. JVMとの対比:分散プリミティブを既知の概念から理解できる導入が秀逸です
  3. パターン間の繋がり:サイドカー・アダプタ・大使の違い、Init ContainerとLifecycle Hookの使い分けなど、似た機能の選択基準が明確になります

Kubernetesの「動かし方」は学べても「設計の仕方」が曖昧に感じている方に、特に読んでほしい一冊です。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?