Ressourcen-Management in OpenShift implementiert mehrstufige Kontrollmechanismen für Compute-, Storage- und API-Ressourcennutzung durch Resource Quotas, Limit Ranges und Pod-spezifische Resource Specifications. Diese Governance-Frameworks gewährleisten faire Ressourcenverteilung, verhindern Resource Starvation und unterstützen Multi-Tenancy in geteilten Cluster-Umgebungen.
Ohne Ressourcenkontrolle können einzelne Anwendungen oder Teams unverhältnismäßig viele Cluster-Ressourcen konsumieren und dadurch andere Workloads beeinträchtigen. Dies führt zu Performance-Problemen, unvorhersagbaren Kosten und potentieller Cluster-Instabilität.
[Diagramm: Ressourcen-Management-Hierarchie mit Quotas, Limit Ranges und Pod-Limits]
OpenShift löst diese Herausforderungen durch ein dreistufiges Ressourcen-Management-System:
Resource Quotas definieren aggregierte Ressourcenlimits auf Projekt-Ebene und beschränken Gesamtverbrauch von CPU, Memory, Storage und Kubernetes-API-Objekten. Diese Makro-Level-Kontrollen implementieren Governance-Richtlinien und verhindern einzelne Projekte daran, unverhältnismäßige Cluster-Ressourcen zu konsumieren.
Compute Resource Quotas beschränken CPU- und Memory-Nutzung über alle Pods innerhalb eines Projekts:
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: production
spec:
hard:
# CPU-Limits
requests.cpu: "10" # Gesamt-CPU-Requests: 10 Kerne
limits.cpu: "20" # Gesamt-CPU-Limits: 20 Kerne
# Memory-Limits
requests.memory: 20Gi # Gesamt-Memory-Requests: 20 GB
limits.memory: 40Gi # Gesamt-Memory-Limits: 40 GB
# Pod-Anzahl
pods: "50" # Maximum 50 Pods im ProjektStorage Quotas kontrollieren persistente Speichernutzung über requests.storage und spezifische Storage Class-Quotas:
apiVersion: v1
kind: ResourceQuota
metadata:
name: storage-quota
spec:
hard:
# Gesamter Storage
requests.storage: 100Gi
# Anzahl Persistent Volume Claims
persistentvolumeclaims: "10"
# Storage-Class-spezifische Quotas
fast-ssd.storageclass.storage.k8s.io/requests.storage: 50Gi
slow-hdd.storageclass.storage.k8s.io/requests.storage: 200GiAPI Object Quotas begrenzen die Anzahl verschiedener Kubernetes-Ressourcen:
apiVersion: v1
kind: ResourceQuota
metadata:
name: object-quota
spec:
hard:
# Kubernetes-Objekte
services: "20"
secrets: "50"
configmaps: "30"
deployments.apps: "15"
replicasets.apps: "20"
# OpenShift-spezifische Objekte
routes.route.openshift.io: "10"
buildconfigs.build.openshift.io: "5"Scoped Quotas ermöglichen differentierte Limits für verschiedene Priority Classes oder Quality of Service-Kategorien:
apiVersion: v1
kind: ResourceQuota
metadata:
name: priority-quota
spec:
hard:
requests.cpu: "5"
limits.memory: 10Gi
scopes:
- PriorityClass
scopeSelector:
matchExpressions:
- operator: In
scopeName: PriorityClass
values: ["high-priority"]# Quota-Usage anzeigen
oc get resourcequota -n production
oc describe resourcequota compute-quota -n production
# Output-Beispiel:
# Name: compute-quota
# Resource Used Hard
# -------- ---- ----
# limits.cpu 15 20
# limits.memory 30Gi 40Gi
# requests.cpu 8 10
# requests.memory 16Gi 20GiLimit Ranges spezifizieren Default-Werte und Constraints für individuelle Ressourcen-Requests und -Limits innerhalb eines Namespaces. Diese Mikro-Level-Kontrollen gewährleisten konsistente Ressourcen-Spezifikationen und verhindern sowohl Über- als auch Unter-Dimensionierung.
apiVersion: v1
kind: LimitRange
metadata:
name: container-limits
spec:
limits:
- type: Container
# Default-Werte für Container ohne Resource-Specs
default:
cpu: "500m" # 0.5 CPU-Kern
memory: "512Mi" # 512 MiB Memory
# Default-Requests wenn nur Limits angegeben
defaultRequest:
cpu: "100m" # 0.1 CPU-Kern
memory: "128Mi" # 128 MiB Memory
# Minimum erlaubte Werte
min:
cpu: "50m" # Mindestens 0.05 CPU-Kern
memory: "64Mi" # Mindestens 64 MiB Memory
# Maximum erlaubte Werte
max:
cpu: "4" # Höchstens 4 CPU-Kerne
memory: "8Gi" # Höchstens 8 GiB MemoryapiVersion: v1
kind: LimitRange
metadata:
name: pod-limits
spec:
limits:
- type: Pod
# Gesamt-Limits pro Pod (alle Container zusammen)
max:
cpu: "8"
memory: "16Gi"
min:
cpu: "100m"
memory: "128Mi"apiVersion: v1
kind: LimitRange
metadata:
name: pvc-limits
spec:
limits:
- type: PersistentVolumeClaim
max:
storage: 100Gi # Maximum 100GB pro PVC
min:
storage: 1Gi # Minimum 1GB pro PVCapiVersion: v1
kind: LimitRange
metadata:
name: ratio-limits
spec:
limits:
- type: Container
maxLimitRequestRatio:
cpu: "4" # Limit darf maximal 4x Request sein
memory: "2" # Limit darf maximal 2x Request sein
default:
cpu: "1"
memory: "1Gi"
defaultRequest:
cpu: "250m" # Ratio 4:1 (1000m:250m)
memory: "512Mi" # Ratio 2:1 (1Gi:512Mi)Pod-spezifische Resource Requests und Limits definieren individuelle Container-Ressourcenanforderungen und bilden die Grundlage für Scheduler-Entscheidungen und Runtime-Enforcement. Die QoS-Klasse ergibt sich automatisch aus den Resource-Spezifikationen.
| QoS-Klasse | Bedingung | Eigenschaften | Eviction-Priorität |
|---|---|---|---|
| Guaranteed | Requests = Limits für alle Container | Reservierte Ressourcen, vorhersagbare Performance | Niedrigste (zuletzt evicted) |
| Burstable | Requests < Limits oder nur Requests definiert | Kann über Request hinaus nutzen | Mittlere |
| BestEffort | Keine Requests/Limits definiert | Nutzt verfügbare Ressourcen | Höchste (zuerst evicted) |
apiVersion: v1
kind: Pod
spec:
containers:
- name: webapp
resources:
requests:
cpu: "1" # = limits
memory: "2Gi" # = limits
limits:
cpu: "1" # = requests
memory: "2Gi" # = requests
# QoS-Klasse: GuaranteedapiVersion: v1
kind: Pod
spec:
containers:
- name: webapp
resources:
requests:
cpu: "500m" # < limits
memory: "1Gi" # < limits
limits:
cpu: "2" # > requests
memory: "4Gi" # > requests
# QoS-Klasse: BurstableapiVersion: v1
kind: Pod
spec:
containers:
- name: webapp
# Keine resources definiert
# QoS-Klasse: BestEffort# Pod-Details mit QoS-Klasse
oc get pod webapp-xyz -o yaml | grep qosClass
# Output: qosClass: Burstable
oc describe pod webapp-xyz | grep "QoS Class"
# Output: QoS Class: BurstableCPU-Werte können in verschiedenen Einheiten angegeben werden:
resources:
requests:
cpu: "1" # 1 CPU-Kern
cpu: "1000m" # 1000 Millicores = 1 CPU-Kern
cpu: "500m" # 0.5 CPU-Kern
cpu: "100m" # 0.1 CPU-Kern (typisch für Sidecar)
limits:
cpu: "2" # Maximum 2 CPU-KerneMemory wird in Bytes oder binären Einheiten angegeben:
resources:
requests:
memory: "128Mi" # 128 Mebibytes (134,217,728 Bytes)
memory: "1Gi" # 1 Gibibyte (1,073,741,824 Bytes)
memory: "500M" # 500 Megabytes (500,000,000 Bytes)
limits:
memory: "2Gi" # Maximum 2 GibibyteMicroservice (Small):
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "512Mi"Web Application (Medium):
resources:
requests:
cpu: "500m"
memory: "1Gi"
limits:
cpu: "2"
memory: "4Gi"Database/Cache (Large):
resources:
requests:
cpu: "2"
memory: "8Gi"
limits:
cpu: "4"
memory: "16Gi"# Pod-Resource-Verbrauch anzeigen
oc adm top pods -n production
# Node-Resource-Verbrauch
oc adm top nodes
# Detaillierte Resource-Metriken
oc get --raw /api/v1/nodes/$(oc get nodes -o name | head -1 | cut -d'/' -f2)/proxy/stats/summary# Quota-Status prüfen
oc describe resourcequota -n production
# Events für Quota-Verletzungen
oc get events --field-selector reason=FailedCreate -n production
# Pod-Events bei Resource-Problemen
oc describe pod failing-pod-namePod bleibt in Pending-Status:
# Scheduler-Probleme prüfen
oc describe pod pending-pod
# Typische Gründe:
# - Insufficient CPU/Memory auf Nodes
# - Resource Quotas ausgeschöpft
# - Node Affinity/Anti-Affinity nicht erfüllbarOOMKilled (Out of Memory):
# Pod-Events prüfen
oc describe pod oomkilled-pod
# Memory-Limits erhöhen oder Memory-Leaks beheben
spec:
containers:
- name: webapp
resources:
limits:
memory: "2Gi" # Von 1Gi erhöhtResource Quota exceeded:
# Quota-Usage analysieren
oc describe resourcequota compute-quota
# Optionen:
# 1. Quota erhöhen
# 2. Ineffiziente Pods optimieren
# 3. Unused Deployments löschenHPA berücksichtigt Resource Quotas bei Skalierungsentscheidungen:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: webapp-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: webapp
minReplicas: 2
maxReplicas: 10 # Begrenzt durch Resource Quota
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70VPA respektiert Limit Range-Constraints bei Ressourcenempfehlungen:
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: webapp-vpa
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: webapp
updatePolicy:
updateMode: "Auto"
resourcePolicy:
containerPolicies:
- containerName: webapp
maxAllowed:
cpu: "4" # Respektiert Limit Range max
memory: "8Gi"
minAllowed:
cpu: "100m" # Respektiert Limit Range min
memory: "128Mi"# Development-Projekt (kleine Quotas)
apiVersion: v1
kind: ResourceQuota
metadata:
name: dev-quota
namespace: webapp-dev
spec:
hard:
requests.cpu: "2"
requests.memory: 4Gi
pods: "20"
---
# Production-Projekt (größere Quotas)
apiVersion: v1
kind: ResourceQuota
metadata:
name: prod-quota
namespace: webapp-prod
spec:
hard:
requests.cpu: "20"
requests.memory: 40Gi
pods: "100"apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority
value: 1000
globalDefault: false
description: "High priority workloads"
---
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: low-priority
value: 100
description: "Low priority batch jobs"Pod mit Priority Class:
apiVersion: v1
kind: Pod
spec:
priorityClassName: high-priority
containers:
- name: critical-app
# Container-Spec# Top-Ressourcenverbraucher identifizieren
oc adm top pods --sort-by=cpu -n production
oc adm top pods --sort-by=memory -n production
# Unused Resources identifizieren
oc get deployments -o custom-columns=NAME:.metadata.name,REPLICAS:.spec.replicas,CPU-REQ:.spec.template.spec.containers[0].resources.requests.cpu,MEM-REQ:.spec.template.spec.containers[0].resources.requests.memoryÜber-dimensionierte Pods identifizieren:
# Pods mit hohen Limits aber niedriger Nutzung
oc adm top pods --containers -n production
# VPA-Recommendations nutzen
oc get vpa webapp-vpa -o yamlUnter-dimensionierte Pods identifizieren:
# Pods mit häufigen Restarts (OOMKilled)
oc get pods -o custom-columns=NAME:.metadata.name,RESTARTS:.status.containerStatuses[0].restartCount --sort-by='.status.containerStatuses[0].restartCount'
# Memory-Usage vs. Limits
oc adm top pods --containersShowback-Metriken sammeln:
# Resource-Requests pro Projekt
oc get resourcequota --all-namespaces -o custom-columns=NAMESPACE:.metadata.namespace,CPU-REQ:.status.used.requests\\.cpu,MEM-REQ:.status.used.requests\\.memory
# Pod-Anzahl und Resource-Verbrauch
for ns in $(oc get namespaces -o name | cut -d'/' -f2); do
echo "=== $ns ==="
oc get pods -n $ns --no-headers | wc -l
oc adm top pods -n $ns --no-headers 2>/dev/null | awk '{cpu+=$2; mem+=$3} END {print "CPU:", cpu "m", "Memory:", mem "Mi"}'
doneStart Small, Scale Up: - Beginnen Sie mit konservativen Requests/Limits - Nutzen Sie Monitoring zur Optimierung - Verwenden Sie VPA für Recommendations
Requests vs. Limits:
# Empfohlenes Verhältnis für Web-Apps
resources:
requests:
cpu: "500m" # Guaranteed baseline
memory: "1Gi" # Guaranteed baseline
limits:
cpu: "2" # 4x Request für Burst-Kapazität
memory: "2Gi" # 2x Request für Memory-SpitzenHierarchische Quotas: - Entwicklung: 20% der Cluster-Ressourcen - Staging: 20% der Cluster-Ressourcen - Production: 60% der Cluster-Ressourcen
Resource-Pufferung: - Quotas auf 80% der verfügbaren Node-Kapazität setzen - 20% Reserve für System-Workloads und Overhead
Wichtige Metriken überwachen: - Resource Quota Utilization (80%+ = Warnung) - Pod Restart Rate (OOMKilled-Events) - Node Resource Utilization - HPA/VPA Scaling-Events
Alerting-Regeln:
# Prometheus Alert-Beispiel
- alert: ResourceQuotaHighUtilization
expr: (kube_resourcequota{resource="requests.memory"} / kube_resourcequota{resource="limits.memory"}) > 0.8
labels:
severity: warning
annotations:
summary: "Resource quota {{ $labels.namespace }} is {{ $value | humanizePercentage }} utilized"