Files
seclusion/deploy/k8s/README.md
charilezhou 08bd6397c8 ci: 添加 Gitea Actions CI/CD 和 Knative 部署配置
- 添加 CI workflow(PR 构建检查)
- 添加 Deploy workflow(main 分支自动部署)
- 添加 Web/API 多阶段 Dockerfile
- 添加 Knative Service 配置(自动扩缩容)
- 添加 K8s ConfigMap、Secret、Namespace 配置
- 添加 .dockerignore 优化构建

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 17:38:28 +08:00

6.5 KiB
Raw Blame History

Knative 部署指南

本项目使用 Knative Serving 在 Kubernetes 上部署应用。

目录结构

.gitea/workflows/
├── ci.yaml          # PR 构建检查
└── deploy.yaml      # 主分支部署

apps/
├── web/Dockerfile   # Web 应用 Dockerfile
└── api/Dockerfile   # API 应用 Dockerfile

deploy/k8s/
├── namespace.yaml   # 命名空间
├── configmap.yaml   # 环境变量配置
├── secret.yaml      # 敏感信息配置
├── web-ksvc.yaml    # Web Knative Service
└── api-ksvc.yaml    # API Knative Service

前置要求

  1. Kubernetes 集群:需要安装 Knative Serving
  2. Gitea Container Registry:镜像仓库地址 gitea.tegical.world
  3. kubectl:本地安装 kubectl 用于手动部署

Gitea Secrets 配置

在 Gitea 仓库设置 → Secrets 中配置:

Secret 名称 说明 生成方式
REGISTRY_USERNAME Gitea 容器镜像仓库用户名 -
REGISTRY_PASSWORD Gitea 容器镜像仓库密码 Token 或密码
KUBECONFIG Base64 编码的 kubeconfig cat ~/.kube/config | base64

配置修改

1. ConfigMap (deploy/k8s/configmap.yaml)

data:
  # 修改为实际的 API 地址
  NEXT_PUBLIC_API_URL: "https://api.example.com"

  # 是否启用加密
  NEXT_PUBLIC_ENABLE_ENCRYPTION: "false"
  ENABLE_ENCRYPTION: "false"

2. Secret (deploy/k8s/secret.yaml)

方式一:直接编辑文件(不推荐)

stringData:
  DATABASE_URL: "postgresql://user:pass@host:5432/db"
  REDIS_URL: "redis://host:6379"
  JWT_SECRET: "your-secret-here"
  # ... 其他配置

方式二:使用 kubectl 创建(推荐)

kubectl create secret generic seclusion-secret -n seclusion \
  --from-literal=DATABASE_URL='postgresql://user:pass@host:5432/db' \
  --from-literal=REDIS_URL='redis://host:6379' \
  --from-literal=JWT_SECRET='your-jwt-secret' \
  --from-literal=JWT_EXPIRES_IN='7d' \
  --from-literal=JWT_REFRESH_SECRET='your-refresh-secret' \
  --from-literal=JWT_REFRESH_EXPIRES_IN='30d' \
  --from-literal=ENCRYPTION_KEY='' \
  --from-literal=NEXT_PUBLIC_ENCRYPTION_KEY=''

3. Knative Service 配置

自动扩缩容配置 (deploy/k8s/web-ksvc.yamldeploy/k8s/api-ksvc.yaml)

metadata:
  annotations:
    # 最小实例数0 允许缩容到零)
    autoscaling.knative.dev/min-scale: "1"
    # 最大实例数
    autoscaling.knative.dev/max-scale: "10"
    # 每个实例的目标并发请求数
    autoscaling.knative.dev/target: "100"

资源限制

resources:
  requests:
    memory: "256Mi"
    cpu: "100m"
  limits:
    memory: "512Mi"
    cpu: "500m"

部署流程

自动部署(推荐)

  1. 创建 PR → 触发 CI workflow 进行构建检查
  2. 合并到 main → 自动构建镜像并部署到 Knative

手动部署

# 1. 构建镜像
docker build -f apps/web/Dockerfile -t gitea.tegical.world/tegical/seclusion-web:latest .
docker build -f apps/api/Dockerfile -t gitea.tegical.world/tegical/seclusion-api:latest .

# 2. 推送镜像
docker push gitea.tegical.world/tegical/seclusion-web:latest
docker push gitea.tegical.world/tegical/seclusion-api:latest

# 3. 部署到 Knative
kubectl apply -f deploy/k8s/namespace.yaml
kubectl apply -f deploy/k8s/configmap.yaml
kubectl apply -f deploy/k8s/secret.yaml
kubectl apply -f deploy/k8s/web-ksvc.yaml
kubectl apply -f deploy/k8s/api-ksvc.yaml

# 4. 等待服务就绪
kubectl wait --for=condition=Ready ksvc/seclusion-web -n seclusion --timeout=300s
kubectl wait --for=condition=Ready ksvc/seclusion-api -n seclusion --timeout=300s

# 5. 查看服务 URL
kubectl get ksvc -n seclusion

查看部署状态

# 查看 Knative Service 状态
kubectl get ksvc -n seclusion

# 查看 Pod 状态
kubectl get pods -n seclusion

# 查看服务日志
kubectl logs -n seclusion -l serving.knative.dev/service=seclusion-web
kubectl logs -n seclusion -l serving.knative.dev/service=seclusion-api

# 查看服务详情
kubectl describe ksvc seclusion-web -n seclusion
kubectl describe ksvc seclusion-api -n seclusion

域名配置

Knative 会自动为每个 Service 分配一个 URL格式通常为

  • http://seclusion-web.seclusion.{knative-domain}
  • http://seclusion-api.seclusion.{knative-domain}

配置自定义域名

创建 deploy/k8s/domain-mapping.yaml

apiVersion: serving.knative.dev/v1alpha1
kind: DomainMapping
metadata:
  name: seclusion.example.com
  namespace: seclusion
spec:
  ref:
    name: seclusion-web
    kind: Service
    apiVersion: serving.knative.dev/v1
---
apiVersion: serving.knative.dev/v1alpha1
kind: DomainMapping
metadata:
  name: api.seclusion.example.com
  namespace: seclusion
spec:
  ref:
    name: seclusion-api
    kind: Service
    apiVersion: serving.knative.dev/v1

应用配置:

kubectl apply -f deploy/k8s/domain-mapping.yaml

故障排查

镜像拉取失败

# 检查镜像仓库凭证
kubectl get secret -n seclusion

# 如需要私有镜像,创建 pull secret
kubectl create secret docker-registry gitea-registry \
  --docker-server=gitea.tegical.world \
  --docker-username=<username> \
  --docker-password=<password> \
  -n seclusion

# 在 Knative Service 中引用
spec:
  template:
    spec:
      imagePullSecrets:
        - name: gitea-registry

服务无法就绪

# 查看事件
kubectl get events -n seclusion --sort-by='.lastTimestamp'

# 查看 Revision 状态
kubectl get revision -n seclusion

# 查看详细日志
kubectl logs -n seclusion -l serving.knative.dev/service=seclusion-web --tail=100

数据库连接失败

确认 DATABASE_URLREDIS_URL 配置正确,且集群内可访问数据库。

回滚

# 查看历史 Revision
kubectl get revision -n seclusion

# 回滚到指定 Revision
kubectl patch ksvc seclusion-web -n seclusion --type='json' \
  -p='[{"op": "replace", "path": "/spec/traffic", "value": [{"revisionName": "seclusion-web-00001", "percent": 100}]}]'

性能优化

1. 调整并发限制

spec:
  template:
    spec:
      # 0 表示无限制,建议设置合理值
      containerConcurrency: 100

2. 调整扩缩容策略

metadata:
  annotations:
    # 缩容窗口期(秒)
    autoscaling.knative.dev/scale-down-delay: "30s"
    # 稳定窗口期(秒)
    autoscaling.knative.dev/window: "60s"

3. 启用缓存优化

在 Dockerfile 中已使用多阶段构建和 BuildKit 缓存优化构建速度。