はじめに
本書『Kubernetes: Up and Running』は、Kubernetes 開発に携わった Kelsey Hightower・Brendan Burns・Joe Beda の三名によって執筆された、Kubernetes 入門から実践までを網羅した技術書です。
著者たちは冒頭でこう述べています。「Kubernetes は、プロセスを再起動するために午前3時に起きたすべてのシステム管理者に感謝する」と。この言葉に、本書の問題意識のすべてが詰まっています。分散システムの構築・デプロイ・保守を根本から簡素化することが、Kubernetes 誕生の動機です。
本記事では、章ごとの要点を整理しながら、エンジニアとしての視点でこの本の価値をお伝えします。
書籍概要
| 項目 | 内容 |
|---|---|
| タイトル | Kubernetes: Up and Running |
| 著者 | Kelsey Hightower, Brendan Burns, Joe Beda |
| 出版社 | O'Reilly Media |
| 対象読者 | サーバーベースのアプリケーション開発・運用に携わるエンジニア |
第1章: はじめに ― なぜ Kubernetes なのか
本章では、Kubernetes を採用する理由を「速度」「スケーリング」「インフラの抽象化」「効率」の4つの観点から整理しています。
速度
速度とは単なる開発スピードではなく、「高可用性を維持しながらどれだけ多くのものを届けられるか」で測られます。その実現を支えるのが、以下の3つの概念です。
- 不変性(Immutability):コンテナを直接変更するのではなく、新しいイメージをビルドして置き換える。変更の記録が残り、ロールバックが容易になります。
- 宣言的構成(Declarative Configuration):システムの「あるべき姿」を定義ファイルに記述し、Kubernetes がそれを実現します。命令型の手続きに比べ、ドリフトが生じにくく、コードレビューやバージョン管理と相性が良いです。
- 自己修復システム(Self-Healing):Kubernetes は望ましい状態を継続的に維持します。コンテナが落ちれば再起動し、レプリカが不足すれば補充します。オペレーターの夜間対応を減らす効果があります。
スケーリング
Kubernetes は、コンポーネント間を API とロードバランサで分離する「疎結合アーキテクチャ」を推奨します。各マイクロサービスを独立したチームが担当でき、6〜8人の「ピザ2枚チーム」規模で組織をスケールさせることが可能になります。
また、複数チームのリソース需要を1つのクラスターに集約することで、個別に最大値を見積もるよりも成長予測の精度が上がり、インフラコストの最適化にも寄与します。
インフラの抽象化
Kubernetes の API 上にアプリケーションを構築すると、コンテナイメージと宣言的な設定ファイルを新しいクラスターに送るだけで、環境間の移植が実現します。AWS・GCP・Azure といったクラウドプロバイダーへの依存を低減できる点は、大きなアドバンテージです。
第2章: コンテナの作成と実行
コンテナイメージの本質は「ルートファイルシステム以下のアプリケーションとその依存関係を1つのアーティファクトにまとめたもの」です。Docker イメージ形式は、レイヤーを積み重ねる構造になっており、いくつかの重要な設計上の注意点があります。
レイヤー設計のベストプラクティス
. (悪い例)
└── レイヤーA: ベースOS
└── レイヤーB: server.js を追加
└── レイヤーC: node パッケージをインストール
. (良い例)
└── レイヤーA: ベースOS
└── レイヤーB: node パッケージをインストール
└── レイヤーC: server.js を追加
変更頻度の低いレイヤーを下層に置くことで、差分ビルド・プッシュ・プルのコストを最小化できます。また、あるレイヤーで削除したファイルは前レイヤーに依然として存在することも覚えておく必要があります。シークレット情報は絶対にイメージに含めてはいけません。
リソース制限
Docker コンテナはメモリ・CPU の上限を設定できます。
$ docker run -d --name myapp \
--publish 8080:8080 \
--memory 200m \
--memory-swap 1G \
--cpu-shares 1024 \
myimage:1
第3〜4章: クラスターのデプロイと kubectl の基本
第3章ではローカルやクラウド上への Kubernetes クラスター構築方法が、第4章では kubectl のコア操作が説明されています。
kubectl は Kubernetes のメインコントロールツールです。よく使うコマンドパターンを把握しておくことで、クラスターとのやり取りが格段にスムーズになります。
# リソースの一覧
kubectl get pods
# 詳細情報の確認
kubectl describe pod <pod-name>
# マニフェストの適用
kubectl apply -f manifest.yaml
# ラベルでフィルタリング
kubectl get pods -l app=myapp,version=v2
第5章: Pod ― Kubernetes の最小デプロイ単位
Pod は、Kubernetes クラスターにおける「デプロイ可能な最小のアーティファクト」です。複数のコンテナを1つのアトミックなユニットとしてまとめ、同一ノードにスケジュールします。
Pod 設計の考え方
「このコンテナたちは、別々のマシンに置かれても正常に動作するだろうか?」という問いが、Pod 設計の出発点です。答えが「No」であれば同じ Pod にまとめる。「Yes」であれば別 Pod にするのが原則です。
たとえば、Web サーバーと Git 同期コンテナは、ローカルファイルシステムを共有する必要があるため、同一 Pod に置きます。一方、WordPress と MySQL は別 Pod にすべきです(スケーリング戦略が異なるため)。
ヘルスチェック
Kubernetes は3種類のヘルスチェックをサポートしています。
| 種別 | 用途 |
|---|---|
| Liveness Probe | アプリケーションが正常動作しているか判定。失敗するとコンテナを再起動 |
| Readiness Probe | リクエストを受け付けられる状態かを判定。失敗するとロードバランサーから除外 |
| exec / tcpSocket | カスタムスクリプトや非 HTTP サービス向けのプローブ |
livenessProbe:
httpGet:
path: /healthy
port: 8080
initialDelaySeconds: 5
timeoutSeconds: 1
periodSeconds: 10
failureThreshold: 3
リソース管理
Pod にはリソースの「リクエスト(最小保証)」と「リミット(上限)」を設定できます。
resources:
requests:
cpu: "500m"
memory: "128Mi"
limits:
cpu: "1000m"
memory: "256Mi"
リクエストはスケジューリングの根拠となり、リミットはカーネルレベルで強制されます。メモリ制限を超えたコンテナは OOM Kill されて再起動されることを念頭に置きましょう。
第6章: ラベルとアノテーション
ラベルはリソースを識別・グループ化するためのキーバリューペアです。セレクターと組み合わせることで、デプロイ対象の Pod を柔軟に絞り込めます。
アノテーションは識別には使われず、ツールやライブラリが利用するメタデータを保持します。デプロイの変更理由(kubernetes.io/change-cause)などを記録するのに適しています。
第7章: サービス検出
Kubernetes の Service オブジェクトは、Pod 群への安定したエンドポイントを提供します。Pod は動的に生成・削除されるため、IP アドレスは常に変化しますが、Service を介することで常に同じ名前でアクセスできます。
Kubernetes DNS によってサービス名が自動的に解決されます。
<service-name>.<namespace>.svc.cluster.local
第8章: ReplicaSet ― 自己修復の基盤
ReplicaSet は「常に指定した数の Pod が実行されている状態を維持する」コントローラです。「クッキーカッター(Pod テンプレート)と必要なクッキーの数(レプリカ数)を1つの API オブジェクトにまとめたもの」という表現がわかりやすいです。
調整ループ
望ましい状態: kuard が3台動いている
現在の状態: kuard が2台しかない
→ ReplicaSet コントローラが新しい Pod を1台作成する
この「調整ループ(Reconciliation Loop)」は Kubernetes 設計の根幹です。宣言的に状態を記述すれば、あとはコントローラが現実をその状態に収束させます。
スケーリング
# 命令的スケーリング(緊急時のみ)
kubectl scale replicaset kuard --replicas=4
# 宣言的スケーリング(推奨)
# kuard-rs.yaml の spec.replicas を変更してから apply
kubectl apply -f kuard-rs.yaml
命令的スケーリングは緊急時に便利ですが、後から YAML ファイルと乖離することを忘れないよう注意が必要です。
HPA(水平 Pod 自動スケーリング)
CPU 使用率に基づいた自動スケーリングも設定できます。
kubectl autoscale rs kuard --min=2 --max=5 --cpu-percent=80
第9章: DaemonSet
DaemonSet は「クラスター内のすべてのノード(または特定のノード)に1つずつ Pod を配置する」ためのオブジェクトです。ログ収集(fluentd)やノード監視エージェントなど、インフラ横断的なツールのデプロイに使われます。
第10章: Job
Job は「バッチ処理など、完了を目的とする一時的なタスク」のためのオブジェクトです。Web サーバーのように常駐するのではなく、処理が終わったら Pod が終了することを前提としています。
第11章: ConfigMap と Secret
アプリケーションの設定値を管理する仕組みです。
| リソース | 用途 |
|---|---|
| ConfigMap | 一般的な設定情報(テキスト、設定ファイルなど) |
| Secret | パスワードや API キーなどの機密情報(Base64 エンコード) |
コンテナイメージに設定を埋め込まず、これらのリソースから注入することで、環境ごとに異なる設定を安全に管理できます。
第12章: Deployment ― ロールアウト管理の中心
Deployment は、ReplicaSet の上位に位置するオブジェクトで、アプリケーションの新バージョンのロールアウトを安全に管理します。
2つのデプロイ戦略
**Recreate(再作成)**は既存の Pod をすべて落としてから新しい Pod を起動する方法です。シンプルですが、ダウンタイムが発生するためテスト環境向きです。
**RollingUpdate(推奨)**は少数の Pod を段階的に入れ替える方法です。ユーザーへの影響を最小限に抑えながら新バージョンをデプロイできます。
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1 # 同時に停止できる Pod 数
maxSurge: 1 # 追加で起動できる Pod 数
maxUnavailable はロールアウト速度と可用性のトレードオフを制御します。maxSurge は追加リソースを一時的に消費してでも可用性を 100% 維持したい場合に使用します。
ロールバック
# 直前のバージョンに戻す
kubectl rollout undo deployment nginx
# 特定のリビジョンに戻す
kubectl rollout undo deployment nginx --to-revision=2
# ロールアウト履歴の確認
kubectl rollout history deployment nginx
バージョン間互換性の重要性
ローリングアップデート中は新旧2バージョンが同時に稼働します。そのため、前方互換性・後方互換性を意識した API 設計が必要です。これは Kubernetes 固有の話ではなく、ダウンタイムなしのデプロイをするなら避けて通れない設計原則です。
第13章: ストレージと Kubernetes の統合
Kubernetes は PersistentVolume と PersistentVolumeClaim を通じて、Pod とストレージ実装を分離します。NFS・iSCSI・クラウドプロバイダーのブロックストレージなど幅広く対応しており、Pod が別ノードに移動しても同じデータにアクセスできます。
第14章: 実際のアプリケーションのデプロイ
本章では、これまで学んだ Pod・ReplicaSet・Service・Deployment・ConfigMap・PersistentVolume を組み合わせて、実際のアプリケーション(MongoDB を含む)をデプロイする例が示されています。各コンセプトが単独ではなく、連携して機能することを実感できます。
全体を通じた所感
本書の強みは、「なぜそう設計されているのか」という背景を丁寧に説明している点です。
たとえば「宣言的構成が優れている理由」「不変インフラがロールバックを容易にする理由」「ReplicaSet と Pod が疎結合である理由」など、設計思想の説明が随所に挟まれており、単なる操作マニュアルではなくアーキテクチャ視点でKubernetesを理解できます。
また、本書全体を通じて「調整ループ」というパターンが Kubernetes の設計に一貫して貫かれていることに気づきます。Pod・ReplicaSet・Deployment・HPA、それぞれが「望ましい状態」と「現在の状態」を比較し続けるシンプルなループで動いています。このパターンを理解すると、知らないリソースに出会っても「どういう調整ループを持っているか」という問いから入れるようになります。
気になった点
- 本書は初版(2017年)のため、現在の Kubernetes の最新機能(例:StatefulSet の深掘り、Operator パターン、CNI 周辺)には対応していません。基礎固めとして読んだ後、公式ドキュメントや追加書籍で補完することを推奨します。
- YAML マニフェストのサンプルが多く、手を動かしながら読むとより理解が深まります。
こんな方にお勧め
- Kubernetes を初めて学ぶエンジニア
- Docker は使っているが、オーケストレーションの全体像を掴みたい方
- コンテナ基盤の設計・運用に携わる SRE・インフラエンジニア
- マイクロサービスアーキテクチャの土台を理解したい開発者
まとめ
本書は、Kubernetes の主要コンセプト(Pod・ReplicaSet・Deployment・Service・ConfigMap・PersistentVolume)を体系的に学べる良書です。コマンドの羅列ではなく、設計思想と実践がバランスよく盛り込まれており、読後は「なぜ Kubernetes がこのように動くのか」を自分の言葉で説明できるようになります。
Kubernetes の学習を始めるにあたって、まず手に取る一冊として自信を持っておすすめできます。