<p>While reading nodeselector (<a href="https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#:%7E:text=nodeSelector" rel="nofollow noreferrer">link</a>), I was bewildered why node selector is a key-value pair. It would have been simple if just provide an identifier. For example instead of following</p>
<pre><code>kubectl label nodes node.xyz disktype=ssd
</code></pre>
<p>We could use</p>
<pre><code>kubectl label nodes node.xyz ssdDisk
</code></pre>
<p>What is the reason for giving nodeselector as key value pair.</p>

Manish Khandelwal
<p>Short answer: because that's what the engineers who created it thought. :)</p>
<p>You can look at the source code. There is <code>nodeSelector</code> defined as a key-value map.
By the way, the <code>labels</code> are also defined in the same way, so that one can match the other.
Due to the fact that node selector is a key-value map - you can use a lot of them while maintaining order.</p>
<hr />
<p>Here you have a <a href="https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/api/core/v1/types.go" rel="nofollow noreferrer">link</a> to the code where nodeselector has been defined. You may be interested in these code snippets:</p>
<pre><code>type NodeSelector struct {
//Required. A list of node selector terms. The terms are ORed.
NodeSelectorTerms []NodeSelectorTerm `json:&quot;nodeSelectorTerms&quot; protobuf:&quot;bytes,1,rep,name=nodeSelectorTerms&quot;`
}
</code></pre>
<pre><code>type NodeSelectorTerm struct {
    // A list of node selector requirements by node's labels.
    // +optional
    MatchExpressions []NodeSelectorRequirement `json:&quot;matchExpressions,omitempty&quot; protobuf:&quot;bytes,1,rep,name=matchExpressions&quot;`
    // A list of node selector requirements by node's fields.
    // +optional
    MatchFields []NodeSelectorRequirement `json:&quot;matchFields,omitempty&quot; protobuf:&quot;bytes,2,rep,name=matchFields&quot;`
}
</code></pre>
<pre><code>type NodeSelectorRequirement struct {
    // The label key that the selector applies to.
    Key string `json:&quot;key&quot; protobuf:&quot;bytes,1,opt,name=key&quot;`
    // Represents a key's relationship to a set of values.
    // Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.
    Operator NodeSelectorOperator `json:&quot;operator&quot; protobuf:&quot;bytes,2,opt,name=operator,casttype=NodeSelectorOperator&quot;`
    // An array of string values. If the operator is In or NotIn,
    // the values array must be non-empty. If the operator is Exists or DoesNotExist,
    // the values array must be empty. If the operator is Gt or Lt, the values
    // array must have a single element, which will be interpreted as an integer.
    // This array is replaced during a strategic merge patch.
    // +optional
    Values []string `json:&quot;values,omitempty&quot; protobuf:&quot;bytes,3,rep,name=values&quot;`
}
</code></pre>
<p>And mapping <code>NodeSelector</code>:</p>
<pre><code>NodeSelector  map[string]string  `json:&quot;nodeSelector,omitempty&quot; protobuf:&quot;bytes,7,rep,name=nodeSelector&quot;`
</code></pre>
