Exercise 2: Resource Management
Task 1 - Understanding Resource Requests and Limits
Properly setting resource requests and limits is essential for optimal cluster performance. Let’s see how to optimize resource usage:
Create a namespace for a QoS (Quality of Service) demonstration:
kubectl create namespace qos-demokubectl create namespace qos-demoCreate a Guaranteed QoS pod (equal
requests andlimits):$guaranteedPodYaml = @" apiVersion: v1 kind: Pod metadata: name: guaranteed-pod namespace: qos-demo spec: containers: - name: nginx image: k8sonazureworkshoppublic.azurecr.io/nginx resources: requests: memory: "100Mi" cpu: "100m" limits: memory: "100Mi" cpu: "100m" "@ $guaranteedPodYaml | kubectl apply -f -cat << EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: guaranteed-pod namespace: qos-demo spec: containers: - name: nginx image: k8sonazureworkshoppublic.azurecr.io/nginx resources: requests: memory: "100Mi" cpu: "100m" limits: memory: "100Mi" cpu: "100m" EOFCreate a Burstable QoS pod (
requests less thanlimits):$burstablePodYaml = @" apiVersion: v1 kind: Pod metadata: name: burstable-pod namespace: qos-demo spec: containers: - name: nginx image: k8sonazureworkshoppublic.azurecr.io/nginx resources: requests: memory: "50Mi" cpu: "50m" limits: memory: "100Mi" cpu: "100m" "@ $burstablePodYaml | kubectl apply -f -cat << EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: burstable-pod namespace: qos-demo spec: containers: - name: nginx image: k8sonazureworkshoppublic.azurecr.io/nginx resources: requests: memory: "50Mi" cpu: "50m" limits: memory: "100Mi" cpu: "100m" EOFCreate a BestEffort QoS pod (no
requests orlimits):$bestEffortPodYaml = @" apiVersion: v1 kind: Pod metadata: name: besteffort-pod namespace: qos-demo spec: containers: - name: nginx image: k8sonazureworkshoppublic.azurecr.io/nginx "@ $bestEffortPodYaml | kubectl apply -f -cat << EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: besteffort-pod namespace: qos-demo spec: containers: - name: nginx image: k8sonazureworkshoppublic.azurecr.io/nginx EOFCheck the QoS class of each pod:
kubectl get pods -n qos-demo -o custom-columns="NAME:.metadata.name,QOS:.status.qosClass"kubectl get pods -n qos-demo -o custom-columns="NAME:.metadata.name,QOS:.status.qosClass"You should see
Guaranteed,Burstable, andBestEffortrespectively.When the cluster is under resource pressure, Kubernetes will evict pods in this order:
BestEffort,Burstable, and finallyGuaranteed. This is important to understand when planning workload priorities.
Task 2 - Monitor Resource Usage
Check current resource usage for your pods:
kubectl top pods -n qos-demokubectl top pods -n qos-demoTip
If you receive a message stating
error: metrics not available yet, you may need to wait a few moments for metrics to be collected.The
topcommand shows the actual resources in use by each pod, rather than the requested or limited resources.Check node resource usage:
kubectl top nodeskubectl top nodes
Task 3 - Create Namespace with Resource Quotas
Create a new namespace for testing resource quotas:
kubectl create namespace limited-resourceskubectl create namespace limited-resourcesCreate a ResourceQuota in this namespace:
$quota = @" apiVersion: v1 kind: ResourceQuota metadata: name: mem-cpu-quota namespace: limited-resources spec: hard: requests.cpu: "1" requests.memory: 1Gi limits.cpu: "2" limits.memory: 2Gi pods: "5" "@ $quota | kubectl apply -f -cat << EOF | kubectl apply -f - apiVersion: v1 kind: ResourceQuota metadata: name: mem-cpu-quota namespace: limited-resources spec: hard: requests.cpu: "1" requests.memory: 1Gi limits.cpu: "2" limits.memory: 2Gi pods: "5" EOFVerify the ResourceQuota:
kubectl describe resourcequota -n limited-resourceskubectl describe resourcequota -n limited-resources
Task 4 - Test Resource Quota Enforcement
Create a deployment that uses a lot of the memory quota:
$deployment1 = @" apiVersion: apps/v1 kind: Deployment metadata: name: memory-demo namespace: limited-resources spec: replicas: 1 selector: matchLabels: app: memory-demo template: metadata: labels: app: memory-demo spec: containers: - name: memory-demo image: k8sonazureworkshoppublic.azurecr.io/nginx resources: requests: memory: "800Mi" cpu: "500m" limits: memory: "1.5Gi" cpu: "1" "@ $deployment1 | kubectl apply -f -cat << EOF | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: name: memory-demo namespace: limited-resources spec: replicas: 1 selector: matchLabels: app: memory-demo template: metadata: labels: app: memory-demo spec: containers: - name: memory-demo image: k8sonazureworkshoppublic.azurecr.io/nginx resources: requests: memory: "800Mi" cpu: "500m" limits: memory: "1.5Gi" cpu: "1" EOFTry to create a second deployment that would exceed the quota:
$deployment2 = @" apiVersion: apps/v1 kind: Deployment metadata: name: memory-demo2 namespace: limited-resources spec: replicas: 1 selector: matchLabels: app: memory-demo2 template: metadata: labels: app: memory-demo2 spec: containers: - name: memory-demo2 image: k8sonazureworkshoppublic.azurecr.io/nginx resources: requests: memory: "800Mi" cpu: "500m" limits: memory: "1.5Gi" cpu: "1" "@ $deployment2 | kubectl apply -f -cat << EOF | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: name: memory-demo2 namespace: limited-resources spec: replicas: 1 selector: matchLabels: app: memory-demo2 template: metadata: labels: app: memory-demo2 spec: containers: - name: memory-demo2 image: k8sonazureworkshoppublic.azurecr.io/nginx resources: requests: memory: "800Mi" cpu: "500m" limits: memory: "1.5Gi" cpu: "1" EOFObserve the error message indicating the quota has been exceeded by reviewing the replicaset:
kubectl describe rs -l "app=memory-demo2" -n limited-resourceskubectl describe rs -l "app=memory-demo2" -n limited-resourcesCheck the current quota usage:
kubectl describe resourcequota -n limited-resourceskubectl describe resourcequota -n limited-resources
Task 5 - LimitRange for Default Values
Create a LimitRange to set default resource
limits andrequests:$limitRange = @" apiVersion: v1 kind: LimitRange metadata: name: default-limits namespace: limited-resources spec: limits: - default: cpu: "500m" memory: "256Mi" defaultRequest: cpu: "100m" memory: "128Mi" type: Container "@ $limitRange | kubectl apply -f -cat << EOF | kubectl apply -f - apiVersion: v1 kind: LimitRange metadata: name: default-limits namespace: limited-resources spec: limits: - default: cpu: "500m" memory: "256Mi" defaultRequest: cpu: "100m" memory: "128Mi" type: Container EOFCreate a pod without specifying resources:
$defaultPod = @" apiVersion: v1 kind: Pod metadata: name: default-resources-pod namespace: limited-resources spec: containers: - name: default-resources image: k8sonazureworkshoppublic.azurecr.io/nginx "@ $defaultPod | kubectl apply -f -cat << EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: default-resources-pod namespace: limited-resources spec: containers: - name: default-resources image: k8sonazureworkshoppublic.azurecr.io/nginx EOFCheck that default resources were applied:
kubectl get pod default-resources-pod -n limited-resources -o jsonpath='{.spec.containers[0].resources}' | ConvertFrom-Jsonkubectl get pod default-resources-pod -n limited-resources \ -o jsonpath='Requests: cpu={.spec.containers[0].resources.requests.cpu}, memory={.spec.containers[0].resources.requests.memory}{"\n"}Limits: cpu={.spec.containers[0].resources.limits.cpu}, memory={.spec.containers[0].resources.limits.memory}{"\n"}'Look for the “Requests” and “Limits” sections to confirm the LimitRange defaults were applied.
Task 6 - Cleanup
Delete the namespace and all resources created in this exercise:
kubectl delete namespace limited-resources kubectl delete resourcequota mem-cpu-quota -n limited-resources kubectl delete limitrange default-limits -n limited-resources kubectl delete pod default-resources-pod -n limited-resources kubectl delete ns qos-demokubectl delete namespace limited-resources kubectl delete resourcequota mem-cpu-quota -n limited-resources kubectl delete limitrange default-limits -n limited-resources kubectl delete pod default-resources-pod -n limited-resources kubectl delete ns qos-demo