Deployment-Konfigurationen in OpenShift definieren deklarative Spezifikationen für Anwendungsbereitstellung und -verwaltung durch strukturierte Metadaten und Konfigurationsparameter. Diese Konfigurationsobjekte abstrahieren komplexe Orchestrierungsdetails und ermöglichen konsistente, reproduzierbare Deployments über verschiedene Umgebungen und Cluster hinweg.
OpenShift Deployment-Konfigurationen implementieren Infrastructure-as-Code-Prinzipien durch YAML- oder JSON-basierte Ressourcendefinitionen, die gewünschte Anwendungszustände beschreiben. Diese deklarative Herangehensweise entkoppelt Deployment-Intent von imperativen Ausführungsschritten und ermöglicht GitOps-Workflows.
[Diagramm: Deployment-Konfigurationshierarchie mit Templates, Kustomize und Environment-Overlays]
Der grundlegende Unterschied zwischen deklarativer und imperativer Konfiguration zeigt sich in der Praxis:
Imperativ (was zu tun ist):
oc create deployment webapp --image=nginx:1.20
oc scale deployment webapp --replicas=3
oc expose deployment webapp --port=80Deklarativ (was erreicht werden soll):
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp
spec:
replicas: 3
selector:
matchLabels:
app: webapp
template:
metadata:
labels:
app: webapp
spec:
containers:
- name: webapp
image: nginx:1.20
ports:
- containerPort: 80Template-basierte Konfigurationen ermöglichen Parametrisierung wiederkehrender Deployment-Patterns durch variable Substitution. Diese Abstraktionsebene unterstützt umgebungsspezifische Anpassungen ohne Duplikation von Basis-Konfigurationen.
apiVersion: template.openshift.io/v1
kind: Template
metadata:
name: webapp-template
parameters:
- name: APP_NAME
description: "Name der Anwendung"
required: true
- name: IMAGE_TAG
description: "Container Image Tag"
value: "latest"
- name: REPLICAS
description: "Anzahl der Pod-Replicas"
value: "2"
objects:
- apiVersion: apps/v1
kind: Deployment
metadata:
name: ${APP_NAME}
spec:
replicas: ${{REPLICAS}}
selector:
matchLabels:
app: ${APP_NAME}
template:
metadata:
labels:
app: ${APP_NAME}
spec:
containers:
- name: ${APP_NAME}
image: nginx:${IMAGE_TAG}Template verwenden:
# Template mit Parametern instanziieren
oc process -f webapp-template.yaml \
-p APP_NAME=frontend \
-p IMAGE_TAG=1.20 \
-p REPLICAS=3 | oc apply -f -Kustomize erweitert native Kubernetes-Konfigurationsmanagement um Overlay-Mechanismen für umgebungsspezifische Modifikationen:
# base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
commonLabels:
app: webapp
---
# overlays/production/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
replicas:
- name: webapp
count: 5
images:
- name: nginx
newTag: 1.20-alpine
patchesStrategicMerge:
- production-resources.yamlContainer-Definitionen spezifizieren Image-References, Resource-Requirements und Environment-Variablen für individuelle Container innerhalb von Pod-Templates. Diese granularen Konfigurationen ermöglichen optimale Ressourcenallokation und Anwendungstuning.
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: webapp
image: nginx:1.20
# Port-Exposition
ports:
- name: http
containerPort: 80
protocol: TCP
- name: metrics
containerPort: 9090
protocol: TCP
# Ressourcen-Management
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "512Mi"
# Environment-Variablen
env:
- name: NODE_ENV
value: "production"
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: db-credentials
key: url
# Volume-Mounts
volumeMounts:
- name: config-volume
mountPath: /etc/nginx/conf.d
- name: data-volume
mountPath: /var/www/htmlInit Container definieren Vorbereitungsschritte für Hauptcontainer-Start:
spec:
template:
spec:
initContainers:
# Database Migration Init Container
- name: db-migration
image: webapp:latest
command: ['npm', 'run', 'migrate']
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: db-credentials
key: url
# File Download Init Container
- name: file-downloader
image: busybox
command: ['wget', '-O', '/shared/config.json', 'https://api.company.com/config']
volumeMounts:
- name: shared-data
mountPath: /shared
# Hauptcontainer starten erst nach Init Container
containers:
- name: webapp
image: webapp:latest
volumeMounts:
- name: shared-data
mountPath: /app/configSidecar-Container-Pattern werden über Multi-Container-Pod-Spezifikationen implementiert:
spec:
template:
spec:
containers:
# Hauptanwendung
- name: webapp
image: webapp:latest
ports:
- containerPort: 8080
volumeMounts:
- name: logs
mountPath: /var/log/app
# Logging Sidecar
- name: log-shipper
image: fluentd:latest
volumeMounts:
- name: logs
mountPath: /var/log/app
readOnly: true
env:
- name: LOG_OUTPUT
value: "elasticsearch:9200"
# Monitoring Sidecar
- name: metrics-exporter
image: prometheus/node-exporter:latest
ports:
- containerPort: 9100
name: metrics
volumes:
- name: logs
emptyDir: {}Service Account-Zuweisungen definieren Identity-Context für Pod-Ausführung und ermöglichen RBAC-basierte Zugriffskontrolle auf Cluster-Ressourcen.
# Service Account definieren
apiVersion: v1
kind: ServiceAccount
metadata:
name: webapp-sa
imagePullSecrets:
- name: private-registry
secrets:
- name: webapp-secrets
---
# In Deployment verwenden
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
serviceAccountName: webapp-sa
containers:
- name: webapp
image: private-registry.company.com/webapp:latestSecurity Context Constraints (SCC) spezifizieren Sicherheitsrichtlinien für Container-Ausführung:
spec:
template:
spec:
# Pod-weite Security-Einstellungen
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
supplementalGroups: [4000]
seLinuxOptions:
level: "s0:c123,c456"
containers:
- name: webapp
# Container-spezifische Security-Einstellungen
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE # Für Port < 1024
volumeMounts:
- name: tmp-volume
mountPath: /tmp
- name: var-cache
mountPath: /var/cache
volumes:
- name: tmp-volume
emptyDir: {}
- name: var-cache
emptyDir: {}# Namespace mit Pod Security Standard
apiVersion: v1
kind: Namespace
metadata:
name: secure-app
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restrictedConfigMap- und Secret-Integration externalisiert Konfigurationsdaten und sensitive Informationen von Container-Images. Diese Separation ermöglicht identische Container-Images über verschiedene Umgebungen mit umgebungsspezifischen Konfigurationen.
spec:
template:
spec:
containers:
- name: webapp
# Einzelne Environment-Variablen aus ConfigMap
env:
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: app-config
key: log_level
# Alle Keys aus ConfigMap als Environment-Variablen
envFrom:
- configMapRef:
name: app-config
# ConfigMap als Volume mounten
volumeMounts:
- name: config-files
mountPath: /etc/config
volumes:
- name: config-files
configMap:
name: app-config
items:
- key: nginx.conf
path: nginx.conf
- key: app.properties
path: application.propertiesProjected Volume-Konfigurationen aggregieren mehrere Konfigurationsquellen:
volumes:
- name: combined-config
projected:
sources:
# ConfigMap-Quelle
- configMap:
name: app-config
items:
- key: config.yaml
path: config/app.yaml
# Secret-Quelle
- secret:
name: app-secrets
items:
- key: database-password
path: secrets/db-password
# Downward API (Pod-Metadaten)
- downwardAPI:
items:
- path: labels/pod-labels
fieldRef:
fieldPath: metadata.labels
- path: cpu-limit
resourceFieldRef:
resource: limits.cpuDownward API ermöglicht Pod-Metadaten-Exposition als Environment-Variablen oder Files:
containers:
- name: webapp
env:
# Pod-Informationen als Environment-Variablen
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
# Resource-Informationen
- name: CPU_LIMIT
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: MEMORY_REQUEST
valueFrom:
resourceFieldRef:
resource: requests.memoryProbe-Konfigurationen sind essentiell für zuverlässige Anwendungsbereitstellung und automatisierte Fehlerbehebung.
containers:
- name: webapp
# Startup Probe (für langsam startende Apps)
startupProbe:
httpGet:
path: /health/startup
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 12 # Max 60 Sekunden Startup-Zeit
successThreshold: 1
# Readiness Probe (Traffic-Ready?)
readinessProbe:
httpGet:
path: /health/ready
port: 8080
httpHeaders:
- name: Accept
value: application/json
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 2
failureThreshold: 3
successThreshold: 1
# Liveness Probe (Container healthy?)
livenessProbe:
httpGet:
path: /health/live
port: 8080
initialDelaySeconds: 30
periodSeconds: 20
timeoutSeconds: 5
failureThreshold: 3
successThreshold: 1HTTP Probe:
livenessProbe:
httpGet:
path: /healthz
port: 8080
scheme: HTTPS # Für TLS-EndpointsTCP Probe:
readinessProbe:
tcpSocket:
port: 5432 # Für Datenbank-ConnectivityCommand Probe:
livenessProbe:
exec:
command:
- cat
- /tmp/healthyResource Request-Spezifikationen definieren minimale CPU- und Memory-Anforderungen für Container-Scheduling und gewährleisten angemessene Ressourcenallokation.
containers:
- name: webapp
resources:
requests:
cpu: "100m" # 0.1 CPU-Kerne
memory: "128Mi" # 128 MiB Memory
ephemeral-storage: "1Gi" # Lokaler Storage
limits:
cpu: "1" # Max 1 CPU-Kern
memory: "1Gi" # Max 1 GiB Memory
ephemeral-storage: "2Gi" # Max lokaler StorageNode Affinity-Rules definieren bevorzugte oder erforderliche Node-Charakteristika:
spec:
template:
spec:
# Node Affinity
affinity:
nodeAffinity:
# Harte Anforderung
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/arch
operator: In
values: ["amd64"]
- key: node.kubernetes.io/instance-type
operator: NotIn
values: ["t2.micro", "t3.nano"]
# Weiche Präferenz
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 80
preference:
matchExpressions:
- key: zone
operator: In
values: ["us-east-1a"]
# Pod Anti-Affinity (Pods verteilen)
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values: ["webapp"]
topologyKey: kubernetes.io/hostname
# Tolerations für Taints
tolerations:
- key: "dedicated"
operator: "Equal"
value: "webapp"
effect: "NoSchedule"PostStart und PreStop Hook-Konfigurationen ermöglichen Anwendungscode-Ausführung bei Container-Lifecycle-Events.
containers:
- name: webapp
lifecycle:
# Nach Container-Start
postStart:
exec:
command:
- /bin/sh
- -c
- |
echo "Container started at $(date)" >> /var/log/lifecycle.log
# Warm-up requests
sleep 10
curl -s http://localhost:8080/warmup
# Vor Container-Stop
preStop:
httpGet:
path: /shutdown
port: 8080
scheme: HTTP
# Alternative: Command-basiert
# exec:
# command:
# - /bin/sh
# - -c
# - nginx -s quit; sleep 15
# Termination Grace Period
terminationGracePeriodSeconds: 60 # Max 60s für graceful shutdownRolling Update-Parameter kontrollieren Update-Geschwindigkeit und Verfügbarkeits-Requirements:
apiVersion: apps/v1
kind: Deployment
spec:
# Update-Strategie
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1 # Max 1 Pod gleichzeitig unavailable
maxSurge: 2 # Max 2 zusätzliche Pods während Update
# Revision-Historie
revisionHistoryLimit: 10 # 10 alte ReplicaSets für Rollback behalten
# Update-Fortschritt
progressDeadlineSeconds: 600 # Max 10 Minuten für Update
template:
# Pod-Template wie gewohntspec:
strategy:
type: Recreate # Alle Pods stoppen, dann neue starten
# Geeignet für:
# - Single-Instance-Anwendungen
# - Persistent Volumes mit ReadWriteOnce
# - Anwendungen die keine parallelen Instanzen unterstützenmetadata:
name: webapp
annotations:
deployment.kubernetes.io/revision: "3"
kubernetes.io/change-cause: "Update to nginx 1.20 with security fixes"
app.company.com/version: "v2.1.0"
app.company.com/owner: "team-frontend"
app.company.com/cost-center: "engineering"
labels:
app: webapp
tier: frontend
environment: production
version: v2.1.0# Blue Deployment (current)
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp-blue
labels:
app: webapp
version: blue
spec:
replicas: 3
selector:
matchLabels:
app: webapp
version: blue
---
# Green Deployment (new)
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp-green
labels:
app: webapp
version: green
spec:
replicas: 3
selector:
matchLabels:
app: webapp
version: green
---
# Service (switch between blue/green)
apiVersion: v1
kind: Service
metadata:
name: webapp-service
spec:
selector:
app: webapp
version: blue # Switch to 'green' for cutover# Stable Deployment (90% Traffic)
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp-stable
spec:
replicas: 9 # 90% der gewünschten Kapazität
---
# Canary Deployment (10% Traffic)
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp-canary
spec:
replicas: 1 # 10% der gewünschten Kapazität
template:
metadata:
labels:
version: canary
spec:
containers:
- name: webapp
image: webapp:v2.0.0 # Neue Version# Deployment-Status anzeigen
oc get deployment webapp -o wide
# Rollout-Status verfolgen
oc rollout status deployment/webapp
# Deployment-Details inspizieren
oc describe deployment webapp
# Pod-Status und Events
oc get pods -l app=webapp
oc describe pod webapp-xyzImage Pull-Fehler:
# Pod-Events prüfen
oc describe pod webapp-xyz | grep -A 10 Events
# Pull Secrets validieren
oc get secret private-registry -o yaml
oc get sa default -o yaml | grep imagePullSecretsResource-Probleme:
# Resource-Quotas prüfen
oc describe resourcequota
# Node-Kapazität prüfen
oc describe nodes | grep -A 5 "Allocated resources"
# Pod-Resource-Requests/-Limits validieren
oc get pods -o custom-columns=NAME:.metadata.name,CPU-REQ:.spec.containers[0].resources.requests.cpu,MEM-REQ:.spec.containers[0].resources.requests.memoryProbe-Probleme:
# Probe-Failures in Pod-Events suchen
oc describe pod webapp-xyz | grep -i probe
# Health-Endpoints manuell testen
oc port-forward pod/webapp-xyz 8080:8080
curl http://localhost:8080/health# YAML-Syntax validieren
oc apply --dry-run=client -f deployment.yaml
# Server-side Validation
oc apply --dry-run=server -f deployment.yaml
# Konfiguration gegen Policies prüfen
oc auth can-i create deployments --as=system:serviceaccount:myproject:webapp-sa