
If you are not familiar with the oc command, refer to OpenShift - Getting Started with the oc command.
The selector annotation is used to:
- configure a pod to run on a certain node
- configure a service to forward requests onto certain pods
- pods in a namespace will be scheduled to run on nodes that contain a certain label
This is only the most common use of selector. There are many more things that selector can be used for.
configure a pod to run on a certain node
Check out my article OpenShift - Run a pod on a specific node using nodeSelector.
Configure a service to forward requests onto certain pods
In this example, my-service does not have a selector and endpoints is none meaning this service will not forward requests onto any pods.
~]$ oc describe service my-service
Name: my-service
Namespace: my-project
Labels: <none>
Annotations: <none>
Selector: <none>
Type: ClusterIP
IP: 172.30.40.50
IPs: 172.30.40.50
Port: http 12345/TCP
TargetPort: 8080/TCP
Endpoints: <none>
Session Affinity: None
Events: <none>
And let's say the pod has no labels.
~]$ oc get pod my-pod-fspkb --output jsonpath="{.metadata.labels}" | jq
{
}
First and foremost, let's label the pod to contain one or more labels.
~]$ oc patch pod my-pod-fspkb --patch '{"metadata":{"labels":{"app": "my-app"}}}'
pod/my-pod-fspkbb patched
Now the pod has label app: my-app.
~]$ oc get pod my-pod-fspkb --output jsonpath="{.metadata.labels}" | jq
{
"app": "my-app"
}
Let's also configure the service with a selector.
~]$ oc patch service my-service --patch '{"spec":{"selector":{"app": "my-app"}}}'
service/my-service patched
Now my-service has selector app=my-app which means that the service will only forward requests onto pods that have label app=my-app. Notice also that Endpoints now contains an IP address and port, 10.11.12.13:8080. This means that there are one or more pods in the namespace that have app=my-app thus the service will be able to forward requests onto the pod that has IP address 10.11.12.13 on port 8080.
~]$ oc describe service my-service
Name: my-service
Namespace: my-project
Labels: <none>
Annotations: <none>
Selector: app=my-app
Type: ClusterIP
IP: 172.30.40.50
IPs: 172.30.40.50
Port: http 12345/TCP
TargetPort: 8080/TCP
Endpoints: 10.11.12.13:8080
Session Affinity: None
Events: <none>
Notice in this example that the pod has label app: my-app and also has IP address 10.11.12.13 and port 8080, thus this is the pod the service will forward requests onto.
~]$ oc get pod my-pod-fspkb --output jsonpath="{.metadata.labels} {.status.podIPs} {.spec.containers[*].ports}" | jq
{
"app": "my-app"
}
[
{
"ip": "10.128.18.55"
}
]
[
{
"containerPort": 8080,
"protocol": "TCP"
},
]
pods in a namespace will be scheduled to run on nodes that contain a certain label
The oc get nodes command will return the list of nodes. Notice there are two worker nodes.
~]# oc get nodes
NAME STATUS ROLES AGE VERSION
my-node-infra-4k6z9 Ready infra 273d v1.11.0+d4cacc0
my-node-master-0 Ready master 273d v1.11.0+d4cacc0
my-node-worker-5n4fj Ready worker 273d v1.11.0+d4cacc0
my-node-worker-v8r9r Ready worker 273d v1.11.0+d4cacc0
Let's say you want to be able to specify the worker node that an application / container / pod will run. To accomplish this, you will need to label the worker nodes. The oc label node command can be used to apply one or more labels to a worker node. The worker node doesn't have to be labeled "region". You can pick any key value pair you would like.
~]$ oc label node my-node-worker-5n4fj region=east
node/my-node-worker-5n4fj labeled
~]$ oc label node my-node-worker-v8r9r region=west
node/my-node-worker-v8r9r labeled
The oc describe node command can be used to see the labels that have been applied to the worker nodes.
~]$ oc describe node my-node-worker-5n4fj
Name: my-node-worker-5n4fj
Roles: infra,worker
Labels: region=east
~]$ oc describe node my-node-worker-v8r9r
Name: my-node-worker-v8r9r
Roles: infra,worker
Labels: region=west
The oc patch command can be used to configure a namespace with the node-selector annotation so that all pods in the namespace are scheduled to run on a node that have a matching label. In this example, namespace my-project is configured with the node-selector region=east annotation so that all pods in my-project are scheduled to run on a node that has label region: east.
oc patch namespace my-project --patch '{"metadata":{"annotations":{"scheduler.alpha.kubernetes.io/node-selector": "region=east"}}}'
The oc get namespace command should now show that the namespaces has the annotation.
~]$ oc get namespace my-project --output yaml
metadata:
annotations:
scheduler.alpha.kubernetes.io/node-selector: region=east
Did you find this article helpful?
If so, consider buying me a coffee over at