Lab Exercises for Workloads & Scheduling
Exercise 0 - Setup
- Prepare a cluster (Single node, kubeadm, k3s, etc)
- Open browser tabs to Kubernetes Documentation, Kubernetes GitHub and Kubernetes Blog (these are permitted as per the current guidelines)
Exercise 1 - Understand deployments and how to perform rolling update and rollbacks
- Create a deployment object consisting of 6 pods, each containing a single
nginx:1.19.5
container - Identify the update strategy adopted by this deployment
- Modify the update strategy so
maxSurge
is equal to50%
andmaxUnavailable
is equal to50%
- Perform a rolling update to this deployment so that the image gets updated to
nginx1.19.6
- Undo the most recent change
Answer - Imperative
kubectl create deployment nginx --image=nginx:1.19.5 --replicas=6
kubectl describe deployment nginx | grep StrategyType
kubectl patch deployment nginx -p "{\"spec\": {\"strategy\": {\"rollingUpdate\": { \"maxSurge\":\"50%\"}}}}" --record=true
kubectl patch deployment nginx -p "{\"spec\": {\"strategy\": {\"rollingUpdate\": { \"maxUnavailable\":\"50%\"}}}}" --record=true
kubectl set image deployment nginx nginx=nginx:1.19.6 --record=true
kubectl rollout undo deployment/nginx
Answer - Declarative
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
spec:
replicas: 6
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.19.5
ports:
- containerPort: 80
kubectl describe deployment nginx (unless specified, will be listed as "UpdateStrategy")
patch.yaml contents:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
strategy:
rollingUpdate:
maxSurge: 50%
maxUnavailable: 50%
template:
spec:
containers:
- name: nginx
image: nginx:1.19.6
kubectl patch deployment nginx --patch-file=patch.yaml
kubectl rollout undo deployment/nginx
Exercise 2 - Use ConfigMaps to configure applications
- Create a configmap named
mycm
that has the following key=value pairkey
= ownervalue
= yourname
- Create a pod of your choice, such as
nginx
. Configure this Pod so that the underlying container has the environent varibaleOWNER
set to the value of this configmap
Answer
Create configmap:
kubectl create configmap mycm --from-literal=owner=david
Define Pod:
apiVersion: v1
kind: Pod
metadata:
name: nginx-configmap
spec:
containers:
- name: nginx-configmap
image: nginx
command: [ "/bin/sh", "-c", "env" ]
env:
# Define the environment variable
- name: OWNER
valueFrom:
configMapKeyRef:
# The ConfigMap containing the value you want to assign to SPECIAL_LEVEL_KEY
name: mycm
# Specify the key associated with the value
key: owner
Validate:
kubectl logs nginx-configmap | grep OWNER
OWNER=david
Exercise 3 - Use Secrets to configure applications
- Create a secret named
mysecret
that has the following key=value pair dbuser
= MyDatabaseUserdbpassword
= MyDatabasePassword- Create a pod of your choice, such as
nginx
. Configure this Pod so that the underlying container has the the following environment variables set: DBUSER
from secret keydbuser
DBPASS
from secret keydbpassword
Answer
kubectl create secret generic mysecret --from-literal=dbuser="MyDatabaseUser" --from-literal=dbpassword="MyDatabasePassword"
Apply the following manifest:
apiVersion: v1
kind: Pod
metadata:
name: nginx-secret
spec:
containers:
- name: nginx-secret
image: nginx
command: [ "/bin/sh", "-c", "env" ]
env:
- name: dbuser
valueFrom:
secretKeyRef:
name: mysecret
key: dbuser
- name: dbpassword
valueFrom:
secretKeyRef:
name: mysecret
key: dbpassword
restartPolicy: Never
Which can be validated with:
kubectl logs nginx-secret | grep db
dbuser=MyDatabaseUser
dbpassword=MyDatabasePassword
Exercise 4 - Know how to scale applications
- Create a deployment object consisting of 3
pods
containing a singlenginx
container - Increase this deployment size by adding two additional pods.
- Decrease this deployment back to the original size of 3
pods
Answer - Imperative
kubectl create deployment nginx --image=nginx --replicas=3
kubectl scale --replicas=5 deployment nginx
kubectl scale --replicas=3 deployment nginx
Answer - Declarative
Apply initial YAML:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
Apply modified YAML:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 5
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1
ports:
- containerPort: 80
Apply original YAML:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
Excerise 5 - Understand how resource limits can affect Pod scheduling
- Create a new namespace called "tenant-b-100mi"
- Create a memory limit of 100Mi for this namespace
- Create a pod with a memory request of 150Mi, ensure the limit has been set by verifying you get a error message.
Answer
kubectl create ns tenant-b-100mi
Deploy the manifest:
apiVersion: v1
kind: LimitRange
metadata:
name: tenant-b-memlimit
namespace: tenant-b-100mi
spec:
limits:
- max:
memory: 100Mi
type: Container
Test with deploying:
apiVersion: v1
kind: Pod
metadata:
name: default-mem-demo
namespace: tenant-b-100mi
spec:
containers:
- name: default-mem-demo
image: nginx
resources:
requests:
memory: 150Mi
Which should return:
The Pod "default-mem-demo" is invalid: spec.containers[0].resources.requests: Invalid value: "150Mi": must be less than or equal to memory limit