先日CKADを再取得した際、Deploymentのラベルの扱いについて再認識したことがあったので備忘メモを残しておきます。
一般的なDeploymentのラベル
よく見るDeploymentの例では、以下の例のようなラベル(★印)が定義されています。
例:controllers/nginx-deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx ←★任意:このリソース(Deployment)のラベル spec: replicas: 3 selector: matchLabels: app: nginx ←★必須:Deploymentが管理するPodのラベル ・・・【A】 template: metadata: labels: app: nginx ←★必須:このリソース(Deployment)配下のPodのラベル ・・・【B】 spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80
それぞれのラベルの意味はkubernetes公式ドキュメント Deployment | Kubernetes にも記載されており【任意/必須】も含めて上記のような役割を担っています。
apply時にエラーとなるパターン
必須の【A】と【B】は省略できず、例えば以下のようなパターンではapply時にエラーとなりリソースを生成できません。(A ⊈ B)
パターン① 【A】(未定義):.spec.selector の定義が存在しない
The Deployment "nginx-deployment" is invalid: * spec.selector: Required value * spec.template.metadata.labels: Invalid value: map[string]string{"app":"nginx"}: `selector` does not match template `labels`
パターン② 【A】(未定義):.spec.selector の定義は存在するがラベルが未定義
The Deployment "nginx-deployment" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string(nil), MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: empty selector is invalid for deployment
パターン③ 【A】app: nginx 【B】(未定義):.spec.template.metadata.labels の定義は存在するがラベルが未定義
The Deployment "nginx-deployment" is invalid: spec.template.metadata.labels: Invalid value: map[string]string(nil): `selector` does not match template `labels`
パターン④ 【A】app: nginx 【B】app: xxxxx:.spec.template.metadata.labels の定義は存在するがラベルが不一致
The Deployment "nginx-deployment" is invalid: spec.template.metadata.labels: Invalid value: map[string]string{"app":"xxxxx"}: `selector` does not match template `labels`
apply時にエラーとならないパターン
ラベルは複数定義できるため、厳密にすべてのラベルが完全に一致している必要があるかと言えばそうではありません。
以下のようなパターンはリソースを生成できます。(A ⊆ B)
パターン⑤ 【A】app: nginx 【B】app: nginx + age: fifty
定義:
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx age: fifty spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80
をapplyすると以下のように問題なくリソース作成できます。
kubectl apply -f deploy.yaml deployment.apps/nginx-deployment created kubectl get pods --show-labels NAME READY STATUS RESTARTS AGE LABELS nginx-deployment-7f5b4c8c69-k458q 1/1 Running 0 27s age=fifty,app=nginx,pod-template-hash=7f5b4c8c69 nginx-deployment-7f5b4c8c69-kb6n2 1/1 Running 0 27s age=fifty,app=nginx,pod-template-hash=7f5b4c8c69 nginx-deployment-7f5b4c8c69-vkrlh 1/1 Running 0 27s age=fifty,app=nginx,pod-template-hash=7f5b4c8c69
パターン⑥ 【A】app: nginx 【B】app: xxxxx + app: yyyyy+ app: zzzzz+ app: nginx
※こんなことする人は居ないと思いますが試しにやってみました。(key重複は後勝ちなんですね😅)
定義:
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: xxxxx app: yyyyy app: zzzzz app: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80
をapplyすると以下のように問題なくリソース作成できます。
kubectl apply -f deploy.yaml deployment.apps/nginx-deployment created kubectl get pods --show-labels NAME READY STATUS RESTARTS AGE LABELS nginx-deployment-647677fc66-8lrnr 1/1 Running 0 12s app=nginx,pod-template-hash=647677fc66 nginx-deployment-647677fc66-gchpd 1/1 Running 0 12s app=nginx,pod-template-hash=647677fc66 nginx-deployment-647677fc66-shcvh 1/1 Running 0 12s app=nginx,pod-template-hash=647677fc66
所感
k8sのリソースまわりは公式ドキュメントなどを読んでもイマイチ正しく理解できたかいつもモヤモヤしてしまいます。 今回のように試験勉強でハマったり気になったりしたことは実際に手を動かしてコマンドを叩いて検証するのが一番スッキリしますし、 単に機械的に資格を取得するための学習だけをするのは非常にもったいないので、学びの機会として今後もうまく利用していきたいところです。
参考情報
今回は以下の情報を参考にさせてもらいました。🙇♂️