Exercises
Exercise 1: Horizontal Pod Autoscaler
In this exercise, you will create and configure a Horizontal Pod Autoscaler (HPA) to automatically scale a deployment based on CPU utilization.
Step 1: Create a Deployment
First, create a deployment that will be scaled by the HPA:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deployment
spec:
replicas: 2
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:latest
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
Apply the deployment:
oc apply -f web-deployment.yaml
oc get deployment web-deployment
Step 2: Create an HPA
Create a Horizontal Pod Autoscaler that scales the deployment based on CPU utilization:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-deployment
minReplicas: 2
maxReplicas: 4
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
Apply the HPA:
oc apply -f web-hpa.yaml
oc get hpa web-hpa
Step 3: Monitor HPA Status
Monitor the HPA to see its current status and scaling decisions:
# View HPA status
oc get hpa web-hpa
# Get detailed HPA information
oc describe hpa web-hpa
# Watch HPA and deployment replicas
oc get hpa web-hpa -w
oc get deployment web-deployment -w
Observe the current replica count and target metrics.
Step 4: Generate Load
Generate CPU load on the pods to trigger scaling. In a separate terminal, run:
# Get a pod name
POD_NAME=$(oc get pods -l app=web -o jsonpath='{.items[0].metadata.name}')
# Generate CPU load (this will run in the background)
oc exec -it $POD_NAME -- sh -c "while true; do dd if=/dev/zero of=/dev/null; done" &
Monitor the HPA and deployment to observe scaling behavior:
# Watch HPA scaling
oc get hpa web-hpa -w
# Check deployment replica count
oc get deployment web-deployment
Step 5: Observe Scaling Behavior
After a few minutes, observe how the HPA responds:
# View HPA events
oc describe hpa web-hpa
# Check current replica count
oc get pods -l app=web
# View HPA metrics
oc get hpa web-hpa -o yaml
Note how the replica count changes based on CPU utilization.
Step 6: Stop Load and Observe Scale-Down
Stop the load generation and observe the scale-down behavior:
# Stop the load generation process
oc exec -it $POD_NAME -- pkill dd
# Monitor scale-down
oc get hpa web-hpa -w
oc get deployment web-deployment -w
Observe the stabilization window and scale-down policies in action.
Exercise 2: Vertical Pod Autoscaler
In this exercise, you will create and configure a Vertical Pod Autoscaler (VPA) to automatically adjust CPU and memory requests and limits for containers based on historical usage.
Step 1: Create a Deployment
Create a deployment that will be managed by the VPA:
apiVersion: apps/v1
kind: Deployment
metadata:
name: vpa-deployment
spec:
replicas: 2
selector:
matchLabels:
app: vpa-app
template:
metadata:
labels:
app: vpa-app
spec:
containers:
- name: app
image: nginx:latest
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
Apply the deployment:
oc apply -f vpa-deployment.yaml
oc get deployment vpa-deployment
oc get pods -l app=vpa-app
Step 2: Create a VPA in Recommendation Mode
| Creating a VPA requires administrator privileges because VPA is a cluster-scoped resource, not namespace-scoped. Please ask your instructor to create the VPA for you. |
Create a VPA in "Off" mode to view recommendations without automatic updates:
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: vpa-recommender
do-not-deploy: "true"
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: vpa-deployment
updatePolicy:
updateMode: "Off"
resourcePolicy:
containerPolicies:
- containerName: app
minAllowed:
cpu: 50m
memory: 64Mi
maxAllowed:
cpu: 2
memory: 4Gi
controlledResources: ["cpu", "memory"]
The instructor will apply the VPA. After it’s created, you can view it:
# View the VPA (instructor will create it)
oc get vpa vpa-recommender
Step 3: View VPA Recommendations
After the VPA has collected some usage data, view its recommendations:
# View VPA status
oc get vpa vpa-recommender -o yaml
# Get detailed VPA information
oc describe vpa vpa-recommender
The VPA will show recommendations including:
* Target: Recommended values for optimal performance
* Lower Bound: Minimum values to maintain performance
* Upper Bound: Maximum values observed
Step 4: Generate Load and Monitor
Generate some load on the pods to provide usage data for VPA analysis:
# Get a pod name
POD_NAME=$(oc get pods -l app=vpa-app -o jsonpath='{.items[0].metadata.name}')
# Generate some CPU load
oc exec -it $POD_NAME -- sh -c "for i in {1..100}; do dd if=/dev/zero of=/dev/null bs=1M count=10; done"
Wait a few minutes, then check the VPA recommendations again:
oc describe vpa vpa-recommender
Observe how the recommendations may change based on actual usage patterns.
Step 5: Create VPA in Initial Mode
| This step also requires administrator privileges. Please ask your instructor to create this VPA. |
Create a new VPA in "Initial" mode that sets resource requests only when pods are first created:
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: vpa-initial
do-not-deploy: "true"
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: vpa-deployment
updatePolicy:
updateMode: "Initial"
resourcePolicy:
containerPolicies:
- containerName: app
minAllowed:
cpu: 50m
memory: 64Mi
maxAllowed:
cpu: 2
memory: 4Gi
controlledResources: ["cpu", "memory"]
# The instructor will delete the previous VPA and create the new one
# You can delete and recreate the deployment to see Initial mode in action
oc delete deployment vpa-deployment
oc apply -f vpa-deployment.yaml
Check the new pods to see if VPA has set resource requests:
oc get pods -l app=vpa-app -o yaml | grep -A 10 resources
oc describe pod -l app=vpa-app
Step 6: Compare Resource Settings
Compare the original resource settings with VPA recommendations:
# View VPA recommendations
oc get vpa vpa-initial -o yaml | grep -A 20 recommendation
# View actual pod resource settings
oc get pod -l app=vpa-app -o jsonpath='{.items[0].spec.containers[0].resources}'
Exercise 3: Descheduler Operator
In this exercise, you will examine the Descheduler Operator configuration and understand how descheduling profiles work. Note that creating or modifying the Descheduler requires administrator privileges.
Step 1: View Descheduler Configuration
Check if the Descheduler Operator is installed and view its configuration:
# View Descheduler custom resources (requires admin privileges to create, but you can view)
oc get kubedescheduler -n openshift-kube-descheduler-operator
# View the cluster Descheduler configuration
oc get kubedescheduler cluster -n openshift-kube-descheduler-operator -o yaml
If the Descheduler is configured, you’ll see the active profiles and settings.
Step 2: Examine Descheduler Profiles
View the profiles that are enabled in the Descheduler configuration:
# View enabled profiles
oc get kubedescheduler cluster -n openshift-kube-descheduler-operator -o jsonpath='{.spec.profiles}'
# View full Descheduler spec
oc get kubedescheduler cluster -n openshift-kube-descheduler-operator -o jsonpath='{.spec}' | jq .
Note which profiles are active. The available profiles include:
* AffinityAndTaints
* TopologyAndDuplicates
* SoftTopologyAndDuplicates
* LifecycleAndUtilization
* LongLifecycle
* CompactAndScale
* KubeVirtRelieveAndMigrate
* EvictPodsWithPVC
* EvictPodsWithLocalStorage
Step 3: View Descheduler Settings
Examine the Descheduler configuration settings:
# View descheduling interval
oc get kubedescheduler cluster -n openshift-kube-descheduler-operator -o jsonpath='{.spec.deschedulingIntervalSeconds}'
# View descheduler mode (Predictive or Automatic)
oc get kubedescheduler cluster -n openshift-kube-descheduler-operator -o jsonpath='{.spec.mode}'
# View eviction limits
oc get kubedescheduler cluster -n openshift-kube-descheduler-operator -o jsonpath='{.spec.evictionLimits}'
Step 4: View Descheduler Operator Status
Check the status of the Descheduler Operator:
# View Descheduler Operator deployment
oc get deployment -n openshift-kube-descheduler-operator
# View Descheduler pods
oc get pods -n openshift-kube-descheduler-operator
# View Descheduler Operator logs (if accessible)
oc logs -n openshift-kube-descheduler-operator -l app=descheduler-operator --tail=50
Step 5: Understand Descheduler Behavior
Create a deployment to observe how descheduling might affect it:
apiVersion: apps/v1
kind: Deployment
metadata:
name: descheduler-test
spec:
replicas: 3
selector:
matchLabels:
app: descheduler-test
template:
metadata:
labels:
app: descheduler-test
spec:
containers:
- name: app
image: nginx:latest
resources:
requests:
cpu: 100m
memory: 128Mi
oc apply -f descheduler-test.yaml
oc get pods -l app=descheduler-test -o wide
Monitor the pods to see their distribution across nodes. If the Descheduler is active with certain profiles, it may move pods to optimize cluster balance.
Step 6: Check for Descheduling Events
Look for descheduling-related events:
# View events related to descheduling
oc get events --all-namespaces --field-selector reason=Descheduled
# View recent events for your test deployment
oc get events --field-selector involvedObject.name=descheduler-test
# Watch pod movements
oc get pods -l app=descheduler-test -o wide -w
Note: If the Descheduler is in Predictive mode, it will simulate evictions but not actually move pods. Only Automatic mode performs actual evictions.
Step 7: Example Descheduler Configuration
| Creating or modifying the Descheduler requires administrator privileges. This example shows what a Descheduler configuration might look like: |
apiVersion: operator.openshift.io/v1
kind: KubeDescheduler
metadata:
name: cluster
namespace: openshift-kube-descheduler-operator
do-not-deploy: "true"
spec:
managementState: Managed
deschedulingIntervalSeconds: 3600
profiles:
- AffinityAndTaints
- TopologyAndDuplicates
mode: Automatic
evictionLimits:
total: 10
node: 5
This configuration would:
* Run descheduling every hour (3600 seconds)
* Use the AffinityAndTaints and TopologyAndDuplicates profiles
* Actually evict pods (Automatic mode)
* Limit evictions to 10 total and 5 per node per run