34

From Kubernetes documentation:

The selector field defines how the Deployment finds which Pods to manage.

But, when creating deployment, I already specify the pod template as part of the deployment. So, why will I need the selectors as well?

Is it supposed to be used like services, where pods are already being started separately, but later brought under the umbrella of Deployment to be managed together?

Paddy
  • 495

3 Answers3

20

Answer for this question we can find in section Deployments from kubernetes.io

So, why will I need the selectors as well?

Quotes below from documentation for k8s v 1.14

.spec.selector is an required field that specifies a label selector for the Pods targeted by this deployment.

.spec.selector must match .spec.template.metadata.labels, or it will be rejected by the API.

In API version apps/v1, .spec.selector and .metadata.labels do not default to .spec.template.metadata.labels if not set. So they must be set explicitly. Also note that .spec.selector is immutable after creation of the Deployment in apps/v1.

A Deployment may terminate Pods whose labels match the selector if their template is different from .spec.template or if the total number of such Pods exceeds .spec.replicas. It brings up new Pods with .spec.template if the number of Pods is less than the desired number.

Pods are already being started separately, but later brought under the umbrella of Deployment to be managed together?

Simply speaking, No

Note: You should not create other pods whose labels match this selector, either directly, by creating another Deployment, or by creating another controller such as a ReplicaSet or a ReplicationController. If you do so, the first Deployment thinks that it created these other pods. Kubernetes does not stop you from doing this. If you have multiple controllers that have overlapping selectors, the controllers will fight with each other and won’t behave correctly.

3

While spec.template.metadata.labels can have extra labels which you can annotate the pod with, the selector section (i.e. matchLabels) need to pin some/few of them so it will know which pods are under its governance.

taitelman
  • 131
0

Here is an example that helped me understand why we need both sets of labels.

Note: I'm still learning k8s too, so I have simplified things based on my understanding; it's possible something in this description is technically incorrect and I am not aware. Feel free for anyone to correct this. But I hope it helps answer the question.

Imagine you have the following deployment configured:

apiVersion: apps/v1
kind: Deployment
metadata:
  ...
spec:
  selector:
    matchLabels:
      app: my-serviceA
      release: free
  template:
    metadata:
      labels:
        app: my-serviceA
        release: free
        version: '254'
        team: 'service-A-team'

The labels app and release in spec.selector.matchLabels tell the Deployment which pods it can control, e.g. to terminate a pod. The Deployment ignores any other labels set in spec.template.metadata.labels. It will only control pods with these app and release labels, regardless of what other labels might be set on those pods.

This means the pods can have other labels that will be ignored by the Deployment, which might change regularly, and which might be used by other things (k8s or other tools). For example, the team label might be used for routing alerts from that pod to the right on-call team. The version label helps engineers know what version of the code is running on that pod. Those labels might be updated regularly, e.g. the version number will be incremented with a new release, or the team monitoring the service may change (or change name), but the Deployment will not be affected by changes to those labels, because it is only watching app and release which should be very stable.

So when a new version of the app is released (254->255), the version label changes in spec.template.metadata.labels, but the Deployment knows that the old pods (with version 254) and the new pods (with version 255) all "belong" to it, because it ignores the version label and only considers the labels set in spec.selector.matchLabels.