<p>Following are the example which I encountered on k8s website.</p>

<pre><code>apiVersion: v1
kind: Service
metadata:
  name: my-nginx
  labels:
    run: my-nginx
spec:
  ports:
  - port: 80
    protocol: TCP
  selector:
    run: my-nginx
</code></pre>

<p><strong>selector:
    run: my-nginx</strong>
Not able to figure out what is the rationale behind labeling it in spec and then applying same selector on the spec definition.Found plenty of example but no explanation for them.</p>

<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-world
spec:
  selector:
    matchLabels:
      run: load-balancer-example
  replicas: 2
  template:
    metadata:
      labels:
        run: load-balancer-example
    spec:
      containers:
        - name: hello-world
          image: gcr.io/google-samples/node-hello:1.0
          ports:
            - containerPort: 8080
              protocol: TCP
</code></pre>

<p>**
 selector:</p>

<pre><code>matchLabels:

  run: load-balancer-example**
</code></pre>

<p>This is one of the fundamental design concepts of Kubernetes:</p>

<p><strong><em>Resources are linked by <a href="https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/" rel="noreferrer">labels and selectors</a>.</em></strong></p>

<p>Resources such as a Service or Deployment that must refer to other resources have a <strong>selector</strong> which defines a set of labels. These resources select all those resources (of a specific type) that have <strong>labels</strong> matching this selector.</p>

<p>For example, a Deployment with a selector of <code>a=b</code> refers to all Pods that happen to have the label <code>a=b</code>.</p>

<p>That's why in your Deployment specification, you have to define the same label (<code>run=load-balancer-example</code>) in the Pod template (<code>template</code> section) as in the selector of the Deployment. Because you want the Deployment to manage <em>these</em> Pods:</p>

<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-world
spec:
  selector:
    matchLabels:
      run: load-balancer-example    # &lt;&lt;&lt;&lt;&lt;----- must match
  replicas: 2
  template:  # &lt;- you define a template for the Pods that will be created here
    metadata:
      labels:
        run: load-balancer-example  # &lt;&lt;&lt;&lt;------ must match
    spec:
      containers:
        - name: hello-world
          image: gcr.io/google-samples/node-hello:1.0
          ports:
            - containerPort: 8080
              protocol: TCP
</code></pre>

<p>If you have any other Pods with the <code>run=load-balancer-example</code>, the Deployment will manage these too. On the other hand, if the labels in the Pod template of the Deployment specification were different from the selector, the Deployment wouldn't manage these Pods because their labels don't match the selector of the Deployment.</p>

<p>In your first example, the label definitions within the Service specification are unrelated. The first one (<code>labels</code>) is the label of the Service (you could omit it, if you want), the second one (<code>selector</code>) is the selector of the Service:</p>

<pre><code>apiVersion: v1
kind: Service
metadata:
  name: my-nginx
  labels:
    run: my-nginx  # &lt;&lt;&lt;&lt;&lt;---- unrelated to the other 'run: my-nginx'
spec:
  ports:
  - port: 80
    protocol: TCP
  selector:
    run: my-nginx  # &lt;&lt;&lt;&lt;&lt;---- unrelated to the other 'run: my-nginx'
</code></pre>

<p>However, the <strong>selector <em>is</em> related to the labels of any Pods</strong>. In particular, this Service will apply to all Pods that have the <code>run=my-nginx</code> label.</p>
