<p>Today I was going through some documentation and discussions about matchLabels statement that is a part of a Deployment (or other objects) in Kubernetes. Example below:</p>

<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
</code></pre>

<p>In some discussions, I saw that depending on the version of the API it could be optional or mandatory to use this selector.</p>

<p>Ref:</p>

<p><a href="https://github.com/helm/charts/issues/7680" rel="nofollow noreferrer">https://github.com/helm/charts/issues/7680</a></p>

<p><a href="https://stackoverflow.com/questions/50309057/what-is-the-purpose-of-a-kubernetes-deployment-pod-selector">What is the purpose of a kubernetes deployment pod selector?</a></p>

<p>But I can't see any official documentation where it is stated explicitly if the usage of this selector was mandatory or not for a specific version of a Kubernetes API. Do you know of any official documentation where it is stated whether or not it is mandatory to use matchLabels selector?</p>

<p>I have checked these links out but I did not bump into an official statement:
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.10/#deploymentspec-v1beta2-apps" rel="nofollow noreferrer">https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.10/#deploymentspec-v1beta2-apps</a></p>

<p><a href="https://kubernetes.io/docs/concepts/workloads/controllers/deployment/" rel="nofollow noreferrer">https://kubernetes.io/docs/concepts/workloads/controllers/deployment/</a></p>

<p><code>kubectl explain deploy.spec.selector --api-version=apps/v1</code></p>

<blockquote>
  <p>Label selector for pods. Existing ReplicaSets whose pods are selected
  by
       this will be the ones affected by this deployment. It must match the pod
       template's labels.</p>
</blockquote>

<p><a href="https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/api/apps/v1/types.go#L276-L279" rel="nofollow noreferrer">https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/api/apps/v1/types.go#L276-L279</a></p>

<blockquote>
<pre><code>Selector *metav1.LabelSelector `json:"selector" protobuf:"bytes,2,opt,name=selector"`
</code></pre>
</blockquote>

<p>The lack of <code>+optional</code> above this line tells you it's mandatory. It matches up with the error message you'll get if you try to make a deployment without one.</p>

<pre><code>cat &lt;&lt;EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
 spec:
   replicas: 1
   template:
     spec:
       containers:
       - image: nginx
         imagePullPolicy: Always
         name: nginx
       dnsPolicy: ClusterFirst
       restartPolicy: Always
EOF
</code></pre>

<blockquote>
  <p>error: error validating "STDIN": 
  in io.k8s.api.apps.v1.DeploymentSpec; if you choose to ignore these
  errors, turn validation off with --validate=false. error validating data: ValidationError(Deployment.spec): missing
  required field "selector"</p>
</blockquote>

<p><a href="https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go#L1076-L1085" rel="nofollow noreferrer">https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go#L1076-L1085</a></p>

<pre><code>type LabelSelector struct {
    // matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
    // map is equivalent to an element of matchExpressions, whose key field is "key", the
    // operator is "In", and the values array contains only "value". The requirements are ANDed.
    // +optional
    MatchLabels map[string]string `json:"matchLabels,omitempty" protobuf:"bytes,1,rep,name=matchLabels"`
    // matchExpressions is a list of label selector requirements. The requirements are ANDed.
    // +optional
    MatchExpressions []LabelSelectorRequirement `json:"matchExpressions,omitempty" protobuf:"bytes,2,rep,name=matchExpressions"`
}
</code></pre>
