阿里云 ACK 部署 Runbook¶
本文说明如何在 阿里云容器服务 ACK 上部署本仓库全栈:myapp、代理商 backend、backend-worker、OSS storage 微服务、双前端、PostgreSQL、Redis 及 Nginx Ingress(SLB)。
清单与脚本位于仓库 deploy/ACK/,与本地 K3s(deploy/k3s/)完全分离,共用 deploy/k3s/base/ 应用 Deployment/Service 作为单一来源。
前置条件¶
| 项 | 要求 |
|---|---|
| ACK 集群 | 已创建,kubectl get nodes 正常 |
| kubeconfig | 建议保存为 ~/.kube/ack-harness-config |
| 个人 ACR | 控制台获取 crpi-* 公网/VPC 域名 |
| 环境变量 | 根目录 .env 配置 ACR_*;src/backend/.env、src/storage/.env 配置业务密钥 |
验证连通:
$env:KUBECONFIG = "$env:USERPROFILE\.kube\ack-harness-config"
kubectl get nodes
架构概览¶
SLB (Ingress EXTERNAL-IP)
│
ingress-nginx-controller
│
┌────────────────────┼────────────────────┐
│ │ │
agent.harness.local canvas.harness.local upload.harness.local
│ │ │
agent-frontend infinitecanvas-frontend storage (:8002)
│ │
└──────── /api ───────────────► backend (:8001)
│
/api/storage ──────► storage (:8002)
│
postgres ◄──────┴──────► redis
myapp (:8000)
- 命名空间:
harness-app - 镜像:本机 push 到 ACR 公网域名;ACK 节点 pull VPC 内网域名
- 持久卷:
alicloud-disk-essd(最小 20Gi,见 ACK patches)
配置 ACR(.env)¶
个人版必须使用控制台给出的 crpi-* 域名:
ACR_REGION=cn-hangzhou
# 公网:本机 push / GitHub Actions
ACR_REGISTRY=crpi-xxxx.cn-hangzhou.personal.cr.aliyuncs.com
# VPC 内网:ACK 节点 pull
ACR_VPC_REGISTRY=crpi-xxxx-vpc.cn-hangzhou.personal.cr.aliyuncs.com
ACR_NAMESPACE=你的命名空间
ACR_USERNAME=你的ACR用户名
ACR_PASSWORD=你的ACR密码
make ack-secrets 会将 deploy/ACK/kustomization.yaml 中的镜像地址同步为 VPC 内网 前缀。
首次部署¶
按顺序执行,不可跳过 push:
$env:KUBECONFIG = "$env:USERPROFILE\.kube\ack-harness-config"
# 1. 推送 postgres / redis(ACK 无法直连 Docker Hub)
make ack-push-base
# 2. 构建并推送 5 个业务镜像
make ack-push
# 3. 生成 Secret + apply 清单
make ack-deploy
# 4. 安装 Nginx Ingress(SLB)
make ack-ingress
# 5. 查看状态
make ack-status
kubectl get svc -n ingress-nginx ingress-nginx-controller
本机访问¶
- 查看 SLB 公网 IP(
EXTERNAL-IP列):
kubectl get svc -n ingress-nginx ingress-nginx-controller
- 在本机
hosts绑定(示例 IP 替换为实际 SLB):
121.40.19.48 agent.harness.local
121.40.19.48 canvas.harness.local
121.40.19.48 upload.harness.local
121.40.19.48 myapp.harness.local
- 浏览器使用 HTTP(非 HTTPS)访问:http://agent.harness.local
| 主机 | 服务 |
|---|---|
agent.harness.local |
代理商前端 + /api → backend |
canvas.harness.local |
Infinite Canvas + /api → backend;/api/storage → storage |
upload.harness.local |
OSS storage 微服务 |
myapp.harness.local |
myapp API |
日常更新¶
$env:KUBECONFIG = "$env:USERPROFILE\.kube\ack-harness-config"
make ack-push # 推送不可变 tag(yyyyMMdd-HHmm-<gitsha>)+ latest 别名
make ack-deploy # 写入 image-tags.env → kustomization newTag 并 apply
单服务示例(Canvas):
make ack-push-infinitecanvas-frontend
make ack-deploy
仅改密钥时:make ack-deploy。
回滚¶
make ack-image-tags # 查看当前 tag 与本地推送历史
make ack-rollback SERVICE=infinitecanvas-frontend TAG=20260722-0907-a1b2c3d
详见 deploy/ACK/README.md · 镜像版本与回滚。
Make 命令对照¶
| 命令 | 作用 |
|---|---|
make ack-push-base |
推送 postgres:16-alpine、redis:7 到个人 ACR |
make ack-push |
构建并 push 业务镜像(不可变 tag + latest) |
make ack-secrets |
生成 Secret,并把 image-tags.env 同步到 kustomization |
make ack-deploy |
ack-secrets + kubectl apply -k deploy/ACK |
make ack-image-tags |
查看当前部署 tag / 推送历史 |
make ack-rollback SERVICE=… TAG=… |
回滚到指定不可变 tag |
make ack-ingress |
安装 Nginx Ingress(含阿里云镜像补丁) |
make ack-status |
查看 Pod / Service / Ingress |
排错¶
网站无法访问 / Ingress 无 ADDRESS¶
根因多为 ingress-nginx-controller 未 Ready(admission Job 无法从 registry.k8s.io 拉镜像)。
kubectl get pods -n ingress-nginx
kubectl get ingress -n harness-app
处理:
- 重试
make ack-ingress(脚本会替换为阿里云镜像) - 或 ACK 控制台 → 组件管理 → 安装官方 Nginx Ingress
确认 controller Running 且 Ingress ADDRESS 列有 SLB IP 后,用 curl 验证:
curl.exe -H "Host: agent.harness.local" http://<SLB-IP>/
Redis Pod Pending(PVC 未绑定) {#redis-pvc}¶
阿里云 ESSD 云盘 最小 20Gi。若 PVC 申请小于 20Gi,会看到:
requested size 10GiB is less than minimum 20GiB
ACK patch 已设为 20Gi(deploy/ACK/patches/redis-storageclass.yaml)。若集群中仍有旧 PVC:
kubectl delete statefulset redis -n harness-app
kubectl delete pvc data-redis-0 -n harness-app
kubectl apply -k deploy/ACK
backend-worker Init 卡住¶
Worker Deployment 的 Init 容器会等待 redis Service 返回 PONG。Redis 就绪后 worker 自动启动。
kubectl get pods -n harness-app -l app=backend-worker
kubectl logs -n harness-app deploy/backend-worker -c wait-redis
短信队列需 MESSAGING_ENABLED=true(K8s ConfigMap 默认已开启)。
镜像已 push 但 Pod 仍是旧版本¶
确认 ack-deploy 已把新不可变 tag 写入 newTag:
make ack-image-tags
kubectl get deploy -n harness-app <name> -o jsonpath="{.spec.template.spec.containers[0].image}{'\n'}"
kubectl rollout restart deployment/<name> -n harness-app # 必要时
新版本有问题请回滚:make ack-rollback SERVICE=<name> TAG=<旧tag>(勿只依赖 rollout undo + latest)。
ImagePullBackOff(业务镜像)¶
- 确认
make ack-push/make ack-push-base已成功,且 ACR 上存在对应不可变 tag - 确认
deploy/ACK/kustomization.yaml使用 VPC 域名(ack-secrets会同步) - 确认
acr-registrySecret 存在于harness-app命名空间
GitHub Actions 自动构建¶
工作流文件:.github/workflows/acr-build-push.yml(push main 后 build + push 到 ACR)。
| 类型 | 名称 |
|---|---|
| Secret | ACR_USERNAME、ACR_PASSWORD |
| Variable | ACR_REGISTRY(公网 crpi-*.personal.cr.aliyuncs.com)、ACR_NAMESPACE |
部署到 ACK 仍需本地执行 make ack-deploy(需 kubeconfig)。详见 ACR Build Push 工作流。
与 K3s 本地部署的对照¶
| 维度 | K3s(Rancher Desktop) | ACK |
|---|---|---|
| 目录 | deploy/k3s/ |
deploy/ACK/ |
| 命令 | make k3s-deploy |
ack-push-base → ack-push → ack-deploy → ack-ingress |
| Ingress | Traefik + *.localhost |
SLB + Nginx + *.harness.local + hosts |
| 镜像 | 本地 build | 个人 ACR |
| 持久卷 | local-path 等 | alicloud-disk-essd ≥ 20Gi |
相关文档¶
仓库脚本与 Kustomize 清单:deploy/ACK/(与 deploy/k3s/base/ 共用应用清单)。