Powerful k8s concepts that every k8s developer must know

Srutha K
4 min readAug 10, 2021

Co-author: Sushma Korati

This blog is to focus on tiny but powerful concepts(most of them revolving around pods) that are often overlooked in the development phase and are only brought into focus during certifications and actual production deployment phases. So here we go!

  1. PDB — Pod Disruption Budget
    Assume our deployment runs a micro-service that has to have 3 pods available at all times. We generally set the number of replicas for such a requirement. But what if the cluster administrator decides to delete the pods (this is called a voluntary disruption)?
    The saviour here is the “Pod Disruption Budget”. Once you create a PDB and specify a minimum availability, the cluster-admin should be careful to use tools that respect PDB instead of directly using delete. Here is an example PD :
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: zk-pdb
spec:
minAvailable: 2 (or) maxUnavailable: 3
selector:
matchLabels:
app: zookeeper

2. IDS — Initial Delay Seconds
Pods generally are configured with probes like the readiness and liveness checks. These are required so that dependent systems and end users know when the pod is available to be used. If a pod has a number of dependencies, it might take a while to start. But the probes tend to keep trying before the pod is fully up. Due to this, the pods fail a few times initially. This is an unnecessary waste of kube resources and does leave a not-so-perfect end user experience.
This is when one should set the “InitialDelaySeconds” field. This would ensure that the control waits for these probes to run till the delay is completed.
This can be set as below

apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-exec
spec:
containers:
- name: liveness
image: k8s.gcr.io/busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5

3. NodeSelector
If there is a scenario where certain pods must use specific nodes, this can be achieved with the help of the NodeSelector. Add a label to your node and use this label as a value to the nodeSelector field in your pod spec.

apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
nodeSelector:
disktype: ssd

4. Node Affinity
NodeAffinityis useful when we want certain pods to prefer certain nodes. For this set some labels on the nodes using which your pods can be set with the appropriate node affinity. For this set labels on your node which can be used to specify the node in your pod configuration.

kubectl label nodes <your-node-name> disktype=ssd

There are 2 types of node affinity that can be set : requiredDuringSchedulingIgnoredDuringExecution and preferredDuringSchedulingIgnoredDuringExecution
Required option ensures that the pod is assigned to the node mentioned in the matchExpression field’s value. If this is not found, the pod results in an unsuccessful state. The preferred option is to select the node with the matchExpression if it is available. Till it is absolutely necessary, it is better to use the preferred option.

apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:

nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values:
- ssd
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
(OR)apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: disktype
operator: In
values:
- ssd
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent

5. Pod Affinity & Pod Anti Affinity
In scenarios where we would want 2 or more pods to be available on the same node, then we can set the PodAffinity for these pods. Similarly to prefer 2 pods to not be together on the same node, we can set the PodAntiAffinity .
Both these have 2 variants : requiredDuringSchedulingIgnoredDuringExecution and preferredDuringSchedulingIgnoredDuringExecution . The required option mandates that the specified pods are put on the same node while the preferred option will ensure the pods being placed together if it is possible.

apiVersion: v1
kind: Pod
metadata:
name: with-pod-affinity
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S1
topologyKey: topology.kubernetes.io/zone
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S2
topologyKey: topology.kubernetes.io/zone
containers:
- name: with-pod-affinity
image: k8s.gcr.io/pause:2.0

6. Taints and Tolerations
Taints are set to nodes to avoid pods from using those nodes. Tolerations on the other hand are set to pods so that these pods with tolerations can tolerate the taint on the node and can reside on the node.
A taint can be added on a node as :

kubectl taint nodes node1 key1=value1:NoSchedule

and a toleration can be set on the pod like below :

tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoSchedule"
(OR)tolerations:
- key: "key1"
operator: "Exists"
effect: "NoSchedule"

-Note: All examples have been picked form the kubernetes official documentation : https://kubernetes.io/

--

--