apiVersion: apps/v1 kind: Deployment metadata: name: app labels: app.kubernetes.io/name: app app.kubernetes.io/component: server spec: replicas: 2 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0 selector: matchLabels: app.kubernetes.io/name: app template: metadata: labels: app.kubernetes.io/name: app app.kubernetes.io/component: server spec: # Pod-level security context for PSS restricted compliance securityContext: runAsNonRoot: true seccompProfile: type: RuntimeDefault # Graceful shutdown terminationGracePeriodSeconds: 30 containers: - name: app image: nginx:1.27-alpine imagePullPolicy: IfNotPresent ports: - name: http containerPort: 8080 protocol: TCP # Container-level security context (PSS restricted) securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true runAsNonRoot: true runAsUser: 1000 runAsGroup: 1000 capabilities: drop: - ALL # Resource management - ALWAYS set these resources: requests: cpu: 100m memory: 128Mi limits: cpu: 500m memory: 256Mi # Health probes livenessProbe: httpGet: path: /healthz port: http initialDelaySeconds: 10 periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 3 readinessProbe: httpGet: path: /ready port: http initialDelaySeconds: 5 periodSeconds: 5 timeoutSeconds: 3 failureThreshold: 3 # Startup probe for slow-starting apps startupProbe: httpGet: path: /healthz port: http initialDelaySeconds: 0 periodSeconds: 5 timeoutSeconds: 3 failureThreshold: 30 # 150 seconds max startup # Volume mounts for read-only root filesystem volumeMounts: - name: tmp mountPath: /tmp - name: cache mountPath: /var/cache/nginx - name: run mountPath: /var/run volumes: - name: tmp emptyDir: {} - name: cache emptyDir: {} - name: run emptyDir: {} # Spread pods across nodes topologySpreadConstraints: - maxSkew: 1 topologyKey: kubernetes.io/hostname whenUnsatisfiable: ScheduleAnyway labelSelector: matchLabels: app.kubernetes.io/name: app