> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Lab Solution Node Affinity Optional

> A hands-on Kubernetes lab demonstrating inspecting and labeling nodes, creating deployments, and using nodeAffinity rules to constrain pods with In and Exists operators

This lab walks through practical Kubernetes node affinity tasks: inspecting node labels, labeling a node, creating deployments, and constraining pods to specific nodes using nodeAffinity. The steps below show the commands, minimal YAML snippets, and verification commands you can run in a cluster.

***

## 1) Count labels on node01

List labels on a node with either `kubectl describe` or `kubectl get --show-labels`.

Example using `--show-labels`:

```bash theme={null}
root@controlplane:~# kubectl get node node01 --show-labels
NAME    STATUS   ROLES    AGE   VERSION   LABELS
node01  Ready    <none>   14m   v1.20.0   beta.kubernetes.io/arch=amd64,kubernetes.io/hostname=node01,...
```

Or view the full label list with:

```bash theme={null}
root@controlplane:~# kubectl describe node node01
# Look under the "Labels:" section in the output.
```

Count the labels shown. (In the environment used here the node shows six labels.)

***

## 2) Check the value of `beta.kubernetes.io/arch` on node01

You can scan the `--show-labels` output for the label or inspect `kubectl describe` output:

```bash theme={null}
root@controlplane:~# kubectl get node node01 --show-labels
# Look for the 'beta.kubernetes.io/arch' label in the LABELS column.
```

In this cluster `beta.kubernetes.io/arch=amd64`.

***

## 3) Apply a label `color=blue` to node01

Add a label to the node using `kubectl label`:

```bash theme={null}
root@controlplane:~# kubectl label node node01 color=blue
node/node01 labeled
```

Verify the label was applied:

```bash theme={null}
root@controlplane:~# kubectl get node node01 --show-labels
NAME    STATUS   ROLES    AGE   VERSION   LABELS
node01  Ready    <none>   14m   v1.20.0   color=blue,beta.kubernetes.io/arch=amd64,...
```

***

## 4) Create a deployment named `blue` (nginx) with 3 replicas

Create the deployment:

```bash theme={null}
root@controlplane:~# kubectl create deployment blue --image=nginx --replicas=3
deployment.apps/blue created
```

Before adding affinity, check which nodes could schedule the pods. Look for taints (if no taints, pods may schedule to any node that meets resource/constraint requirements):

```bash theme={null}
root@controlplane:~# kubectl get nodes
NAME          STATUS   ROLES                AGE   VERSION
controlplane  Ready    control-plane,master 15m   v1.20.0
node01        Ready    <none>               14m   v1.20.0

root@controlplane:~# kubectl describe node node01 | grep Taints
Taints:         <none>

root@controlplane:~# kubectl describe node controlplane | grep Taints
Taints:         <none>
```

Because there are no taints, the scheduler could place the `blue` pods on either node by default.

***

## 5) Constrain `blue` deployment to node01 using nodeAffinity

Edit the `blue` Deployment and add a nodeAffinity rule under `spec.template.spec.affinity.nodeAffinity` so the scheduler only places pods on nodes with `color=blue`.

Open the deployment for editing:

```bash theme={null}
root@controlplane:~# kubectl edit deployment blue
```

Inside the Deployment's Pod template, add the following YAML under `spec.template.spec` (maintain correct indentation relative to the existing manifest):

```yaml theme={null}
affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: color
          operator: In
          values:
          - blue
```

A minimal view of the relevant part of the updated Deployment spec:

```yaml theme={null}
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: blue
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: color
                operator: In
                values:
                - blue
      containers:
      - name: nginx
        image: nginx
```

Save the edit and verify the pods are scheduled on `node01`:

```bash theme={null}
root@controlplane:~# kubectl get pods -o wide -l app=blue
NAME                      READY   STATUS    RESTARTS   AGE   NODE
blue-xxxxx-yyyyy          1/1     Running   0          1m    node01
blue-xxxxx-zzzzz          1/1     Running   0          1m    node01
blue-xxxxx-aaaaa          1/1     Running   0          1m    node01
```

All `blue` pods are now placed on `node01` as required.

<Callout icon="lightbulb" color="#1CB2FE">
  When using `operator: In` you must provide one or more `values`. The node must have the exact label key/value pair to match.
</Callout>

***

## 6) Create a deployment named `red` (nginx) with 2 replicas and ensure it runs on the control plane node

The control plane node has the label `node-role.kubernetes.io/master` (no value). To match nodes that have the label regardless of its value, use the `Exists` operator.

Recommended workflow: generate the Deployment YAML with a dry-run, edit it to add the affinity block, then create it.

Generate YAML:

```bash theme={null}
root@controlplane:~# kubectl create deployment red --image=nginx --replicas=2 --dry-run=client -o yaml > red.yaml
```

Edit `red.yaml` and add the nodeAffinity under `spec.template.spec`:

```yaml theme={null}
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: red
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: node-role.kubernetes.io/master
                operator: Exists
      containers:
      - name: nginx
        image: nginx
```

Important: `operator: Exists` must be used without a `values` field.

Create the deployment:

```bash theme={null}
root@controlplane:~# kubectl create -f red.yaml
deployment.apps/red created
```

Verify the `red` pods are scheduled on the control plane node:

```bash theme={null}
root@controlplane:~# kubectl get pods -o wide -l app=red
NAME                      READY   STATUS    RESTARTS   AGE   NODE
red-xxxxx-yyyyy           1/1     Running   0          30s   controlplane
red-xxxxx-zzzzz           1/1     Running   0          30s   controlplane
```

<Callout icon="warning" color="#FF6B6B">
  YAML indentation is significant. If you see errors like `did not find expected key` when creating from a file, check the spacing/indentation for the added affinity block relative to `spec.template.spec`.
</Callout>

***

## Quick reference: common commands and affinity operators

| Purpose | Command / YAML |
| - | - |
| List node labels | `kubectl get node node01 --show-labels` |
| Describe node | `kubectl describe node node01` |
| Add a label to a node | `kubectl label node node01 color=blue` |
| Create deployment | `kubectl create deployment blue --image=nginx --replicas=3` |
| Dry-run to file | `kubectl create deployment red --image=nginx --replicas=2 --dry-run=client -o yaml > red.yaml` |
| nodeAffinity key exists (no value) | `operator: Exists` |
| nodeAffinity exact match | `operator: In` with `values: ["blue"]` |

***

You have now completed the lab tasks:

* inspected node labels,
* applied a node label,
* created a deployment and constrained it to a specific node using nodeAffinity with `In`,
* and created another deployment constrained to nodes that have a label using the `Exists` operator.

## Links and References

* [Kubernetes Node Affinity documentation](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity)
* [kubectl cheat sheet](https://kubernetes.io/docs/reference/kubectl/cheatsheet/)
* [Kubernetes scheduling concepts](https://kubernetes.io/docs/concepts/scheduling-eviction/)

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/cka-certification-course-certified-kubernetes-administrator/module/cd124bdf-9911-4cc1-8177-f2d8b6dfd2a0/lesson/15d9d7b3-4fcf-404f-8ba7-fea0f0481ee5" />
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.