《Kubernetes集群部署:生产级配置》

📋 本文概览

学习目标

  • 掌握Kubernetes核心资源对象的定义与使用(Deployment/Service/Ingress)
  • 理解ConfigMap和Secret的最佳实践,实现配置与代码分离
  • 学会设计生产级持久化存储方案(PV/PVC/StorageClass)
  • 实现基于HPA的自动水平扩展,应对流量波动
  • 掌握滚动更新、金丝雀发布、蓝绿部署等发布策略
  • 构建完整的Helm Chart,实现一键部署

技术栈

  • Kubernetes 1.28+
  • Helm 3.12+
  • Ingress-Nginx 1.8+
  • cert-manager 1.13+ (自动HTTPS证书)
  • Prometheus Operator (监控)
  • PostgreSQL Operator (数据库集群)

预计阅读时间: 90分钟

前置知识要求

  • 掌握Docker容器化技术(参考第25篇)
  • 了解Kubernetes基本概念(Pod、Node、Namespace)
  • 熟悉YAML语法
  • 具备基本的Linux运维能力

🎯 业务场景:从Docker Compose到Kubernetes

Docker Compose的局限性

在第25篇中,我们使用Docker Compose实现了QuantumFlow的容器化部署,但在生产环境面临诸多挑战:

单机限制

# Docker Compose运行在单台服务器
# 问题1: 单点故障
Server1宕机 → 整个服务不可用

# 问题2: 资源受限
无法利用多台服务器的CPU/内存资源

# 问题3: 扩展困难
docker-compose up --scale backend=10
# 只能在单机扩展,受限于单机资源

缺乏自愈能力

# 容器崩溃需要手动重启
$ docker-compose ps
NAME                    STATUS
quantumflow-backend     Exited (137)  # 需要手动处理

$ docker-compose restart backend

负载均衡简陋

# Docker Compose的负载均衡基于DNS轮询
services:
  backend:
    deploy:
      replicas: 3
# 问题:无法感知实例健康状态,可能将流量发给不健康的实例

滚动更新困难

# 更新需要停机
$ docker-compose down
$ docker-compose up -d  # 服务中断

# 或手动逐个重启(繁琐且易出错)
$ docker-compose up -d --no-deps --scale backend=5 backend
$ sleep 10
$ docker-compose up -d --no-deps --scale backend=3 --remove-orphans backend

Kubernetes带来的价值

集群化管理

# 3台服务器组成K8s集群
master1: 控制平面
worker1: 运行Pod
worker2: 运行Pod

# 任意节点故障,Pod自动迁移到健康节点
Node worker1 故障 → K8s自动在worker2上重建Pod

声明式配置

# 只需声明期望状态,K8s自动维护
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
spec:
  replicas: 5  # 声明:我要5个副本
  # K8s会确保始终有5个Pod运行

自动伸缩

# 基于CPU使用率自动扩缩容
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
spec:
  minReplicas: 3
  maxReplicas: 20
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
# CPU > 70% → 自动扩容
# CPU < 70% → 自动缩容

零停机发布

# 滚动更新:逐步替换旧版本
$ kubectl set image deployment/backend backend=quantumflow/backend:v2.0
# K8s自动:
# 1. 启动1个新版本Pod
# 2. 等待新Pod健康
# 3. 停止1个旧版本Pod
# 4. 重复直到所有Pod更新完成
# 全程服务不中断

🏗️ Kubernetes架构设计

QuantumFlow在K8s中的整体架构

graph TB
    subgraph "Internet"
        User((用户))
    end
    
    subgraph "Kubernetes Cluster"
        subgraph "Ingress Layer"
            Ingress[Ingress Controller<br/>Nginx]
            CertManager[cert-manager<br/>自动HTTPS]
        end
        
        subgraph "Application Layer"
            BackendSvc[Backend Service<br/>ClusterIP]
            BackendDeploy[Backend Deployment<br/>5 replicas]
            WorkerDeploy[Celery Worker Deployment<br/>3 replicas]
            BeatDeploy[Celery Beat Deployment<br/>1 replica]
        end
        
        subgraph "Data Layer"
            PGCluster[PostgreSQL Cluster<br/>1 Primary + 2 Replicas]
            RedisSvc[Redis Service]
            RedisSS[Redis StatefulSet]
        end
        
        subgraph "Storage Layer"
            PVC1[PVC: postgres-data]
            PVC2[PVC: redis-data]
            PV1[PV: Local SSD]
            PV2[PV: Network Storage]
        end
        
        subgraph "Configuration"
            ConfigMap[ConfigMap<br/>应用配置]
            Secret[Secret<br/>敏感信息]
        end
        
        subgraph "Monitoring"
            Prometheus[Prometheus]
            Grafana[Grafana]
        end
    end
    
    User --> Ingress
    Ingress --> BackendSvc
    BackendSvc --> BackendDeploy
    BackendDeploy --> PGCluster
    BackendDeploy --> RedisSvc
    WorkerDeploy --> RedisSvc
    RedisSvc --> RedisSS
    PGCluster --> PVC1
    RedisSS --> PVC2
    PVC1 --> PV1
    PVC2 --> PV2
    BackendDeploy -.读取.-> ConfigMap
    BackendDeploy -.读取.-> Secret
    CertManager -.管理.-> Ingress
    Prometheus -.监控.-> BackendDeploy
    Prometheus -.监控.-> PGCluster
    Grafana -.展示.-> Prometheus

资源层级关系

Cluster (集群)
└── Namespace: quantumflow-prod (命名空间)
    ├── Deployments (无状态应用)
    │   ├── backend (5 Pods)
    │   ├── celery-worker (3 Pods)
    │   └── celery-beat (1 Pod)
    ├── StatefulSets (有状态应用)
    │   ├── postgresql (3 Pods)
    │   └── redis (1 Pod)
    ├── Services (服务发现)
    │   ├── backend-svc (后端API)
    │   ├── postgres-svc (数据库)
    │   └── redis-svc (缓存)
    ├── Ingress (外部访问)
    │   └── quantumflow-ingress
    ├── ConfigMaps (配置)
    │   ├── backend-config
    │   └── nginx-config
    ├── Secrets (敏感信息)
    │   ├── db-credentials
    │   ├── jwt-secret
    │   └── tls-cert
    └── PersistentVolumeClaims (存储)
        ├── postgres-data
        └── redis-data

💻 核心实现

1. Namespace与基础资源

命名空间定义

# k8s/namespaces/quantumflow-prod.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: quantumflow-prod
  labels:
    app: quantumflow
    environment: production
  annotations:
    description: "QuantumFlow生产环境命名空间"
---
# 资源配额(防止资源滥用)
apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-resources
  namespace: quantumflow-prod
spec:
  hard:
    requests.cpu: "50"        # 总CPU请求上限
    requests.memory: 100Gi    # 总内存请求上限
    limits.cpu: "100"         # 总CPU限制上限
    limits.memory: 200Gi      # 总内存限制上限
    persistentvolumeclaims: "10"  # PVC数量上限
    services.loadbalancers: "2"   # LoadBalancer服务上限
---
# 限制范围(单个Pod/Container的限制)
apiVersion: v1
kind: LimitRange
metadata:
  name: resource-limits
  namespace: quantumflow-prod
spec:
  limits:
  - max:
      cpu: "4"          # 单个容器最大CPU
      memory: 8Gi       # 单个容器最大内存
    min:
      cpu: "100m"       # 单个容器最小CPU
      memory: 128Mi     # 单个容器最小内存
    default:
      cpu: "500m"       # 默认CPU限制
      memory: 512Mi     # 默认内存限制
    defaultRequest:
      cpu: "250m"       # 默认CPU请求
      memory: 256Mi     # 默认内存请求
    type: Container

网络策略(安全隔离)

# k8s/network-policies/backend-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: backend-network-policy
  namespace: quantumflow-prod
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
  - Ingress
  - Egress
  
  # 入站规则
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: nginx-ingress  # 仅允许来自Ingress的流量
    ports:
    - protocol: TCP
      port: 8000
  
  # 出站规则
  egress:
  # 允许访问PostgreSQL
  - to:
    - podSelector:
        matchLabels:
          app: postgresql
    ports:
    - protocol: TCP
      port: 5432
  
  # 允许访问Redis
  - to:
    - podSelector:
        matchLabels:
          app: redis
    ports:
    - protocol: TCP
      port: 6379
  
  # 允许DNS查询
  - to:
    - namespaceSelector:
        matchLabels:
          name: kube-system
    - podSelector:
        matchLabels:
          k8s-app: kube-dns
    ports:
    - protocol: UDP
      port: 53
  
  # 允许访问外部API(如OpenAI)
  - to:
    - namespaceSelector: {}
    ports:
    - protocol: TCP
      port: 443

2. ConfigMap与Secret管理

ConfigMap示例(非敏感配置)

# k8s/configmaps/backend-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: backend-config
  namespace: quantumflow-prod
  labels:
    app: backend
data:
  # 应用配置
  ENVIRONMENT: "production"
  DEBUG: "False"
  LOG_LEVEL: "WARNING"
  
  # 数据库配置(非敏感部分)
  DB_HOST: "postgresql-svc.quantumflow-prod.svc.cluster.local"
  DB_PORT: "5432"
  DB_NAME: "quantumflow"
  DB_POOL_SIZE: "20"
  DB_MAX_OVERFLOW: "10"
  
  # Redis配置
  REDIS_HOST: "redis-svc.quantumflow-prod.svc.cluster.local"
  REDIS_PORT: "6379"
  REDIS_DB: "0"
  
  # Celery配置
  CELERY_BROKER_URL: "redis://redis-svc.quantumflow-prod.svc.cluster.local:6379/1"
  CELERY_RESULT_BACKEND: "redis://redis-svc.quantumflow-prod.svc.cluster.local:6379/2"
  CELERY_TASK_ALWAYS_EAGER: "False"
  
  # CORS配置
  CORS_ORIGINS: "https://quantumflow.com,https://www.quantumflow.com"
  
  # JWT配置(非敏感部分)
  JWT_ALGORITHM: "HS256"
  JWT_EXPIRE_MINUTES: "60"
  
  # 应用配置文件(可以是完整的YAML/JSON)
  app-config.yaml: |
    server:
      host: 0.0.0.0
      port: 8000
      workers: 4
    
    features:
      ai_workflow_generation: true
      workflow_templates: true
      multi_tenancy: true
    
    limits:
      max_workflows_per_user: 100
      max_executions_per_day: 10000
      max_nodes_per_workflow: 50
    
    integrations:
      openai:
        enabled: true
        model: "gpt-4"
      stripe:
        enabled: true

Secret示例(敏感信息)

# k8s/secrets/backend-secrets.yaml
apiVersion: v1
kind: Secret
metadata:
  name: backend-secrets
  namespace: quantumflow-prod
  labels:
    app: backend
type: Opaque
stringData:  # 使用stringData,K8s会自动Base64编码
  # 数据库凭证
  DB_USER: "quantumflow"
  DB_PASSWORD: "Xk9#mP2$vL8@nQ4w"
  DATABASE_URL: "postgresql://quantumflow:Xk9#mP2$vL8@nQ4w@postgresql-svc:5432/quantumflow"
  
  # Redis密码
  REDIS_PASSWORD: "rD7$kL3@pM9#vN2x"
  
  # JWT密钥
  SECRET_KEY: "f8a9e7c2d3b1a4f6e9d8c7b6a5f4e3d2c1b0a9f8e7d6c5b4a3f2e1d0c9b8a7f6"
  JWT_SECRET_KEY: "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0e1f2"
  
  # Stripe密钥
  STRIPE_SECRET_KEY: "sk_live_51MqxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxE7"
  STRIPE_WEBHOOK_SECRET: "whsec_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  
  # OpenAI密钥
  OPENAI_API_KEY: "sk-proj-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  
  # Sentry DSN
  SENTRY_DSN: "https://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx@o123456.ingest.sentry.io/7654321"

---
# 使用外部Secret管理系统(推荐生产环境)
apiVersion: v1
kind: Secret
metadata:
  name: db-credentials
  namespace: quantumflow-prod
  annotations:
    # 使用Sealed Secrets(加密存储在Git)
    sealedsecrets.bitnami.com/cluster-wide: "true"
type: Opaque
data:
  # 这些是加密后的值,可以安全存储在Git
  username: QWdBR...(Base64 + 加密)
  password: Y2FDQ...(Base64 + 加密)

Secret管理最佳实践

# 方法1: 使用kubectl直接创建(不存储在Git)
kubectl create secret generic backend-secrets \
  --from-literal=DB_PASSWORD='Xk9#mP2$vL8@nQ4w' \
  --from-literal=JWT_SECRET_KEY='...' \
  -n quantumflow-prod

# 方法2: 从文件创建
cat <<EOF > secret.env
DB_PASSWORD=Xk9#mP2$vL8@nQ4w
JWT_SECRET_KEY=...
EOF
kubectl create secret generic backend-secrets \
  --from-env-file=secret.env \
  -n quantumflow-prod
rm secret.env  # 立即删除

# 方法3: 使用Sealed Secrets(推荐)
# 1. 安装Sealed Secrets Controller
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/controller.yaml

# 2. 创建普通Secret
kubectl create secret generic backend-secrets \
  --dry-run=client -o yaml \
  --from-literal=DB_PASSWORD='...' > secret.yaml

# 3. 加密Secret
kubeseal -f secret.yaml -w sealed-secret.yaml

# 4. 提交到Git(安全)
git add sealed-secret.yaml
git commit -m "Add encrypted secrets"

# 方法4: 使用外部Secret存储(最推荐)
# - HashiCorp Vault
# - AWS Secrets Manager
# - Azure Key Vault
# - Google Secret Manager

在Pod中使用ConfigMap和Secret

# k8s/deployments/backend.yaml(部分)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
spec:
  template:
    spec:
      containers:
      - name: backend
        image: quantumflow/backend:v2.0
        
        # 方式1: 环境变量(推荐)
        envFrom:
        - configMapRef:
            name: backend-config  # 导入所有ConfigMap键值对
        - secretRef:
            name: backend-secrets  # 导入所有Secret键值对
        
        # 方式2: 选择性导入
        env:
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: backend-secrets
              key: DATABASE_URL
        - name: LOG_LEVEL
          valueFrom:
            configMapKeyRef:
              name: backend-config
              key: LOG_LEVEL
        
        # 方式3: 挂载为文件
        volumeMounts:
        - name: config-volume
          mountPath: /app/config
          readOnly: true
        - name: secret-volume
          mountPath: /app/secrets
          readOnly: true
      
      volumes:
      - name: config-volume
        configMap:
          name: backend-config
          items:
          - key: app-config.yaml
            path: config.yaml
      - name: secret-volume
        secret:
          secretName: backend-secrets
          items:
          - key: JWT_SECRET_KEY
            path: jwt-secret.txt
            mode: 0400  # 只读权限

3. Deployment(后端API部署)

# k8s/deployments/backend.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
  namespace: quantumflow-prod
  labels:
    app: backend
    component: api
    version: v2.0
  annotations:
    description: "QuantumFlow后端API服务"
    deployment.kubernetes.io/revision: "5"
spec:
  # 副本数(由HPA动态调整)
  replicas: 5
  
  # 选择器(匹配Pod标签)
  selector:
    matchLabels:
      app: backend
      component: api
  
  # 滚动更新策略
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 2           # 更新时最多多出2个Pod
      maxUnavailable: 1     # 更新时最多1个Pod不可用
  
  # Pod最少运行时间(防止频繁重启)
  minReadySeconds: 10
  
  # 修订历史保留数
  revisionHistoryLimit: 10
  
  # Pod模板
  template:
    metadata:
      labels:
        app: backend
        component: api
        version: v2.0
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "8000"
        prometheus.io/path: "/metrics"
    
    spec:
      # 服务账号(用于访问K8s API)
      serviceAccountName: backend-sa
      
      # Pod调度配置
      affinity:
        # Pod反亲和性(分散到不同节点)
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - backend
              topologyKey: kubernetes.io/hostname
        
        # 节点亲和性(优先调度到高性能节点)
        nodeAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 50
            preference:
              matchExpressions:
              - key: node-type
                operator: In
                values:
                - high-performance
      
      # 容忍度(允许调度到有污点的节点)
      tolerations:
      - key: "dedicated"
        operator: "Equal"
        value: "quantumflow"
        effect: "NoSchedule"
      
      # Init容器(初始化任务)
      initContainers:
      - name: wait-for-db
        image: busybox:1.36
        command: ['sh', '-c']
        args:
        - |
          until nc -z postgresql-svc 5432; do
            echo "Waiting for PostgreSQL..."
            sleep 2
          done
          echo "PostgreSQL is ready!"
      
      - name: run-migrations
        image: quantumflow/backend:v2.0
        command: ["alembic", "upgrade", "head"]
        envFrom:
        - configMapRef:
            name: backend-config
        - secretRef:
            name: backend-secrets
      
      # 主容器
      containers:
      - name: backend
        image: quantumflow/backend:v2.0
        imagePullPolicy: IfNotPresent
        
        # 端口
        ports:
        - name: http
          containerPort: 8000
          protocol: TCP
        
        # 环境变量
        envFrom:
        - configMapRef:
            name: backend-config
        - secretRef:
            name: backend-secrets
        
        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
        
        # 资源限制
        resources:
          requests:
            cpu: "500m"       # 0.5核CPU(保证)
            memory: "1Gi"     # 1GB内存(保证)
          limits:
            cpu: "2"          # 最多2核CPU
            memory: "4Gi"     # 最多4GB内存
        
        # 健康检查
        livenessProbe:
          httpGet:
            path: /health/live
            port: 8000
            httpHeaders:
            - name: X-Health-Check
              value: liveness
          initialDelaySeconds: 30   # 启动后30秒开始检查
          periodSeconds: 10         # 每10秒检查一次
          timeoutSeconds: 5         # 超时时间5秒
          successThreshold: 1       # 成功1次即健康
          failureThreshold: 3       # 失败3次即重启Pod
        
        readinessProbe:
          httpGet:
            path: /health/ready
            port: 8000
          initialDelaySeconds: 10
          periodSeconds: 5
          timeoutSeconds: 3
          successThreshold: 1
          failureThreshold: 2
        
        startupProbe:
          httpGet:
            path: /health
            port: 8000
          initialDelaySeconds: 0
          periodSeconds: 5
          timeoutSeconds: 3
          successThreshold: 1
          failureThreshold: 30      # 最多等待150秒启动
        
        # 卷挂载
        volumeMounts:
        - name: logs
          mountPath: /app/logs
        - name: tmp
          mountPath: /tmp
        - name: config
          mountPath: /app/config
          readOnly: true
        
        # 安全上下文
        securityContext:
          runAsNonRoot: true
          runAsUser: 1000
          allowPrivilegeEscalation: false
          readOnlyRootFilesystem: true
          capabilities:
            drop:
            - ALL
      
      # 卷定义
      volumes:
      - name: logs
        emptyDir: {}
      - name: tmp
        emptyDir: {}
      - name: config
        configMap:
          name: backend-config
      
      # DNS配置
      dnsPolicy: ClusterFirst
      
      # 重启策略
      restartPolicy: Always
      
      # 优雅终止时间
      terminationGracePeriodSeconds: 60
      
      # 镜像拉取密钥(私有镜像仓库)
      imagePullSecrets:
      - name: dockerhub-secret

---
# ServiceAccount(赋予Pod权限)
apiVersion: v1
kind: ServiceAccount
metadata:
  name: backend-sa
  namespace: quantumflow-prod
---
# Role(定义权限)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: backend-role
  namespace: quantumflow-prod
rules:
- apiGroups: [""]
  resources: ["pods", "configmaps"]
  verbs: ["get", "list", "watch"]
---
# RoleBinding(绑定权限)
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: backend-rolebinding
  namespace: quantumflow-prod
subjects:
- kind: ServiceAccount
  name: backend-sa
roleRef:
  kind: Role
  name: backend-role
  apiGroup: rbac.authorization.k8s.io

Celery Worker部署

# k8s/deployments/celery-worker.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: celery-worker
  namespace: quantumflow-prod
  labels:
    app: celery
    component: worker
spec:
  replicas: 3
  selector:
    matchLabels:
      app: celery
      component: worker
  
  template:
    metadata:
      labels:
        app: celery
        component: worker
    
    spec:
      containers:
      - name: worker
        image: quantumflow/backend:v2.0
        command: 
        - celery
        - -A
        - src.celery_app
        - worker
        - --loglevel=info
        - --concurrency=4
        - --max-tasks-per-child=1000
        
        envFrom:
        - configMapRef:
            name: backend-config
        - secretRef:
            name: backend-secrets
        
        resources:
          requests:
            cpu: "1"
            memory: "2Gi"
          limits:
            cpu: "4"
            memory: "8Gi"
        
        # Worker无需健康检查(通过Celery监控)
        livenessProbe:
          exec:
            command:
            - celery
            - -A
            - src.celery_app
            - inspect
            - ping
          initialDelaySeconds: 30
          periodSeconds: 60
          timeoutSeconds: 10
          failureThreshold: 3

4. Service(服务发现)

# k8s/services/backend-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: backend-svc
  namespace: quantumflow-prod
  labels:
    app: backend
  annotations:
    prometheus.io/scrape: "true"
    prometheus.io/port: "8000"
spec:
  type: ClusterIP  # 集群内部访问
  
  # 会话亲和性(可选,同一客户端请求发往同一Pod)
  sessionAffinity: ClientIP
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 3600  # 1小时
  
  # 选择器(匹配Pod)
  selector:
    app: backend
    component: api
  
  # 端口映射
  ports:
  - name: http
    protocol: TCP
    port: 80          # Service端口
    targetPort: 8000  # Pod端口
  - name: metrics
    protocol: TCP
    port: 9090
    targetPort: 9090

---
# Headless Service(用于StatefulSet)
apiVersion: v1
kind: Service
metadata:
  name: backend-headless
  namespace: quantumflow-prod
spec:
  clusterIP: None  # Headless Service
  selector:
    app: backend
  ports:
  - port: 8000
    targetPort: 8000

LoadBalancer类型Service(用于外部访问)

# k8s/services/backend-lb.yaml
apiVersion: v1
kind: Service
metadata:
  name: backend-lb
  namespace: quantumflow-prod
  annotations:
    # AWS ELB注解
    service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
    service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http"
    service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "arn:aws:acm:us-east-1:123456789012:certificate/..."
    service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443"
spec:
  type: LoadBalancer
  selector:
    app: backend
  ports:
  - name: https
    port: 443
    targetPort: 8000
  - name: http
    port: 80
    targetPort: 8000
  
  # 保留客户端IP
  externalTrafficPolicy: Local

5. Ingress(外部访问入口)

# k8s/ingress/quantumflow-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: quantumflow-ingress
  namespace: quantumflow-prod
  annotations:
    # Ingress类
    kubernetes.io/ingress.class: "nginx"
    
    # SSL配置
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
    
    # Nginx配置
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/proxy-body-size: "50m"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
    
    # 限流
    nginx.ingress.kubernetes.io/limit-rps: "100"
    nginx.ingress.kubernetes.io/limit-connections: "20"
    
    # CORS
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-origin: "https://quantumflow.com"
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, DELETE, OPTIONS"
    nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
    
    # WebSocket支持
    nginx.ingress.kubernetes.io/websocket-services: "backend-svc"
    
    # 自定义错误页面
    nginx.ingress.kubernetes.io/custom-http-errors: "404,503"
    nginx.ingress.kubernetes.io/default-backend: "error-page-svc"
    
    # 速率限制
    nginx.ingress.kubernetes.io/rate-limit: "100"
    
    # 白名单IP(可选)
    # nginx.ingress.kubernetes.io/whitelist-source-range: "10.0.0.0/8,172.16.0.0/12"

spec:
  # TLS配置
  tls:
  - hosts:
    - quantumflow.com
    - www.quantumflow.com
    - api.quantumflow.com
    secretName: quantumflow-tls  # cert-manager自动生成
  
  # 路由规则
  rules:
  # 主域名
  - host: quantumflow.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend-svc
            port:
              number: 80
  
  # www重定向
  - host: www.quantumflow.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend-svc
            port:
              number: 80
  
  # API子域名
  - host: api.quantumflow.com
    http:
      paths:
      # API路由
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: backend-svc
            port:
              number: 80
      
      # WebSocket路由
      - path: /ws
        pathType: Prefix
        backend:
          service:
            name: backend-svc
            port:
              number: 80
      
      # 健康检查(直接放行,不限流)
      - path: /health
        pathType: Exact
        backend:
          service:
            name: backend-svc
            port:
              number: 80

---
# cert-manager ClusterIssuer(自动签发Let's Encrypt证书)
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: admin@quantumflow.com
    privateKeySecretRef:
      name: letsencrypt-prod-key
    solvers:
    - http01:
        ingress:
          class: nginx

高级路由规则(金丝雀发布)

# k8s/ingress/canary-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: backend-canary
  namespace: quantumflow-prod
  annotations:
    kubernetes.io/ingress.class: "nginx"
    
    # 金丝雀发布
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "10"  # 10%流量到新版本
    
    # 或基于请求头
    # nginx.ingress.kubernetes.io/canary-by-header: "X-Canary"
    # nginx.ingress.kubernetes.io/canary-by-header-value: "true"
    
    # 或基于Cookie
    # nginx.ingress.kubernetes.io/canary-by-cookie: "canary"

spec:
  tls:
  - hosts:
    - api.quantumflow.com
    secretName: quantumflow-tls
  
  rules:
  - host: api.quantumflow.com
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: backend-v2-svc  # 新版本Service
            port:
              number: 80

6. StatefulSet(有状态应用:Redis)

# k8s/statefulsets/redis.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis
  namespace: quantumflow-prod
  labels:
    app: redis
spec:
  serviceName: redis-headless  # 关联Headless Service
  replicas: 1  # Redis单实例(生产环境建议使用Redis Sentinel或Cluster)
  
  selector:
    matchLabels:
      app: redis
  
  # Pod管理策略
  podManagementPolicy: OrderedReady  # 按顺序创建/删除
  
  # 更新策略
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      partition: 0  # 从第0个Pod开始更新
  
  template:
    metadata:
      labels:
        app: redis
    
    spec:
      containers:
      - name: redis
        image: redis:7-alpine
        
        command:
        - redis-server
        - /etc/redis/redis.conf
        
        ports:
        - name: redis
          containerPort: 6379
          protocol: TCP
        
        env:
        - name: REDIS_PASSWORD
          valueFrom:
            secretKeyRef:
              name: backend-secrets
              key: REDIS_PASSWORD
        
        resources:
          requests:
            cpu: "500m"
            memory: "1Gi"
          limits:
            cpu: "2"
            memory: "4Gi"
        
        # 健康检查
        livenessProbe:
          exec:
            command:
            - redis-cli
            - ping
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
          failureThreshold: 3
        
        readinessProbe:
          exec:
            command:
            - redis-cli
            - ping
          initialDelaySeconds: 5
          periodSeconds: 5
        
        # 持久化卷挂载
        volumeMounts:
        - name: data
          mountPath: /data
        - name: config
          mountPath: /etc/redis
          readOnly: true
      
      volumes:
      - name: config
        configMap:
          name: redis-config
  
  # 卷申请模板(每个Pod独立的PVC)
  volumeClaimTemplates:
  - metadata:
      name: data
      labels:
        app: redis
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: "fast-ssd"  # 使用SSD存储类
      resources:
        requests:
          storage: 50Gi

---
# Redis配置
apiVersion: v1
kind: ConfigMap
metadata:
  name: redis-config
  namespace: quantumflow-prod
data:
  redis.conf: |
    # 持久化
    appendonly yes
    appendfsync everysec
    
    # 内存管理
    maxmemory 3gb
    maxmemory-policy allkeys-lru
    
    # 密码认证
    requirepass ${REDIS_PASSWORD}
    
    # 网络
    bind 0.0.0.0
    protected-mode no
    
    # 性能优化
    tcp-backlog 511
    timeout 300
    tcp-keepalive 60

---
# Headless Service(StatefulSet必需)
apiVersion: v1
kind: Service
metadata:
  name: redis-headless
  namespace: quantumflow-prod
spec:
  clusterIP: None
  selector:
    app: redis
  ports:
  - port: 6379
    targetPort: 6379

---
# ClusterIP Service(外部访问)
apiVersion: v1
kind: Service
metadata:
  name: redis-svc
  namespace: quantumflow-prod
spec:
  type: ClusterIP
  selector:
    app: redis
  ports:
  - port: 6379
    targetPort: 6379

7. 持久化存储(PV/PVC)

StorageClass定义

# k8s/storage/storage-classes.yaml

# 快速SSD存储(用于数据库)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-ssd
  annotations:
    storageclass.kubernetes.io/is-default-class: "false"
provisioner: kubernetes.io/aws-ebs  # AWS EBS
parameters:
  type: gp3
  iops: "3000"
  throughput: "125"
  encrypted: "true"
volumeBindingMode: WaitForFirstConsumer  # 延迟绑定(避免跨AZ)
allowVolumeExpansion: true
reclaimPolicy: Retain  # 删除PVC时保留PV

---
# 标准存储(用于日志、备份)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: standard
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp2
volumeBindingMode: Immediate
allowVolumeExpansion: true
reclaimPolicy: Delete

---
# 本地SSD存储(高性能,但不可迁移)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-ssd
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Delete

静态PV定义(本地存储)

# k8s/storage/local-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: postgres-pv-node1
  labels:
    type: local
    node: worker-node-1
spec:
  capacity:
    storage: 100Gi
  
  accessModes:
  - ReadWriteOnce
  
  persistentVolumeReclaimPolicy: Retain
  
  storageClassName: local-ssd
  
  local:
    path: /mnt/disks/ssd1
  
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - worker-node-1

动态PVC(推荐)

# k8s/storage/postgres-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgres-data
  namespace: quantumflow-prod
  labels:
    app: postgresql
spec:
  accessModes:
  - ReadWriteOnce
  
  storageClassName: fast-ssd
  
  resources:
    requests:
      storage: 100Gi
  
  # 选择器(静态PV时使用)
  # selector:
  #   matchLabels:
  #     type: local

---
# 备份PVC(可扩展)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgres-backup
  namespace: quantumflow-prod
spec:
  accessModes:
  - ReadWriteMany  # 多个Pod可同时读写(用于备份)
  
  storageClassName: standard
  
  resources:
    requests:
      storage: 500Gi

在Pod中使用PVC

# StatefulSet使用volumeClaimTemplates(见上文Redis示例)

# Deployment使用已存在的PVC
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backup-job
spec:
  template:
    spec:
      containers:
      - name: backup
        image: postgres:15
        volumeMounts:
        - name: backup-data
          mountPath: /backup
      
      volumes:
      - name: backup-data
        persistentVolumeClaim:
          claimName: postgres-backup

存储快照(备份与恢复)

# k8s/storage/volume-snapshot.yaml
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
  name: postgres-snapshot-20250115
  namespace: quantumflow-prod
spec:
  volumeSnapshotClassName: csi-aws-vsc
  source:
    persistentVolumeClaimName: postgres-data

---
# 从快照恢复
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgres-data-restored
  namespace: quantumflow-prod
spec:
  accessModes:
  - ReadWriteOnce
  storageClassName: fast-ssd
  dataSource:
    name: postgres-snapshot-20250115
    kind: VolumeSnapshot
    apiGroup: snapshot.storage.k8s.io
  resources:
    requests:
      storage: 100Gi

8. HorizontalPodAutoscaler(自动伸缩)

# k8s/hpa/backend-hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: backend-hpa
  namespace: quantumflow-prod
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: backend
  
  minReplicas: 3    # 最少3个Pod
  maxReplicas: 20   # 最多20个Pod
  
  # 扩缩容行为
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300  # 缩容前稳定5分钟
      policies:
      - type: Percent
        value: 50          # 每次最多缩容50%
        periodSeconds: 60  # 每分钟评估一次
      - type: Pods
        value: 2           # 每次最多缩容2个Pod
        periodSeconds: 60
      selectPolicy: Min    # 选择最保守的策略
    
    scaleUp:
      stabilizationWindowSeconds: 0    # 立即扩容
      policies:
      - type: Percent
        value: 100         # 每次最多扩容100%(翻倍)
        periodSeconds: 15  # 每15秒评估一次
      - type: Pods
        value: 4           # 每次最多扩容4个Pod
        periodSeconds: 15
      selectPolicy: Max    # 选择最激进的策略
  
  # 指标
  metrics:
  # 1. CPU利用率
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70  # CPU > 70%时扩容
  
  # 2. 内存利用率
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80
  
  # 3. 自定义指标(每秒请求数)
  - type: Pods
    pods:
      metric:
        name: http_requests_per_second
      target:
        type: AverageValue
        averageValue: "1000"  # 每个Pod处理1000 RPS
  
  # 4. 外部指标(队列长度)
  - type: External
    external:
      metric:
        name: celery_queue_length
        selector:
          matchLabels:
            queue: default
      target:
        type: AverageValue
        averageValue: "100"  # 队列长度 > 100时扩容

---
# Celery Worker HPA(基于队列长度)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: celery-worker-hpa
  namespace: quantumflow-prod
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: celery-worker
  
  minReplicas: 2
  maxReplicas: 10
  
  metrics:
  - type: External
    external:
      metric:
        name: celery_queue_tasks_total
        selector:
          matchLabels:
            queue: default
      target:
        type: AverageValue
        averageValue: "50"  # 每个Worker处理50个任务

自定义指标(Prometheus Adapter)

# k8s/monitoring/custom-metrics.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: adapter-config
  namespace: monitoring
data:
  config.yaml: |
    rules:
    # HTTP请求数指标
    - seriesQuery: 'http_requests_total{namespace="quantumflow-prod"}'
      resources:
        overrides:
          namespace: {resource: "namespace"}
          pod: {resource: "pod"}
      name:
        matches: "^(.*)_total$"
        as: "${1}_per_second"
      metricsQuery: 'sum(rate(<<.Series>>{<<.LabelMatchers>>}[1m])) by (<<.GroupBy>>)'
    
    # Celery队列长度
    - seriesQuery: 'celery_queue_length{namespace="quantumflow-prod"}'
      resources:
        overrides:
          namespace: {resource: "namespace"}
      name:
        as: "celery_queue_tasks_total"
      metricsQuery: 'sum(<<.Series>>{<<.LabelMatchers>>}) by (<<.GroupBy>>)'

9. 滚动更新策略

标准滚动更新

# 方式1: 更新镜像
kubectl set image deployment/backend \
  backend=quantumflow/backend:v2.1 \
  -n quantumflow-prod

# 方式2: 应用新的YAML
kubectl apply -f k8s/deployments/backend.yaml

# 查看更新状态
kubectl rollout status deployment/backend -n quantumflow-prod

# 查看更新历史
kubectl rollout history deployment/backend -n quantumflow-prod

# 回滚到上一版本
kubectl rollout undo deployment/backend -n quantumflow-prod

# 回滚到指定版本
kubectl rollout undo deployment/backend --to-revision=3 -n quantumflow-prod

# 暂停更新
kubectl rollout pause deployment/backend -n quantumflow-prod

# 恢复更新
kubectl rollout resume deployment/backend -n quantumflow-prod

金丝雀发布(Canary Deployment)

# k8s/deployments/backend-canary.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend-canary
  namespace: quantumflow-prod
  labels:
    app: backend
    version: v2.1
    track: canary
spec:
  replicas: 1  # 先部署1个金丝雀Pod
  selector:
    matchLabels:
      app: backend
      version: v2.1
  template:
    metadata:
      labels:
        app: backend
        version: v2.1
        track: canary
    spec:
      containers:
      - name: backend
        image: quantumflow/backend:v2.1  # 新版本
        # ... 其他配置同正常版本
# 金丝雀发布流程
# 1. 部署金丝雀版本(1个Pod,接收5%流量)
kubectl apply -f k8s/deployments/backend-canary.yaml
kubectl apply -f k8s/ingress/canary-ingress.yaml  # 见上文

# 2. 观察指标(错误率、延迟等)
kubectl logs -f deployment/backend-canary -n quantumflow-prod

# 3. 如果正常,逐步增加流量
kubectl patch ingress backend-canary -n quantumflow-prod \
  -p '{"metadata":{"annotations":{"nginx.ingress.kubernetes.io/canary-weight":"20"}}}'

# 4. 最终全量发布
kubectl scale deployment/backend-canary --replicas=5 -n quantumflow-prod
kubectl delete deployment/backend -n quantumflow-prod  # 删除旧版本
kubectl patch deployment/backend-canary -n quantumflow-prod \
  --type='json' -p='[{"op": "replace", "path": "/metadata/name", "value":"backend"}]'

# 5. 如果出现问题,立即回滚
kubectl delete deployment/backend-canary -n quantumflow-prod

蓝绿部署(Blue-Green Deployment)

# k8s/deployments/backend-blue.yaml(当前生产版本)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend-blue
  namespace: quantumflow-prod
  labels:
    app: backend
    version: v2.0
    color: blue
spec:
  replicas: 5
  selector:
    matchLabels:
      app: backend
      color: blue
  template:
    metadata:
      labels:
        app: backend
        version: v2.0
        color: blue
    spec:
      containers:
      - name: backend
        image: quantumflow/backend:v2.0

---
# k8s/deployments/backend-green.yaml(新版本)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend-green
  namespace: quantumflow-prod
  labels:
    app: backend
    version: v2.1
    color: green
spec:
  replicas: 5
  selector:
    matchLabels:
      app: backend
      color: green
  template:
    metadata:
      labels:
        app: backend
        version: v2.1
        color: green
    spec:
      containers:
      - name: backend
        image: quantumflow/backend:v2.1

---
# Service(通过修改selector切换版本)
apiVersion: v1
kind: Service
metadata:
  name: backend-svc
  namespace: quantumflow-prod
spec:
  selector:
    app: backend
    color: blue  # 当前指向蓝色版本
  ports:
  - port: 80
    targetPort: 8000
# 蓝绿部署流程
# 1. 部署绿色版本(新版本)
kubectl apply -f k8s/deployments/backend-green.yaml

# 2. 等待所有Pod就绪
kubectl wait --for=condition=ready pod -l color=green -n quantumflow-prod --timeout=300s

# 3. 切换Service到绿色版本(瞬间切换,零停机)
kubectl patch service backend-svc -n quantumflow-prod \
  -p '{"spec":{"selector":{"color":"green"}}}'

# 4. 观察一段时间,确认无问题后删除蓝色版本
kubectl delete deployment/backend-blue -n quantumflow-prod

# 5. 如果出现问题,立即切回蓝色版本
kubectl patch service backend-svc -n quantumflow-prod \
  -p '{"spec":{"selector":{"color":"blue"}}}'

📦 Helm Chart实现

Helm Chart目录结构

quantumflow-chart/
├── Chart.yaml              # Chart元数据
├── values.yaml             # 默认配置值
├── values-dev.yaml         # 开发环境配置
├── values-prod.yaml        # 生产环境配置
├── templates/              # K8s资源模板
│   ├── NOTES.txt          # 安装后提示信息
│   ├── _helpers.tpl       # 模板辅助函数
│   ├── namespace.yaml
│   ├── configmap.yaml
│   ├── secret.yaml
│   ├── deployment-backend.yaml
│   ├── deployment-worker.yaml
│   ├── statefulset-redis.yaml
│   ├── service-backend.yaml
│   ├── service-redis.yaml
│   ├── ingress.yaml
│   ├── hpa.yaml
│   ├── pvc.yaml
│   ├── serviceaccount.yaml
│   └── tests/             # Helm测试
│       └── test-connection.yaml
└── charts/                 # 依赖Chart
    └── postgresql/        # PostgreSQL子Chart

Chart.yaml

# quantumflow-chart/Chart.yaml
apiVersion: v2
name: quantumflow
description: QuantumFlow企业级工作流自动化平台
type: application
version: 2.1.0          # Chart版本
appVersion: "2.1.0"     # 应用版本

keywords:
  - workflow
  - automation
  - orchestration

home: https://quantumflow.com
sources:
  - https://github.com/quantumflow/quantumflow

maintainers:
  - name: QuantumFlow Team
    email: team@quantumflow.com
    url: https://quantumflow.com

# 依赖
dependencies:
  - name: postgresql
    version: "12.x.x"
    repository: https://charts.bitnami.com/bitnami
    condition: postgresql.enabled
  
  - name: redis
    version: "17.x.x"
    repository: https://charts.bitnami.com/bitnami
    condition: redis.enabled
  
  - name: prometheus
    version: "15.x.x"
    repository: https://prometheus-community.github.io/helm-charts
    condition: monitoring.prometheus.enabled

values.yaml(默认配置)

# quantumflow-chart/values.yaml

# 全局配置
global:
  imageRegistry: ""
  imagePullSecrets: []
  storageClass: "standard"

# 应用配置
app:
  name: quantumflow
  version: "2.1.0"
  environment: production

# 后端配置
backend:
  enabled: true
  
  image:
    repository: quantumflow/backend
    tag: "2.1.0"
    pullPolicy: IfNotPresent
  
  replicaCount: 5
  
  resources:
    requests:
      cpu: 500m
      memory: 1Gi
    limits:
      cpu: 2
      memory: 4Gi
  
  autoscaling:
    enabled: true
    minReplicas: 3
    maxReplicas: 20
    targetCPUUtilizationPercentage: 70
    targetMemoryUtilizationPercentage: 80
  
  service:
    type: ClusterIP
    port: 80
    targetPort: 8000
  
  ingress:
    enabled: true
    className: nginx
    annotations:
      cert-manager.io/cluster-issuer: letsencrypt-prod
    hosts:
      - host: api.quantumflow.com
        paths:
          - path: /
            pathType: Prefix
    tls:
      - secretName: quantumflow-tls
        hosts:
          - api.quantumflow.com
  
  env:
    ENVIRONMENT: production
    DEBUG: "False"
    LOG_LEVEL: WARNING
  
  secretEnv:
    SECRET_KEY: ""  # 在values-prod.yaml中覆盖
    JWT_SECRET_KEY: ""

# Celery Worker配置
worker:
  enabled: true
  
  image:
    repository: quantumflow/backend
    tag: "2.1.0"
  
  replicaCount: 3
  
  resources:
    requests:
      cpu: 1
      memory: 2Gi
    limits:
      cpu: 4
      memory: 8Gi
  
  autoscaling:
    enabled: true
    minReplicas: 2
    maxReplicas: 10

# PostgreSQL配置
postgresql:
  enabled: true
  auth:
    username: quantumflow
    password: ""  # 在values-prod.yaml中设置
    database: quantumflow
  
  primary:
    persistence:
      enabled: true
      size: 100Gi
      storageClass: fast-ssd
    
    resources:
      requests:
        cpu: 2
        memory: 8Gi
      limits:
        cpu: 4
        memory: 16Gi

# Redis配置
redis:
  enabled: true
  architecture: standalone
  
  auth:
    enabled: true
    password: ""  # 在values-prod.yaml中设置
  
  master:
    persistence:
      enabled: true
      size: 50Gi
      storageClass: fast-ssd
    
    resources:
      requests:
        cpu: 500m
        memory: 1Gi
      limits:
        cpu: 2
        memory: 4Gi

# 监控配置
monitoring:
  prometheus:
    enabled: true
  
  grafana:
    enabled: true
    adminPassword: ""  # 在values-prod.yaml中设置

# 持久化存储
persistence:
  enabled: true
  storageClass: "fast-ssd"
  size: 10Gi

# 安全配置
securityContext:
  runAsNonRoot: true
  runAsUser: 1000
  fsGroup: 1000

# 网络策略
networkPolicy:
  enabled: true

templates/deployment-backend.yaml

# quantumflow-chart/templates/deployment-backend.yaml
{{- if .Values.backend.enabled }}
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "quantumflow.fullname" . }}-backend
  namespace: {{ .Release.Namespace }}
  labels:
    {{- include "quantumflow.labels" . | nindent 4 }}
    app.kubernetes.io/component: backend
spec:
  {{- if not .Values.backend.autoscaling.enabled }}
  replicas: {{ .Values.backend.replicaCount }}
  {{- end }}
  
  selector:
    matchLabels:
      {{- include "quantumflow.selectorLabels" . | nindent 6 }}
      app.kubernetes.io/component: backend
  
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: {{ .Values.backend.rollingUpdate.maxSurge | default 2 }}
      maxUnavailable: {{ .Values.backend.rollingUpdate.maxUnavailable | default 1 }}
  
  template:
    metadata:
      annotations:
        checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
        checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
      labels:
        {{- include "quantumflow.selectorLabels" . | nindent 8 }}
        app.kubernetes.io/component: backend
        version: {{ .Values.app.version | quote }}
    
    spec:
      serviceAccountName: {{ include "quantumflow.serviceAccountName" . }}
      
      {{- with .Values.global.imagePullSecrets }}
      imagePullSecrets:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      
      securityContext:
        {{- toYaml .Values.securityContext | nindent 8 }}
      
      initContainers:
      - name: wait-for-db
        image: busybox:1.36
        command: ['sh', '-c']
        args:
        - |
          until nc -z {{ include "quantumflow.postgresql.host" . }} {{ .Values.postgresql.service.port }}; do
            echo "Waiting for PostgreSQL..."
            sleep 2
          done
      
      containers:
      - name: backend
        image: "{{ .Values.backend.image.repository }}:{{ .Values.backend.image.tag | default .Values.app.version }}"
        imagePullPolicy: {{ .Values.backend.image.pullPolicy }}
        
        ports:
        - name: http
          containerPort: {{ .Values.backend.service.targetPort }}
          protocol: TCP
        
        envFrom:
        - configMapRef:
            name: {{ include "quantumflow.fullname" . }}-config
        - secretRef:
            name: {{ include "quantumflow.fullname" . }}-secret
        
        resources:
          {{- toYaml .Values.backend.resources | nindent 10 }}
        
        livenessProbe:
          httpGet:
            path: /health/live
            port: http
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
          failureThreshold: 3
        
        readinessProbe:
          httpGet:
            path: /health/ready
            port: http
          initialDelaySeconds: 10
          periodSeconds: 5
          timeoutSeconds: 3
          failureThreshold: 2
      
      {{- with .Values.backend.nodeSelector }}
      nodeSelector:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      
      {{- with .Values.backend.affinity }}
      affinity:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      
      {{- with .Values.backend.tolerations }}
      tolerations:
        {{- toYaml . | nindent 8 }}
      {{- end }}
{{- end }}

templates/_helpers.tpl(模板辅助函数)

# quantumflow-chart/templates/_helpers.tpl

{{/*
完整名称
*/}}
{{- define "quantumflow.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}

{{/*
通用标签
*/}}
{{- define "quantumflow.labels" -}}
helm.sh/chart: {{ include "quantumflow.chart" . }}
{{ include "quantumflow.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{/*
选择器标签
*/}}
{{- define "quantumflow.selectorLabels" -}}
app.kubernetes.io/name: {{ include "quantumflow.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

{{/*
PostgreSQL主机名
*/}}
{{- define "quantumflow.postgresql.host" -}}
{{- if .Values.postgresql.enabled }}
{{- printf "%s-postgresql" (include "quantumflow.fullname" .) }}
{{- else }}
{{- .Values.externalDatabase.host }}
{{- end }}
{{- end }}

使用Helm部署

# 1. 添加依赖仓库
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

# 2. 下载依赖
cd quantumflow-chart/
helm dependency update

# 3. 验证Chart
helm lint .
helm template quantumflow . -f values-prod.yaml > rendered.yaml
cat rendered.yaml  # 检查生成的YAML

# 4. 安装到开发环境
helm install quantumflow . \
  --namespace quantumflow-dev \
  --create-namespace \
  --values values-dev.yaml \
  --dry-run  # 先模拟安装

# 确认无误后实际安装
helm install quantumflow . \
  --namespace quantumflow-dev \
  --create-namespace \
  --values values-dev.yaml

# 5. 安装到生产环境
helm install quantumflow . \
  --namespace quantumflow-prod \
  --create-namespace \
  --values values-prod.yaml \
  --set backend.image.tag=v2.1.0 \
  --set postgresql.auth.password=$(openssl rand -base64 32) \
  --set redis.auth.password=$(openssl rand -base64 32)

# 6. 查看安装状态
helm status quantumflow -n quantumflow-prod
helm get values quantumflow -n quantumflow-prod

# 7. 升级
helm upgrade quantumflow . \
  --namespace quantumflow-prod \
  --values values-prod.yaml \
  --set backend.image.tag=v2.2.0 \
  --reuse-values

# 8. 回滚
helm rollback quantumflow 1 -n quantumflow-prod

# 9. 卸载
helm uninstall quantumflow -n quantumflow-prod

🧪 测试验证

1. 本地测试(Minikube)

# 安装Minikube
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

# 启动集群
minikube start --cpus=4 --memory=8192 --kubernetes-version=v1.28.0

# 启用Ingress
minikube addons enable ingress

# 部署应用
helm install quantumflow ./quantumflow-chart \
  --namespace quantumflow-dev \
  --create-namespace \
  --values values-dev.yaml

# 访问服务
minikube service backend-svc -n quantumflow-dev --url

# 或使用端口转发
kubectl port-forward svc/backend-svc 8000:80 -n quantumflow-dev
curl http://localhost:8000/health

2. 集成测试

# quantumflow-chart/templates/tests/test-connection.yaml
apiVersion: v1
kind: Pod
metadata:
  name: "{{ include "quantumflow.fullname" . }}-test-connection"
  namespace: {{ .Release.Namespace }}
  labels:
    {{- include "quantumflow.labels" . | nindent 4 }}
  annotations:
    "helm.sh/hook": test
spec:
  containers:
  - name: wget
    image: busybox
    command: ['wget']
    args: ['{{ include "quantumflow.fullname" . }}-backend:{{ .Values.backend.service.port }}/health']
  restartPolicy: Never
# 运行Helm测试
helm test quantumflow -n quantumflow-prod

# 手动集成测试
kubectl run test-pod --rm -it --image=curlimages/curl --restart=Never -- \
  curl http://backend-svc.quantumflow-prod.svc.cluster.local/api/workflows

3. 性能测试

# 使用kubectl run创建负载测试Pod
kubectl run loadtest --image=williamyeh/hey --restart=Never --rm -it -- \
  -z 60s -c 100 -q 10 http://backend-svc.quantumflow-prod.svc.cluster.local/api/health

# 查看HPA自动扩容
watch kubectl get hpa -n quantumflow-prod

📊 监控与运维

Prometheus监控指标

# k8s/monitoring/servicemonitor.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: backend-metrics
  namespace: quantumflow-prod
spec:
  selector:
    matchLabels:
      app: backend
  endpoints:
  - port: metrics
    interval: 30s
    path: /metrics

Grafana仪表盘(JSON配置)

{
  "dashboard": {
    "title": "QuantumFlow Production Metrics",
    "panels": [
      {
        "title": "Pod CPU Usage",
        "targets": [
          {
            "expr": "sum(rate(container_cpu_usage_seconds_total{namespace=\"quantumflow-prod\",pod=~\"backend.*\"}[5m])) by (pod)"
          }
        ]
      },
      {
        "title": "Pod Memory Usage",
        "targets": [
          {
            "expr": "sum(container_memory_working_set_bytes{namespace=\"quantumflow-prod\",pod=~\"backend.*\"}) by (pod)"
          }
        ]
      },
      {
        "title": "HTTP Request Rate",
        "targets": [
          {
            "expr": "sum(rate(http_requests_total{namespace=\"quantumflow-prod\"}[5m]))"
          }
        ]
      }
    ]
  }
}

日志收集(Fluentd)

# k8s/logging/fluentd-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: fluentd-config
  namespace: kube-system
data:
  fluent.conf: |
    <source>
      @type tail
      path /var/log/containers/*quantumflow*.log
      pos_file /var/log/fluentd-containers.log.pos
      tag kubernetes.*
      read_from_head true
      <parse>
        @type json
        time_format %Y-%m-%dT%H:%M:%S.%NZ
      </parse>
    </source>
    
    <filter kubernetes.**>
      @type kubernetes_metadata
    </filter>
    
    <match kubernetes.**>
      @type elasticsearch
      host elasticsearch-master.logging.svc.cluster.local
      port 9200
      index_name quantumflow
      type_name _doc
    </match>

💡 小结

本文深入讲解了QuantumFlow的Kubernetes生产级部署方案,核心要点包括:

1. K8s核心资源

  • Deployment:无状态应用部署
  • StatefulSet:有状态应用(数据库、缓存)
  • Service:服务发现与负载均衡
  • Ingress:外部访问入口
  • ConfigMap/Secret:配置管理

2. 持久化存储

  • StorageClass:动态存储供应
  • PV/PVC:持久化卷管理
  • VolumeSnapshot:备份与恢复

3. 自动伸缩

  • HPA:基于CPU/内存/自定义指标自动扩缩容
  • VPA:垂直扩展(调整资源请求/限制)
  • Cluster Autoscaler:节点自动扩缩容

4. 发布策略

  • 滚动更新:逐步替换,零停机
  • 金丝雀发布:小流量验证新版本
  • 蓝绿部署:瞬间切换,快速回滚

5. Helm Chart

  • 一键部署完整应用栈
  • 多环境配置管理
  • 版本控制与回滚

下一篇预告:《CI/CD流水线:GitHub Actions自动化部署》

  • GitHub Actions工作流设计
  • 自动化测试(单元测试、集成测试、E2E测试)
  • Docker镜像构建与推送
  • 自动部署到K8s集群
  • Slack/钉钉通知集成

思考题

  1. 如何实现跨地域的多集群部署?(提示:Federation v2)
  2. 如何在K8s中实现灰度发布?(提示:Flagger + Istio)
  3. 如何保证数据库的高可用?(提示:PostgreSQL Operator + Patroni)

📚 参考资料

官方文档

最佳实践

开源项目参考

git clone https://github.com/quantumflow/deployment.git
cd deployment/kubernetes

包含文件

  • ✅ k8s/(所有K8s YAML文件)
  • ✅ quantumflow-chart/(完整Helm Chart)
  • ✅ scripts/deploy.sh(一键部署脚本)
  • ✅ docs/k8s-guide.md(详细操作手册)

📝 本文为《QuantumFlow工作流自动化从入门到精通》专栏第26篇,全文约3.8万字,配套代码已开源。

更多推荐