🎓 レベル:標準 | 重要度:A(必須)
📎 前提:Docker Composeで複数コンテナ | 関連:Pod・Deployment・ReplicaSet・IaCとは・宣言的構成
要点(BLUF)
- K8s の本質は 宣言的+調整ループ。「望ましい状態(desired state)」をYAMLで宣言すると、コントローラが現実(current state)を絶えず比較し、ズレを自動で埋め続ける。
- だから「3レプリカ」と書けば、1つ落ちても自動で3に戻る。命令(how)でなく**目標(what)**を書くのがK8s流。
- 構成は**コントロールプレーン(頭脳)とワーカーノード(実行)**の2層。状態の真実は etcd に集約される。
概念 ── 命令でなく「望ましい状態」を宣言する
従来の運用は手続き的でした——「サーバにSSHして、起動して、落ちたら再起動して…」。K8s は逆です。最終的にどうあってほしいかだけを宣言し、そこへ寄せる仕事はK8sに任せます。
flowchart LR
desired["望ましい状態(YAML:3レプリカで動かす)"] --> ctrl["コントローラ"]
current["現実の状態(今2つしか動いていない)"] --> ctrl
ctrl -->|"差分を検知して1つ追加"| act["アクション実行"]
act --> current
ctrl -->|"一致するまで繰り返す"| ctrl
この「宣言された目標と現実を比べ、差を埋め続ける」反復が調整ループ(reconciliation loop)。サーモスタットに似ています——「室温22度」を宣言すれば、寒ければ暖め、暑ければ冷やし、目標に保ち続ける。systemd の Restart=always(プロセスとサービス管理(systemd))を、クラスタ全体に拡張したものと捉えると腑に落ちます。
仕組み ── コントロールプレーンとノード
クラスタは2種類のマシン群でできています。
flowchart TB
subgraph cp["コントロールプレーン(頭脳)"]
api["API Server(唯一の入口・全操作はここ経由)"]
etcd["etcd(全状態の真実を保存)"]
sched["Scheduler(Podを置くノードを決める)"]
cm["Controller Manager(調整ループ群)"]
end
subgraph nodes["ワーカーノード(実行)"]
kubelet1["kubelet(ノード上のPodを世話する)"]
kubelet2["kubelet"]
end
api --- etcd
api --- sched
api --- cm
api -->|"指示"| kubelet1
api -->|"指示"| kubelet2
| 部品 | 役割 |
|---|---|
| API Server | 唯一の窓口。kubectl も他部品も全部ここ経由 |
| etcd | 望ましい状態・現実の状態を保存する分散キーバリュー |
| Scheduler | 新しいPodをどのノードに置くか決める |
| Controller Manager | Deployment等の調整ループを回す |
| kubelet | 各ノードで、割り当てられたPodを起動・監視 |
kubectl apply すると、(1) YAMLが API Server に届き、(2) etcd に「望ましい状態」が記録され、(3) コントローラが差分を検知し、(4) Scheduler がノードを選び、(5) kubelet がコンテナを起動——という流れ。etcd の背後にある分散合意(一貫性をどう保つか)の理論は 分散システム へ。
動く例 ── 宣言して、状態を見る
# YAML(望ましい状態)を適用する。create でなく apply で「この状態にして」と宣言
kubectl apply -f deployment.yaml
# 現実の状態を見る
kubectl get pods
# 1つ消してみる → 調整ループが自動で作り直す
kubectl delete pod <pod名>
kubectl get pods # 数秒後、また望ましい数に戻っている
kubectl delete pod で消しても勝手に復活するのが調整ループの体感ポイント。「直す」のでなく「宣言に戻す」。
なぜ宣言的なのか
- 自己修復のため:望ましい状態を常に保持しているので、ズレ(故障・誤削除)を自動で正せる。手順書を実行する運用と違い、現実が目標に追従し続ける。
- 再現性・レビュー性のため:状態がYAML(コード)なので git で管理・レビューでき、同じ宣言から同じクラスタが起こせる(IaCとは・宣言的構成 と同じ思想・GitOps=GitOpsと自動化 の前提)。
- スケールのため:人間が個々のコンテナを世話するのは数十が限界。目標だけ宣言すれば、数千コンテナでも調整ループが面倒をみる。
⚠️ よくある誤解・落とし穴
- 「
kubectlで手作業すれば速い」→ 手で消したPodも調整ループが復活させる。YAMLを直さず手で変えても元に戻る。変更は宣言(YAML)を直すのが筋。 - 「K8s があれば何でも自動」→ 自動なのは「宣言した状態への収束」だけ。何を宣言するか(設計)は人間の仕事。
- 「小さなアプリにも常にK8s」→ 調整ループ・運用の複雑さは重い。単一コンテナ・少数サービスなら Compose やマネージドで十分なことも多い。
- 「etcd は気にしなくていい」→ etcd はクラスタの真実の源。ここが壊れる/バックアップがないとクラスタを失う。
- 「コントロールプレーンが落ちても平気」→ 既存Podは動き続けるが、変更・自己修復が止まる。本番はコントロールプレーンも冗長化(マネージドK8sが面倒をみる・要最新確認)。
対応ラボ
cloud-infra-study/labs/04-02_deployment.yaml(次トピックと共通。kubectl apply → Pod削除 → 自動復活、で調整ループを観察。kind/minikube 等のローカルクラスタで)。
関連
- 宣言される最小ワークロードは Pod・Deployment・ReplicaSet
- 単位であるコンテナは コンテナとは(名前空間・cgroups)
- 同じ宣言的思想のインフラ版は IaCとは・宣言的構成
- 宣言をgit起点で自動適用するのは GitOpsと自動化