- 物理機リージョン/AZ
- ハイパーバイザVM exit で捕まえる
- VMゲストOS
- コンテナnamespace / cgroup今ここ
- プロセスアプリ / DB
この期は、宣言と世界を誰がいつ比べるかを見ています。今回は、比べる者が「どれが自分の持ち物か」をどう決めているかを見ます。
まず結論
ReplicaSet が「自分の Pod」を数えるのも、Service が送り先を決めるのも、名前や作った履歴ではなく、その時点でセレクタに合うラベルを持つ Pod への問い合わせです。
数える者と送る者は別々のセレクタで問い合わせます。だから同じ app=web の Pod が、数には入らないのに送り先には入ることがあります。
replicas: 2 の ReplicaSet(セレクタ app=web)が動いている横に、同じ app=web のラベルを付けた Pod を手で1つ作りました。数秒後に何が起きていたでしょうか。
当てることが目的ではありません。外した予測ほど記憶に残るので、直感で選んでください。
「自分の Pod」は、名前でも履歴でもなく問い合わせで決まる
用語を1文ずつ言い直します。Pod はコンテナを動かす最小の単位、ReplicaSet(RS)は Pod の数を保つオブジェクトとそのコントローラ、Deployment は RS を作って入れ替える上位の宣言です。
RS の宣言は3つの欄でできています。
A ReplicaSet is defined with fields, including a selector that specifies how to identify Pods it can acquire, a number of replicas indicating how many Pods it should be maintaining, and a pod template specifying the data of new Pods it should create to meet the number of replicas criteria.
数を保つためにテンプレートから Pod を作りますが、数える対象はテンプレートで作ったものに限りません。 数えるのはセレクタで、セレクタが見るのはラベルです。
Unlike names and UIDs, labels do not provide uniqueness. In general, we expect many objects to carry the same label(s). Via a label selector, the client/user can identify a set of objects. The label selector is the core grouping primitive in Kubernetes.
ラベルは一意ではありません。だから「この Pod は誰のものか」は、その時点でラベルがセレクタに合うかという問い合わせの答えになります。公式文書は Pod を relatively ephemeral, disposable entities と書きます。Pod が作り直されて名前が変わっても、ラベルが合えば同じ集合に入ります。
- ・取り込まれた Pod の ownerReferences に RS の情報が入る。これは結果であって条件ではない
素の ReplicaSet の横に、同じラベルの Pod を置く
k3s v1.37.0(rancher/k3s:v1.37.0-k3s1)で、replicas: 2・セレクタ app=web の RS を作り、Pod が Ready になってから、同じ app=web を付けた stray という Pod を手で作りました。
pod/stray createdNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELSweb-f9qzq 1/1 Running 0 11s 10.42.0.8 a8a2e58ff591 <none> <none> app=webweb-vdhjh 1/1 Running 0 11s 10.42.0.7 a8a2e58ff591 <none> <none> app=webNAME DESIRED CURRENT READY AGEweb 2 2 2 12sTIME REASON MSG2026-09-27T22:46:29Z SuccessfulCreate Created pod: web-vdhjh2026-09-27T22:46:29Z SuccessfulCreate Created pod: web-f9qzq2026-09-27T22:46:32Z SuccessfulDelete Deleted pod: strayError from server (NotFound): pods "stray" not found
RS のイベントに Deleted pod: stray があります。RS は stray を取り込み、3つと数え、1つを消しました。条件は文書どおりです。
If there is a Pod that has no OwnerReference or the OwnerReference is not a Controller and it matches a ReplicaSet's selector, it will be immediately acquired by said ReplicaSet.
同じ文書は Non-Template Pod acquisitions の節で、素の Pod に RS のセレクタと合うラベルを付けないよう strongly recommended と書いています。
ReplicaSet が既存の Pod を取り込む条件として、公式文書に沿うのはどれですか。
数える者と送る者は、別々に問い合わせる
問い合わせるのは RS だけではありません。Service も同じ形です。
The controller for that Service continuously scans for Pods that match its selector, and then makes any necessary updates to the set of EndpointSlices for the Service.
RS と Service のコントローラは、それぞれ自分のセレクタで問い合わせます。同じラベルを見ていても、セレクタが違えば答えの集合は違います。 Deployment の下ではこの差がはっきり出ます。Deployment は子の RS に pod-template-hash を足します。
It is generated by hashing the PodTemplate of the ReplicaSet and using the resulting hash as the label value that is added to the ReplicaSet selector, Pod template labels, and in any existing Pods that the ReplicaSet might have.
Service の名前は DNS で cluster IP に引かれます(This resolves to the cluster IP of the Service.)。名前は変わらず、その裏の集合がラベルへの問い合わせで入れ替わります。
Terraform では、同一性は問い合わせでは決まりません。Terraform identifies instances by the map key or set member using the value provided to for_each. とあり、アドレスは azurerm_resource_group.rg["a_group"] のようにキーを含みます。構成に書いたキーが「どれか」を決めます。ただし、ラベルをキーと同じものと見るのは誤りです。キーは1つのインスタンスを指しますが、ラベルは一意ではありません。
Deployment の下では、数えられないのに送り先には入る
同じ k3s で、replicas: 2 の Deployment と、セレクタ app=web の Service を作り、同じ stray を置きました(2回実行し同じ結果。2回目を掲載)。
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTORweb-6bff7579cf 2 2 2 3s c busybox:1.36 app=web,pod-template-hash=6bff7579cfpod/stray createdpod/stray condition metNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELSstray 1/1 Running 0 6s 10.42.0.21 a8a2e58ff591 <none> <none> app=webweb-6bff7579cf-76zfp 1/1 Running 0 9s 10.42.0.20 a8a2e58ff591 <none> <none> app=web,pod-template-hash=6bff7579cfweb-6bff7579cf-cjlfj 1/1 Running 0 9s 10.42.0.19 a8a2e58ff591 <none> <none> app=web,pod-template-hash=6bff7579cfNAME DESIRED CURRENT READY AGEweb-6bff7579cf 2 2 2 9sNAME READY UP-TO-DATE AVAILABLE AGEweb 2/2 2 2 9sNAME ADDRESSTYPE PORTS ENDPOINTS AGEweb-xrnvg IPv4 8080 10.42.0.20,10.42.0.19,10.42.0.21 9s10.42.0.20 web-6bff7579cf-76zfp ready=true10.42.0.19 web-6bff7579cf-cjlfj ready=true10.42.0.21 stray ready=trueownerReferences=
RS のセレクタは app=web,pod-template-hash=6bff7579cf です。stray のラベルは app=web だけなので合わず、RS は2のまま、stray は消されずに Running で残りました。最終行のとおり stray の ownerReferences は空です。
一方、EndpointSlice には3件目として stray の IP 10.42.0.21 が ready=true で入っています。数える者の答えは2件、送る者の答えは3件です。
確かめていないこともあります。stray は sleep だけで待ち受けていないので、Service 経由の通信が実際に stray に届くかは測っていません。言えるのは「送り先の一覧に載った」までです。また、Deployment 文書は他のコントローラとセレクタを重ねないよう Kubernetes doesn't stop you from overlapping, and if multiple controllers have overlapping selectors those controllers might conflict and behave unexpectedly. と警告しています。「Deployment なら安全」ではありません。
Deployment の下では、手で作った app=web の Pod が RS に数えられず、EndpointSlice には入りました。理由として実演に合うのはどれですか。
数える者(Deployment 配下の ReplicaSet)
セレクタに pod-template-hash が足されている。app=web だけの stray は合わないので数に入らず、消されもしない。ownerReferences も空のまま。
NAME DESIRED CURRENT READY SELECTORweb-6bff7579cf 2 2 2 app=web,pod-template-hash=6bff7579cf
送る者(Service の EndpointSlice)
セレクタは app=web だけ。stray は合うので、送り先の一覧に3件目として ready=true で入る。誰の数にも入っていない Pod が、送り先には入っている。
10.42.0.20 web-6bff7579cf-76zfp ready=true10.42.0.19 web-6bff7579cf-cjlfj ready=true10.42.0.21 stray ready=true
同じ stray が、一方では数えられず、他方では送り先に入りました。何が違ったのでしょうか。
stray の側は何も変わっていません。問い合わせた側が、何を条件にしていたかを並べてください。
この章のまとめ
- RS が数えるのも Service が送るのも、その時点でセレクタに合うラベルを持つ Pod への問い合わせ。名前や作った者は問わない。
- 素の RS は、同じラベルで Controller の所有者が無い Pod を
immediately acquiredし、超過分を消す。 - どれが消えるかは scale down の順序で決まる。実演で stray が消えたのは観測で、一般則ではない。
- Deployment 配下の RS はセレクタに
pod-template-hashを持つので、app=web だけの Pod を数えない。だが Service の EndpointSlice には入る。 - ownerReferences は取り込んだ結果で、取り込む条件ではない。
- Terraform の for_each はキーで同一性を決める。ラベルは一意ではなく、キーと同じものではない。
自分の現場で確かめる
読んだだけでは身につきません。手元の環境で実際に見てみてください。
理解度チェック
読んだ直後は「分かった」と感じやすいものです。実際に解いて確かめてください。
素の ReplicaSet の実演で、2回とも手で作った Pod が削除されました。ここから言えることとして適切なのはどれですか。
用語集(4語)
- ラベルとセレクタ
- ラベルはオブジェクトに付けるキーと値の組で、一意ではない。セレクタはラベルの条件で集合を問い合わせる式。公式文書は `the core grouping primitive` と呼ぶ。
- ownerReferences
- Pod の持ち主を記録する欄。ReplicaSet が取り込んだ Pod には RS の情報が入る。取り込む条件ではなく結果。
- pod-template-hash
- Deployment のコントローラが、作ったり引き取ったりした ReplicaSet のセレクタ・Pod テンプレートのラベル・既存の Pod に足すラベル。子の RS 同士が重ならないようにする。公式は `Do not change this label.`
- EndpointSlice
- Service の送り先の IP を記録するオブジェクト。Service のコントローラがセレクタに合う Pod を走査して更新する。各エンドポイントに serving・terminating・ready の状態を持つ。
出典(一次ソース)
- Kubernetes Documentation — ReplicaSet (Last modified May 13, 2026) ↗
- Kubernetes Documentation — Deployments (Last modified July 07, 2026) ↗
- Kubernetes Documentation — Service (Last modified July 07, 2026) ↗
- Kubernetes Documentation — EndpointSlices (Last modified June 22, 2025) ↗
- Kubernetes Documentation — Pods (Last modified July 18, 2026) ↗
- Kubernetes Documentation — Labels and Selectors (Last modified March 15, 2026) ↗
- Kubernetes Documentation — DNS for Services and Pods (Last modified July 29, 2025) ↗
- Terraform — for_each meta-argument reference (2026-09-28 取得) ↗