<p>I am new to Kubernetes, so this might be obvious, but in a deployment yaml, why do we have to define the labels in the deployment metadata, then define the same labels in the template metadata, but match those separately in the selector?</p>
<p>Shouldn't it be obvious that the template belongs to the deployment it's under?
Is there a use case for a deployment to have a template it doesn't match?</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-backend
spec:
  replicas: 2
  selector:
    matchLabels:
      app: api-backend
  template:
    metadata:
      labels:
        app: api-backend
    spec:
      #...etc
</code></pre>
<p>I might be missing some key understanding of k8s or yamls.</p>
<p>Having the template with no label, and it seems to work, but I don't understand why. Kubernetes could be auto-magically inserting the labels.</p>

<p>Let's simplify labels, selectors and template labels first.</p>
<ul>
<li>The Labels in the metadata section are assigned to the deployment itself.</li>
<li>The Labels in the <code>.spec.template</code> section are assigned to the pods created by the deployment. These are actually called PodTemplate labels.</li>
<li>The selectors provide uniqueness to your resource. It is used to identify the resources that match the labels in <code>.spec.selector.matchLabels</code> section.</li>
</ul>
<p>Now, it is not mandatory to have all the podTemplate Labels in the matchLabels section. a pod can have many labels but only one of the matchLabels is enough to identify the pods. Here's an use case to understand why it has to be used</p>
<p>&quot;Let’s say you have deployment X which creates two pods with label <code>nginx-pods</code> and image <code>nginx</code> and another deployment Y which applies to the pods with the same label <code>nginx-pods</code> but uses images <code>nginx:alpine</code>. If deployment X is running and you run deployment Y after, it will not create new pods, but instead, it will replace the existing pods with <code>nginx:alpine</code> image. Both deployment will identify the pods as the labels in the pods matches the labels in both of the deployments <code>.spec.selector.matchLabels</code>&quot;</p>
