- 物理機リージョン/AZ
- ハイパーバイザVM exit で捕まえる
- VMゲストOS今ここ
- コンテナnamespace / cgroup今ここ
- プロセスアプリ / DB
第8期でコンテナと VM の仕組みを見ました。この期は、それらを「望む状態を書いて」動かす道具が、いつ・誰が世界と比べているのかを見ます。
まず結論
宣言は望む状態の記録にすぎません。世界がそれに近づくのは、誰かが世界と比べて差を埋めたときだけです。
Kubernetes ではコントローラがその比較を止まらずに繰り返し、Terraform は plan や apply を呼ばれたときにだけ比べます。手で消したものが戻るかどうかは、ここで分かれます。
Kubernetes で「Pod を2つ保つ」と宣言し、そのうち1つを手で消しました。Terraform では宣言して作ったファイルを手で消しました。5秒後、それぞれどうなっているでしょうか。
当てることが目的ではありません。外した予測ほど記憶に残るので、直感で選んでください。
宣言は記録で、近づけるのは比べる者
「望む状態を書けば、あとは道具がそうしてくれる」。半分だけ正しい言い方です。書いた時点で起きるのは記録だけで、世界を動かすのは、記録と世界を比べて差を埋める誰かです。
Kubernetes の公式文書は、この「誰か」をサーモスタットで説明します。
When you set the temperature, that's telling the thermostat about your desired state. The actual room temperature is the current state. The thermostat acts to bring the current state closer to the desired state, by turning equipment on or off.
設定温度が望む状態、室温が現在の状態です。そして In Kubernetes, controllers are control loops that watch the state of your cluster, then make or request changes where needed. と続きます。コントローラとは、望む状態と現在の状態を比べて差を埋めようとし続ける制御ループのことです。
この期で繰り返し出てくる資源を先に定義します。
- Pod:
Pods are the smallest deployable units of computing that you can create and manage in Kubernetes.1つ以上のコンテナの組です。 - ReplicaSet:
A ReplicaSet's purpose is to maintain a stable set of replica Pods running at any given time.同じ Pod を指定した数だけ保ちます。 - Deployment:
A Deployment provides declarative updates for Pods and ReplicaSets.公式は、通常は Deployment を定義して ReplicaSet を自動で管理させる、と書きます。
どれも望む状態の記録です。Pod はノードの kubelet が、ReplicaSet・Deployment はそれぞれのコントローラが差を埋めます。
- ・比べるのは「今の数」。途中の変化を見逃しても、次に比べれば追いつく
- ・公式は、クラスタが安定状態に達しないこともありうると書く
比べる材料は変化の出来事ではなく今の状態です。API 規約はこれを the system's behavior is level-based rather than edge-based と呼び、値が 2→5→3 と書き換えられても 5 を経る必要はないと例示します。理由は This enables robust behavior in the presence of missed intermediate state changes. です。
ReplicaSet の Pod を1つ消す
k3s v1.37.0(rancher/k3s:v1.37.0-k3s1)の上で、busybox の Pod を2つ保つ ReplicaSet web を作り、1つを消しました。出力は実行ログのままです。
$ kubectl get pods -l app=web # 22:49:19NAME READY STATUS RESTARTS AGEweb-spmlj 1/1 Running 0 4sweb-zbd7n 1/1 Running 0 4s$ kubectl delete pod web-spmlj --wait=false # 22:49:19pod "web-spmlj" deleted from default namespace$ kubectl get pods -l app=web # +1s 22:49:20NAME READY STATUS RESTARTS AGEweb-dqkj4 1/1 Running 0 1sweb-spmlj 1/1 Terminating 0 5sweb-zbd7n 1/1 Running 0 5s$ kubectl get pods -l app=web # +41s 22:50:00NAME READY STATUS RESTARTS AGEweb-dqkj4 1/1 Running 0 41sweb-zbd7n 1/1 Running 0 45s$ kubectl get events --field-selector involvedObject.kind=ReplicaSet,involvedObject.name=web --sort-by=.lastTimestamp | tail -346s Normal SuccessfulCreate replicaset/web Created pod: web-spmlj46s Normal SuccessfulCreate replicaset/web Created pod: web-zbd7n42s Normal SuccessfulCreate replicaset/web Created pod: web-dqkj4
見るべきは3点です。消した web-spmlj は戻らず、別名の web-dqkj4 ができました。消した Pod がまだ Terminating のうちに新しい Pod が Running です。イベントでは、作ったのが replicaset/web だと分かります。同じ手順を3回流し、3回とも別名の Pod ができました。Pod 名と秒数はこの環境の値です。
削除が比べ直す契機になるのは事実です。controllers.md も、ReplicaSet コントローラは Pod の削除に反応して関係する ReplicaSet を処理待ちに積む、と書きます。それでも、何を作るかを決めるのは「今2つ無い」という数です。同じ文書の指針は Level driven, not edge driven. でした。
ReplicaSet コントローラが新しい Pod を作った判断の根拠として、公式の設計指針に沿うのはどれですか。
Terraform は、呼ばれたときに比べる
Terraform も望む状態を書く道具ですが、比べる時点が違います。plan の文書は、plan を作るときの既定の動作をこう書きます。
By default, Terraform performs the following operations when it creates a plan: Reads the current state of any already-existing remote objects to make sure that the Terraform state is up-to-date. Compares the current configuration to the prior state and noting any differences.
state の文書にも Prior to any operation, Terraform does a refresh to update the state with the real infrastructure. とあります。つまり比べるのは plan や apply を始めたときです。操作と操作の間に見張っているかどうかを文書は直接書いていませんが、次の実演で、見張っていないことは確かめられます。
ここで両向きの誤りを避けます。「Terraform も常に見張っている」は誤りです。逆に「Terraform は差分を見ない」も誤りで、呼ばれれば実物を読み直して比べます。Kubernetes 側も、「宣言すれば必ず落ち着く」とは公式が書いていません。potentially, your cluster never reaches a stable state と認めたうえで、コントローラが動いていれば安定しなくても構わない、という立場です。
作ったファイルを消して、5秒待つ
Terraform 1.16.4、provider hashicorp/local v2.9.1 で local_file を1つ作り、手で消しました。plan の表示は一部の行を、最後の apply の後の確認出力は省いています。ほかに一部のコマンドを省略しています。ls exit=0 は記録用に出した行で、ls 自体は何も表示していません。
$ terraform apply -auto-approvelocal_file.greeting: Creating...local_file.greeting: Creation complete after 0s [id=f572d396fae9206628714fb2ce00f72e94f2258f]Apply complete! Resources: 1 added, 0 changed, 0 destroyed.$ rm out/hello.txt; sleep 5; ls out/ # 22:53:17ls exit=0$ grep -c local_file terraform.tfstate # state still records it1$ terraform plan -no-color # 22:53:22local_file.greeting: Refreshing state... [id=f572d396fae9206628714fb2ce00f72e94f2258f]# local_file.greeting will be createdPlan: 1 to add, 0 to change, 0 to destroy.$ ls out/ # still nothing after planls exit=0$ terraform apply -auto-approvelocal_file.greeting: Creating...local_file.greeting: Creation complete after 0s [id=f572d396fae9206628714fb2ce00f72e94f2258f]Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
5秒待ってもファイルは戻らず、state には記録が残ったままです。plan を呼ぶと Refreshing state... で実物を読み、消失に気づいて will be created と出します。それでも plan の後にファイルはありません。文書のとおり The plan command alone does not actually carry out the proposed changes です。戻ったのは apply を呼んだときでした。2回流して同じ出力でした。
ファイルを消したあとに terraform plan を実行しました。実演で起きたことはどれですか。
Kubernetes の ReplicaSet
Pod を消すと、誰も何も呼ばないのに1秒後には別名の Pod が動いていました。比べ続けるコントローラが、今の数が足りないことを見て作り直したからです。
記録 ReplicaSet の replicas: 2比べる者 ReplicaSet コントローラ比べる時点 止まらずに繰り返す消した後 別名の Pod が作られた
Terraform の local_file
ファイルを消しても5秒間何も起きず、plan で差に気づき、apply で戻りました。比べるのは操作を呼ばれたときだけだからです。
記録 main.tf と state比べる者 terraform plan / apply比べる時点 呼ばれたとき消した後 apply を呼ぶまで無いまま
どちらも「宣言的」と呼ばれます。手で消したものが戻るかどうかを分けたのは何でしょうか。
記録の書き方ではなく、記録と世界を比べる者がいつ動いているかを比べてください。
この章のまとめ
- 宣言は望む状態の記録。世界を近づけるのは、記録と世界を比べて差を埋める者。
- Kubernetes のコントローラは比べ続ける制御ループ。Pod・ReplicaSet・Deployment は望む状態の記録で、コントローラが差を埋める。
- 比べる材料は今の状態(level-based)。消した Pod は戻らず、別名の Pod が作られた。
- Terraform は plan や apply の開始時に実物を読み直して比べる。消したファイルは5秒待っても戻らず、plan でも戻らず、apply で戻った。
- 「宣言すれば必ず落ち着く」も「Terraform も常に見張っている」も「Terraform は差分を見ない」も誤り。
自分の現場で確かめる
読んだだけでは身につきません。手元の環境で実際に見てみてください。
理解度チェック
読んだ直後は「分かった」と感じやすいものです。実際に解いて確かめてください。
Kubernetes の API 規約は、ある値が 2→5→3 と続けて書き換えられた場合について何と書いていますか。
用語集(5語)
- Pod
- Kubernetes で作って管理できる最小の実行単位(`the smallest deployable units of computing`)。1つ以上のコンテナをまとめたもの。
- ReplicaSet
- 指定した数の同じ Pod を保つための資源。公式は、通常は Deployment を定義して ReplicaSet を自動で管理させると書く。
- Deployment
- Pod と ReplicaSet の宣言的な更新を担う資源。望む状態を書くと、Deployment コントローラが実際の状態を変えていく。
- コントローラ
- クラスタの状態を見て、望む状態に近づくよう必要な変更を行ったり頼んだりする制御ループ。多くは API サーバに依頼して変更する。
- level-based / edge-based
- 今の状態(水準)で判断するか、変化の出来事で判断するか。Kubernetes の API 規約は前者だと書く。
出典(一次ソース)
- Kubernetes — Controllers (Last modified September 01, 2024) ↗
- Kubernetes — Pods (Last modified July 18, 2026) ↗
- Kubernetes — ReplicaSet (Last modified May 13, 2026) ↗
- Kubernetes — Deployments (Last modified July 07, 2026) ↗
- kubernetes/community — API Conventions(最終コミット 2026-07-14) ↗
- kubernetes/community — Writing Controllers(最終コミット 2026-05-08) ↗
- Terraform — Command: plan(2026-09-28 取得) ↗
- Terraform — State(2026-09-28 取得) ↗