対象
異常なめんどくさがりの人
疑問
kubernetesのDeployment
代表的な記述例がここ
https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
にあるこちらですが
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.15.4
ports:
- containerPort: 80
なんか app: nginx
多くないですか?
と思ったので少し調べました。
それぞれの役割
まずはそれぞれにどういう意味があるのかを確認します。
これはわかりやすく書いてある記事があるのでそちらを読みましょう。
https://44smkn.hatenadiary.com/entry/2018/07/30/235030
https://medium.com/@zwhitchcox/matchlabels-labels-and-selectors-explained-in-detail-for-beginners-d421bdd05362
.metadata.labels
と .spec.template.metadata.labels
については問題ないですね。
(余談ですが.metadata.labels
は必須のフィールドでないので特に必要なければ設定しなくてもよいみたいです)
少し引っかかるのが.spec.selector.matchLabels
基本的に.spec.template.metadata.labels
と同じものを書くものみたいです。
というか両者が一致しないとエラーになってapplyできません。(厳密に言うと.spec.selector.matchLabels
が.spec.template.metadata.labels
に含まれていればapplyは通る)
省略もできません、必須のフィールドです。
必要なのは先程の記事を読めばわかるのですが、
なぜ同じことを2回書かなくてはいけないのか!内部でよしなにやってくれ!
と思ったので続いてその理由も調べました。
両方書かせる理由
(個人的には納得できた)答えがありました
https://stackoverflow.com/questions/50309057/what-is-the-purpose-of-a-kubernetes-deployment-pod-selector
要約すると
-
apps/v1beta1
まではspec.selector.matchLabels
の指定がない場合spec.template.metadata.labels
と同じものを展開してくれていた(実際にapps/v1beta1
でdeployすると確認できます) -
kubectl apply
を使った時に設定はmetadata.annotations.kubectl.kubernetes.io/last-applied-configuration
に保持されるが、ここには実際に記述したものしか保持されない(上の勝手に補完されるspec.template.metadata.labels
は保持されない) -
kubectl apply
でspec.template.metadata.labels
を変更した時に、前回補完されたspec.selector.matchLabels
と一致せずにエラーになる! - で、
apps/v1beta2
からはspec.selector.matchLabels
もちゃんと書いてもらうことになった、あとspec.template.metadata.labels
は変更禁止になった
ということみたいですね、
変更できなくしたならbeta1の頃のように補完してくれても問題ないような気がするんですが。
これだけだとkubectl apply
の実装に合わせて取り繕ったように見えてしまいますし、ちゃんと調べたらもっと深い部分の話が出てきそうです。
が、全部書かないといけない理由としては納得できたので一旦ここで終了。気が向いたら更に追ってみようかと…