apiVersion: apps/v1 kind: Deployment metadata: name: k8s-pilot namespace: k8s-pilot labels: app: k8s-pilot spec: replicas: 2 selector: matchLabels: app: k8s-pilot # Recreate one pod at a time — always keep 1 running strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 maxSurge: 0 template: metadata: labels: app: k8s-pilot spec: serviceAccountName: k8s-pilot # Spread across nodes — one pod on Pi5, one on Pi4 topologySpreadConstraints: - maxSkew: 1 topologyKey: kubernetes.io/hostname whenUnsatisfiable: DoNotSchedule labelSelector: matchLabels: app: k8s-pilot # Hard anti-affinity: never two pods on the same node affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchLabels: app: k8s-pilot topologyKey: kubernetes.io/hostname # Must tolerate control-plane taint so Pi5 is eligible tolerations: - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule containers: - name: k8s-pilot # Replace with your Gitea registry path: # image: git.it-microevo.com//k8s-pilot:latest image: gitea.it-microevo.com/dev/k8s-pilot:latest imagePullPolicy: Always ports: - containerPort: 3000 env: - name: PORT value: "3000" resources: requests: cpu: 50m memory: 64Mi limits: cpu: 200m memory: 256Mi livenessProbe: httpGet: path: / port: 3000 initialDelaySeconds: 10 periodSeconds: 30 failureThreshold: 3 readinessProbe: httpGet: path: / port: 3000 initialDelaySeconds: 5 periodSeconds: 10