<p>What is the significance of having this section - <code>spec.template.metadata</code>? It does not seem to be mandatory. However I would like to know where it would be very useful! Otherwise what is the point of repeating all the selectors?</p>

<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello
spec:
  selector:
    matchLabels:
      app: hello
      tier: backend
      track: stable
  replicas: 7
  template:
    metadata:
      labels:
        app: hello
        tier: backend
        track: stable
    spec:
      containers:
        - name: hello
          image: "gcr.io/google-samples/hello-go-gke:1.0"
          ports:
            - name: http
              containerPort: 80
</code></pre>

<p>What makes you think it is not required?</p>
<p>If you don't provide the <code>Metadata</code> for a deployment template, it will fail with a message like this:</p>
<pre><code>The Deployment &quot;nginx&quot; is invalid: spec.template.metadata.labels: 
Invalid value: map[string]string(nil): `selector` does not match template `lab
els`
</code></pre>
<p>Or if the metadata does not match the selector, will fail with a message like this:</p>
<pre><code>The Deployment &quot;nginx&quot; is invalid: spec.template.metadata.labels: 
Invalid value: map[string]string{&quot;run&quot;:&quot;nginxv1&quot;}: `selector` does not match template `labels`
</code></pre>
<p>Also, if you do not provide the <code>selector</code> it will error with a message like this:</p>
<pre><code>error validating &quot;STDIN&quot;: error validating data: ValidationError(Deployment.spec): 
missing required field &quot;selector&quot; in io.k8s.api.apps.v1.DeploymentSpec; 
if you choose to ignore these errors, turn validation off with --validate=false
</code></pre>
<p>The yaml used is the below:</p>
<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: nginx
  name: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      run: nginx
  strategy: {}
  template:
    metadata:
      labels:
        run: nginxv1
    spec:
      containers:
      - image: nginx
        name: nginx
</code></pre>
<p>When you read the <a href="https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#creating-a-deployment" rel="nofollow noreferrer">docs</a>, the description for the <code>selector</code> says:</p>
<blockquote>
<p>The selector field defines how the Deployment finds which Pods to manage. In this case, you simply select a label that is defined in the Pod template (app: nginx). However, more sophisticated selection rules are possible, <strong>as long as the Pod template itself satisfies the rule</strong>.</p>
</blockquote>
<h1><a href="https://kubernetes.io/docs/reference/federation/v1/definitions/#_v1_objectmeta" rel="nofollow noreferrer">Metadata</a></h1>
<p>Most objects in Kubernetes have a metadata, it is responsible to store information about the resource like, name, labels, annotations and so on.</p>
<p>When you create a deployment, the template is needed for creation\update of ReplicaSet and PODs, in this case, they need to match the selector, otherwise you would end up with orphan resources around your cluster, and the metadata store the data used to link them.</p>
<p>This was designed this way to make the resources are loosely coupled from each other, if you make simple change to the label of a pod created by this deployment\replicaSet, you will notice that the old POD keep running, but a new one is created, because the old one does not attend the selector rule anymore and ReplicaSet create a new one to keep the number of desired replicas.</p>
