第二十六篇:《Kubernetes集群部署:生产级配置》
·
《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/钉钉通知集成
思考题
- 如何实现跨地域的多集群部署?(提示:Federation v2)
- 如何在K8s中实现灰度发布?(提示:Flagger + Istio)
- 如何保证数据库的高可用?(提示: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万字,配套代码已开源。
更多推荐

所有评论(0)