AppFlowy-Cloud云原生:Kubernetes部署与运维
概述:为什么选择Kubernetes部署?
还在为传统Docker Compose部署的运维复杂度而头疼?企业级应用需要高可用、弹性伸缩和自动化运维能力,这正是Kubernetes(K8s)的核心优势。本文将手把手教你将AppFlowy-Cloud从单机Docker Compose部署升级到生产级的Kubernetes集群部署。
通过本文你将掌握:
- ✅ AppFlowy-Cloud在K8s中的完整部署架构
- ✅ 生产环境配置的最佳实践
- ✅ 高可用性和弹性伸缩策略
- ✅ 监控、日志和运维自动化方案
- ✅ 从开发到生产的全链路部署流程
架构设计:云原生部署蓝图
整体架构图
核心组件服务映射
| Docker Compose服务 | Kubernetes资源类型 | 部署策略 |
|---|---|---|
| appflowy_cloud | Deployment + Service | 多副本,HPA自动伸缩 |
| gotrue | Deployment + Service | 单副本,会话亲和 |
| admin_frontend | Deployment + Service | 多副本 |
| appflowy_web | Deployment + Service | 多副本 |
| postgres | StatefulSet | 主从集群 |
| redis | StatefulSet | 哨兵模式 |
| minio | StatefulSet | 分布式模式 |
| nginx | Ingress | 外部负载均衡 |
环境准备与工具链
必备工具清单
# Kubernetes集群管理
kubectl version --client
helm version
# 容器镜像工具
docker version
buildx version
# 配置管理
envsubst --version
yq --version
# 监控工具
prometheus --version
grafana-cli --version
集群资源要求
| 资源类型 | 开发环境 | 生产环境 | 说明 |
|---|---|---|---|
| CPU | 4核 | 16核 | 建议多节点分布 |
| 内存 | 8GB | 32GB | 按工作负载分配 |
| 存储 | 50GB | 200GB+ | SSD推荐 |
| 节点数 | 1-3 | 3-5+ | 高可用要求 |
部署实战:从零搭建K8s集群
步骤1:创建命名空间和配置
# appflowy-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: appflowy
labels:
name: appflowy
environment: production
# 创建命名空间
kubectl apply -f appflowy-namespace.yaml
# 设置默认命名空间
kubectl config set-context --current --namespace=appflowy
步骤2:配置管理(ConfigMap和Secret)
# appflowy-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: appflowy-config
namespace: appflowy
data:
APPFLOWY_ENVIRONMENT: "production"
RUST_LOG: "info"
APPFLOWY_ACCESS_CONTROL: "true"
APPFLOWY_DATABASE_MAX_CONNECTIONS: "40"
APPFLOWY_WEBSOCKET_MAILBOX_SIZE: "6000"
# 从deploy.env生成Secret
kubectl create secret generic appflowy-secrets \
--namespace=appflowy \
--from-file=.env=deploy.env \
--dry-run=client -o yaml > appflowy-secrets.yaml
步骤3:数据库服务部署(PostgreSQL集群)
# postgres-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
namespace: appflowy
spec:
serviceName: "postgres"
replicas: 3
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: pgvector/pgvector:pg16
env:
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: appflowy-secrets
key: POSTGRES_USER
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: appflowy-secrets
key: POSTGRES_PASSWORD
- name: POSTGRES_DB
value: postgres
ports:
- containerPort: 5432
volumeMounts:
- name: postgres-data
mountPath: /var/lib/postgresql/data
livenessProbe:
exec:
command:
- pg_isready
- -U
- postgres
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
exec:
command:
- pg_isready
- -U
- postgres
initialDelaySeconds: 5
periodSeconds: 5
volumeClaimTemplates:
- metadata:
name: postgres-data
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "ssd"
resources:
requests:
storage: 50Gi
步骤4:应用服务部署(Deployment模式)
# appflowy-cloud-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: appflowy-cloud
namespace: appflowy
labels:
app: appflowy-cloud
spec:
replicas: 3
selector:
matchLabels:
app: appflowy-cloud
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: appflowy-cloud
version: v1.0.0
spec:
containers:
- name: appflowy-cloud
image: appflowyinc/appflowy_cloud:latest
envFrom:
- configMapRef:
name: appflowy-config
- secretRef:
name: appflowy-secrets
ports:
- containerPort: 8000
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 5
periodSeconds: 5
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "500m"
步骤5:服务暴露(Service和Ingress)
# appflowy-service.yaml
apiVersion: v1
kind: Service
metadata:
name: appflowy-cloud
namespace: appflowy
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8000"
spec:
selector:
app: appflowy-cloud
ports:
- name: http
port: 8000
targetPort: 8000
type: ClusterIP
# appflowy-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: appflowy-ingress
namespace: appflowy
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
spec:
tls:
- hosts:
- appflowy.your-domain.com
secretName: appflowy-tls
rules:
- host: appflowy.your-domain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: appflowy-cloud
port:
number: 8000
- path: /gotrue
pathType: Prefix
backend:
service:
name: gotrue
port:
number: 9999
高级配置:生产环境优化
自动伸缩策略(HPA)
# appflowy-hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: appflowy-cloud-hpa
namespace: appflowy
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: appflowy-cloud
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
资源配额管理
# resource-quotas.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: appflowy-quota
namespace: appflowy
spec:
hard:
requests.cpu: "8"
requests.memory: 16Gi
limits.cpu: "16"
limits.memory: 32Gi
requests.storage: 100Gi
persistentvolumeclaims: "10"
services.loadbalancers: "2"
services.nodeports: "5"
监控与日志:运维可视化
Prometheus监控配置
# appflowy-service-monitor.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: appflowy-monitor
namespace: appflowy
labels:
app: appflowy
release: prometheus
spec:
selector:
matchLabels:
app: appflowy-cloud
endpoints:
- port: http
interval: 30s
path: /metrics
namespaceSelector:
matchNames:
- appflowy
关键监控指标
| 指标类型 | 监控项 | 告警阈值 | 说明 |
|---|---|---|---|
| 应用性能 | http_request_duration_seconds | >500ms | 请求延迟 |
| 数据库 | postgres_connections_total | >80% | 连接池使用率 |
| 缓存 | redis_memory_used_bytes | >85% | 内存使用率 |
| 存储 | minio_free_bytes | <10% | 磁盘空间 |
| 业务 | active_websocket_connections | >5000 | 活跃连接数 |
日志收集架构
持续部署:GitOps工作流
ArgoCD应用定义
# appflowy-argocd-app.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: appflowy-cloud
namespace: argocd
spec:
project: default
source:
repoURL: 'https://gitcode.com/GitHub_Trending/ap/AppFlowy-Cloud'
targetRevision: HEAD
path: k8s/
helm:
valueFiles:
- values-production.yaml
destination:
server: 'https://kubernetes.default.svc'
namespace: appflowy
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
ignoreDifferences:
- group: apps
kind: Deployment
jsonPointers:
- /spec/replicas
GitHub Actions部署流水线
# .github/workflows/deploy-to-k8s.yaml
name: Deploy to Kubernetes
on:
push:
branches: [ main ]
paths:
- 'k8s/**'
- 'src/**'
- 'Cargo.toml'
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ secrets.REGISTRY_URL }}
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Build and push AppFlowy Cloud
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
push: true
tags: |
${{ secrets.REGISTRY_URL }}/appflowy-cloud:${{ github.sha }}
${{ secrets.REGISTRY_URL }}/appflowy-cloud:latest
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Deploy to Kubernetes
uses: steebchen/kubectl@v2
with:
config: ${{ secrets.KUBECONFIG }}
command: |
set -x
kubectl set image deployment/appflowy-cloud \
appflowy-cloud=${{ secrets.REGISTRY_URL }}/appflowy-cloud:${{ github.sha }} \
-n appflowy
kubectl rollout status deployment/appflowy-cloud -n appflowy --timeout=300s
故障排除与运维实践
常见问题诊断命令
# 查看Pod状态
kubectl get pods -n appflowy -o wide
# 查看服务端点
kubectl get endpoints -n appflowy
# 查看事件日志
kubectl get events -n appflowy --sort-by=.lastTimestamp
# 进入容器调试
kubectl exec -it <pod-name> -n appflowy -- /bin/bash
# 查看应用日志
kubectl logs -f deployment/appflowy-cloud -n appflowy
# 端口转发本地调试
kubectl port-forward svc/appflowy-cloud 8000:8000 -n appflowy
性能优化建议
-
数据库连接池优化
# 在ConfigMap中调整 APPFLOWY_DATABASE_MAX_CONNECTIONS: "60" POSTGRES_MAX_CONNECTIONS: "100" -
Redis缓存策略
# 启用Redis持久化和内存优化 maxmemory-policy: volatile-lru maxmemory: 1gb -
镜像拉取策略
# 加快容器启动速度 imagePullPolicy: IfNotPresent -
就绪和存活探针优化
# 调整探针间隔避免频繁重启 initialDelaySeconds: 15 periodSeconds: 10 failureThreshold: 3
安全加固:生产环境最佳实践
网络策略隔离
# network-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: appflowy-network-policy
namespace: appflowy
spec:
podSelector:
matchLabels:
app: appflowy-cloud
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: appflowy-web
- podSelector:
matchLabels:
app: admin-frontend
ports:
- protocol: TCP
port: 8000
egress:
- to:
- podSelector:
matchLabels:
app: postgres
ports:
- protocol: TCP
port: 5432
- to:
- podSelector:
matchLabels:
app: redis
ports:
- protocol: TCP
port: 6379
RBAC权限控制
# appflowy-rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: appflowy
name: appflowy-role
rules:
- apiGroups: [""]
resources: ["pods", "services", "endpoints"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources: ["deployments", "replicasets"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: appflowy
name: appflowy-rolebinding
subjects:
- kind: ServiceAccount
name: appflowy-serviceaccount
namespace: appflowy
roleRef:
kind: Role
name: appflowy-role
apiGroup: rbac.authorization.k8s.io
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



