apiVersion: apps/v1 kind: StatefulSet metadata: name: broker-gateway-service namespace: foxhunt labels: app: broker-gateway-service component: broker tier: backend version: v1 spec: serviceName: broker-gateway-service replicas: 2 selector: matchLabels: app: broker-gateway-service # Update strategy: rolling update with 1 pod at a time updateStrategy: type: RollingUpdate rollingUpdate: partition: 0 # Pod template template: metadata: labels: app: broker-gateway-service component: broker tier: backend version: v1 annotations: prometheus.io/scrape: "true" prometheus.io/port: "9096" prometheus.io/path: "/metrics" spec: # Security context for pod securityContext: runAsNonRoot: true runAsUser: 1000 runAsGroup: 1000 fsGroup: 1000 # Service account for RBAC serviceAccountName: broker-gateway-service # Anti-affinity: prefer different nodes for high availability affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - broker-gateway-service topologyKey: kubernetes.io/hostname # Init container: wait for database to be ready initContainers: - name: wait-for-postgres image: busybox:1.36 command: - 'sh' - '-c' - | until nc -z postgres-service 5432; do echo "Waiting for PostgreSQL..." sleep 2 done echo "PostgreSQL is ready" - name: wait-for-redis image: busybox:1.36 command: - 'sh' - '-c' - | until nc -z redis-service 6379; do echo "Waiting for Redis..." sleep 2 done echo "Redis is ready" # Main application container containers: - name: broker-gateway-service image: jgrusewski/foxhunt-broker-gateway:latest imagePullPolicy: Always # Ports ports: - name: grpc containerPort: 50056 protocol: TCP - name: health containerPort: 8086 protocol: TCP - name: metrics containerPort: 9096 protocol: TCP # Environment variables from ConfigMap envFrom: - configMapRef: name: broker-gateway-config # Secret environment variables (CQG credentials) env: - name: CQG_USERNAME valueFrom: secretKeyRef: name: broker-gateway-secret key: cqg-username - name: CQG_PASSWORD valueFrom: secretKeyRef: name: broker-gateway-secret key: cqg-password - name: CQG_SENDER_COMP_ID valueFrom: secretKeyRef: name: broker-gateway-secret key: cqg-sender-comp-id # Resource limits and requests resources: limits: cpu: 2000m memory: 512Mi requests: cpu: 500m memory: 256Mi # Liveness probe: check if service is alive livenessProbe: exec: command: - /usr/local/bin/grpc_health_probe - -addr=localhost:50056 initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 3 successThreshold: 1 # Readiness probe: check if service is ready to accept traffic readinessProbe: exec: command: - /usr/local/bin/grpc_health_probe - -addr=localhost:50056 initialDelaySeconds: 10 periodSeconds: 5 timeoutSeconds: 5 failureThreshold: 3 successThreshold: 1 # Startup probe: allow slow startup (30s * 10 = 5 minutes max) startupProbe: exec: command: - /usr/local/bin/grpc_health_probe - -addr=localhost:50056 initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 30 successThreshold: 1 # Volume mounts volumeMounts: - name: logs mountPath: /app/logs - name: data mountPath: /app/data # Security context for container securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true runAsNonRoot: true runAsUser: 1000 capabilities: drop: - ALL # Termination grace period (allow 30s for graceful shutdown) terminationGracePeriodSeconds: 30 # DNS policy dnsPolicy: ClusterFirst # Restart policy restartPolicy: Always # Volume claim templates for StatefulSet volumeClaimTemplates: - metadata: name: logs labels: app: broker-gateway-service spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi storageClassName: standard - metadata: name: data labels: app: broker-gateway-service spec: accessModes: - ReadWriteOnce resources: requests: storage: 5Gi storageClassName: standard --- apiVersion: v1 kind: ServiceAccount metadata: name: broker-gateway-service namespace: foxhunt labels: app: broker-gateway-service