# Production-Ready Kubernetes Deployment Template # Replace all with actual values apiVersion: apps/v1 kind: Deployment metadata: name: namespace: labels: app.kubernetes.io/name: app.kubernetes.io/instance: app.kubernetes.io/version: "" app.kubernetes.io/component: # backend, frontend, database, cache app.kubernetes.io/part-of: app.kubernetes.io/managed-by: kubectl annotations: description: "" contact: "" spec: replicas: 3 # Minimum 3 for production HA revisionHistoryLimit: 10 selector: matchLabels: app.kubernetes.io/name: app.kubernetes.io/instance: strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0 # Zero-downtime deployment minReadySeconds: 10 progressDeadlineSeconds: 600 template: metadata: labels: app.kubernetes.io/name: app.kubernetes.io/instance: app.kubernetes.io/version: "" annotations: prometheus.io/scrape: "true" prometheus.io/port: "9090" prometheus.io/path: "/metrics" spec: serviceAccountName: # Pod-level security context securityContext: runAsNonRoot: true runAsUser: 1000 runAsGroup: 1000 fsGroup: 1000 seccompProfile: type: RuntimeDefault # Init containers (optional) initContainers: - name: init-wait image: busybox:1.36 command: ['sh', '-c', 'echo "Initializing..."'] securityContext: allowPrivilegeEscalation: false runAsNonRoot: true runAsUser: 1000 containers: - name: image: /: # Never use :latest imagePullPolicy: IfNotPresent ports: - name: http containerPort: 8080 protocol: TCP - name: metrics containerPort: 9090 protocol: TCP # Environment variables env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: POD_IP valueFrom: fieldRef: fieldPath: status.podIP # Load from ConfigMap and Secret envFrom: - configMapRef: name: -config - secretRef: name: -secret # Resource limits resources: requests: memory: "256Mi" cpu: "250m" limits: memory: "512Mi" cpu: "500m" # Startup probe (for slow-starting apps) startupProbe: httpGet: path: /health/startup port: http initialDelaySeconds: 0 periodSeconds: 10 timeoutSeconds: 3 failureThreshold: 30 # 5 minutes to start # Liveness probe livenessProbe: httpGet: path: /health/live port: http initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 3 # Readiness probe readinessProbe: httpGet: path: /health/ready port: http initialDelaySeconds: 5 periodSeconds: 5 timeoutSeconds: 3 failureThreshold: 3 # Volume mounts volumeMounts: - name: tmp mountPath: /tmp - name: cache mountPath: /app/cache # - name: data # mountPath: /var/lib/app # Container security context securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true runAsNonRoot: true runAsUser: 1000 capabilities: drop: - ALL # Lifecycle hooks lifecycle: preStop: exec: command: ["/bin/sh", "-c", "sleep 15"] # Graceful shutdown # Volumes volumes: - name: tmp emptyDir: {} - name: cache emptyDir: sizeLimit: 1Gi # - name: data # persistentVolumeClaim: # claimName: -data # Scheduling affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchLabels: app.kubernetes.io/name: topologyKey: kubernetes.io/hostname topologySpreadConstraints: - maxSkew: 1 topologyKey: topology.kubernetes.io/zone whenUnsatisfiable: ScheduleAnyway labelSelector: matchLabels: app.kubernetes.io/name: terminationGracePeriodSeconds: 30 # Image pull secrets (if using private registry) # imagePullSecrets: # - name: regcred