Exercise

In this exercise, you will use a specific constraint to make sure a Pod is deployed on a given node.

The following specification defines a Pod with a single MySQL container:

mysql.yaml
apiVersion: v1
kind: Pod
metadata:
  name: db
spec:
  containers:
  - image: mysql:5.7
    name: mysql
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: mysqlpwd
    volumeMounts:
    - name: data
      mountPath: /var/lib/mysql
  volumes:
  - name: data
    emptyDir: {}

To make sure the Pod is created on a specific type of node (node with a SSD disk), we add a constraint with the affinity property in the Pod’s specification:

mysql.yaml
apiVersion: v1
kind: Pod
metadata:
  name: db
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: disktype
            operator: In
            values:
            - ssd
  containers:
  - image: mysql:5.7
    name: mysql
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: mysqlpwd
    volumeMounts:
    - name: data
      mountPath: /var/lib/mysql
  volumes:
  - name: data
    emptyDir: {}

This constraint specifies the Pod must be scheduled on a node with the label disktype: ssd.

Copy this specification in mysql.yaml and create the Pod:

kubectl apply -f mysql.yaml

Verify its status:

kubectl get po db

You should get a result similar to the following one indicating the Pod is still Pending:

NAME   READY   STATUS    RESTARTS   AGE
db     0/1     Pending   0          2m31s

Get more info regarding the Pod:

kubectl describe po db

You will see no node match the constraint specified in the Pod’s specification (the result below is obtained when running the command on a 3 nodes cluster)

...
Events:
  Type     Reason            Age                 From               Message
  ----     ------            ----                ----               -------
  Warning  FailedScheduling  2s (x8 over 4m29s)  default-scheduler  0/3 nodes are available: 3 node(s) didn't match node selector.

Because there is no node with the label disktype: ssd, the constraint cannot be satisfied so the Pod cannot be deployed.

Use the following command to add the label on one of the cluster’s nodes (first replace NODE_NAME by the name of one the node of your cluster)

kubectl label nodes NODE_NAME disktype=ssd

After a couple of seconds, check the status of the Pod:

kubectl get po db

You should see the Pod is now in the Running status:

NAME   READY   STATUS         RESTARTS   AGE
db     1/1     Running        0          10m

If you describe the Pod once again, you’ll see it has been deployed on the node with the corresponding label.

kubectl describe po db
...
Events:
  Type     Reason            Age                 From                  Message
  ----     ------            ----                ----                  -------
  Warning  FailedScheduling  59s (x18 over 11m)  default-scheduler     0/3 nodes are available: 3 node(s) didn't match node selector.
  Normal   Scheduled         55s                 default-scheduler     Successfully assigned default/db to NODE_NAME
  Normal   Pulling           51s                 kubelet, NODE_NAME    pulling image "mysql:5.7"
  Normal   Pulled            25s                 kubelet, NODE_NAME    Successfully pulled image "mysql:5.7"
  Normal   Created           25s                 kubelet, NODE_NAME    Created container
  Normal   Started           24s                 kubelet, NODE_NAME    Started container