Introduction
Labels are a useful way to select which nodes that an application will run on. These nodes are created by machines which are defined by the MachineSets we worked with in previous sections of this workshop. An example of this would be running a memory intensive application only on a specific node type.
While you can directly add a label to a node, it is not recommended because nodes can be recreated, which would cause the label to disappear. Therefore we need to label the MachineSet itself. An important caveat to this process is that only new machines created by the MachineSet will get the label. This means you will need to either scale the MachineSet down to zero then back up to create new machines with the label, or you can label the existing machines directly.
Set a label for the MachineSet
-
Just like the last section, let’s pick a MachineSet to add our label. To do so, run the following command:
MACHINESET=$(oc -n openshift-machine-api get machinesets -o name | head -1) echo ${MACHINESET}Sample Outputmachineset.machine.openshift.io/aro-cluster-lwqq8-8mkmr-worker-eastus1 -
Now, let’s patch the MachineSet with our new label. To do so, run the following command:
oc -n openshift-machine-api patch ${MACHINESET} \ --type=merge \ --patch '{"spec":{"template":{"spec":{"metadata":{"labels":{"tier":"frontend"}}}}}}'Sample Outputmachineset.machine.openshift.io/aro-cluster-lwqq8-8mkmr-worker-eastus1 patched -
As you’ll remember, the existing machines won’t get this label, but all new machines will. While we could just scale this MachineSet down to zero and back up again, that could disrupt our workloads. Instead, let’s just loop through and add the label to all of our nodes in that MachineSet. To do so, run the following command:
MACHINES=$(oc -n openshift-machine-api get machines -o name -l "machine.openshift.io/cluster-api-machineset=$(echo $MACHINESET | cut -d / -f2 )" | cut -d / -f2 | xargs) for MACHINE in $(echo ${MACHINES}); do oc label -n openshift-machine-api machine ${MACHINE} tier=frontend oc label node ${MACHINE} tier=frontend doneSample Outputmachine.machine.openshift.io/aro-cluster-lwqq8-8mkmr-worker-eastus1-6qt5v labeled node/aro-cluster-lwqq8-8mkmr-worker-eastus1-6qt5v labeled machine.machine.openshift.io/aro-cluster-lwqq8-8mkmr-worker-eastus1-8vzrw labeled node/aro-cluster-lwqq8-8mkmr-worker-eastus1-8vzrw labeled machine.machine.openshift.io/aro-cluster-lwqq8-8mkmr-worker-eastus1-vgmng labeled node/aro-cluster-lwqq8-8mkmr-worker-eastus1-vgmng labeledDepending when (or if) you did the Autoscaling lab you may have 1, 2 or 3 Machines and Nodes that get the label.
-
Now, let’s verify the nodes are properly labeled. To do so, run the following command:
oc get nodes --selector='tier=frontend' -o nameSample Outputnode/aro-cluster-lwqq8-8mkmr-worker-eastus1-6qt5v node/aro-cluster-lwqq8-8mkmr-worker-eastus1-8vzrw node/aro-cluster-lwqq8-8mkmr-worker-eastus1-vgmngPending that your output shows one or more node(s), this demonstrates that our MachineSet and associated nodes are properly annotated!
Deploy an app to the labeled nodes
Now that we’ve successfully labeled our nodes, let’s deploy a workload to demonstrate app placement using nodeSelector.
This should force our app to deploy only on labeled nodes.
-
First, let’s create a namespace (also known as a project in OpenShift). To do so, run the following command:
oc new-project nodeselector-exSample OutputNow using project "nodeselector-ex" on server "https://api.rbrlitrg.westeurope.aroapp.io:6443". You can add applications to this project with the 'new-app' command. For example, try: oc new-app rails-postgresql-example to build a new example application in Ruby. Or use kubectl to deploy a simple Kubernetes application: kubectl create deployment hello-node --image=k8s.gcr.io/e2e-test-images/agnhost:2.33 -- /agnhost serve-hostname -
Next, let’s deploy our application and associated resources that will target our labeled nodes. Notice how we added the
nodeSelectorto the specification of our Deployment to do this. Run the following command:cat << EOF | oc create -f - --- kind: Deployment apiVersion: apps/v1 metadata: name: nodeselector-app namespace: nodeselector-ex spec: replicas: 1 selector: matchLabels: app: nodeselector-app template: metadata: labels: app: nodeselector-app spec: nodeSelector: tier: frontend containers: - name: hello-openshift image: "docker.io/openshift/hello-openshift" ports: - containerPort: 8080 protocol: TCP - containerPort: 8888 protocol: TCP EOFSample Outputdeployment.apps/nodeselector-app created -
Now, let’s validate that the application has been deployed to one of the labeled nodes. To do so, run the following command:
oc -n nodeselector-ex get pod -l app=nodeselector-app \ -o jsonpath='{.items[0].spec.nodeName}'; echoSample Outputaro-cluster-lwqq8-8mkmr-worker-eastus1-6qt5v -
Double check the name of the node to compare it to the output above to ensure the node selector worked to put the pod on the correct node:
oc get nodes --selector='tier=frontend' -o nameSample Outputnode/aro-cluster-lwqq8-8mkmr-worker-eastus1-6qt5v node/aro-cluster-lwqq8-8mkmr-worker-eastus1-8vzrw node/aro-cluster-lwqq8-8mkmr-worker-eastus1-vgmngIn the list of nodes look for the final string to match, in this example
shj9g) -
Next create a
serviceusing theoc exposecommand:oc expose deployment nodeselector-app -n nodeselector-exSample Outputservice/nodeselector-app exposed -
Expose the newly created
servicewith aroute:oc create route edge --service=nodeselector-app --insecure-policy=Redirect -n nodeselector-exSample Outputroute.route.openshift.io/nodeselector-app created -
Fetch the URL for the newly created
route:oc get routes/nodeselector-app -n nodeselector-ex -o jsonpath='https://{.spec.host}{"\n"}'Sample Outputhttps://nodeselector-app-nodeselector-ex.apps.nbybk9f3.eastus.aroapp.ioThen visit the URL presented in a new tab in your web browser (using HTTPS).
The application is exposed over the default ingress using a predetermined URL and trusted TLS certificate. This is done using the OpenShift
Routeresource which is an extension to the KubernetesIngressresource.
Congratulations!
You’ve successfully demonstrated the ability to label nodes and target those nodes using a nodeSelector.