Files

59 lines
3.1 KiB
Bash
Raw Permalink Normal View History

2026-08-17 15:31:27 +08:00
#!/usr/bin/env bash
# scripts/deploy-dev.sh
#
# 把某个已经推到 ACR 的镜像部署到 Dev 环境(公司内网 Ubuntu 服务器上的 k3s 集群)。
# 见 09-build-deploy.md「Dev 环境怎么部署」。
#
# 用法:
# ./scripts/deploy-dev.sh <commit-sha 或 release tag>
#
# 前提:
# - 已连上公司 VPN
# - KUBECONFIG 指向那台机器(k3s 默认生成在 /etc/rancher/k3s/k3s.yaml
# 里面的 https://127.0.0.1:6443 要换成机器的内网 IP
# - 镜像已经由 main 分支的 docker-build-push job 推到 ACR
#
# 和 UAT/Prod 那条链路的三处区别:
# 1. 不接 CI/CD,谁要验证谁自己跑;
# 2. 不用 Key Vault——这台机器到不了 Key Vault 的 Private Endpoint
# Dev 的 Secret 就是下面这两个写死的假值(跟 local profile 同一个思路)。
# Dev 环境本来也不该碰生产密钥;
# 3. 镜像可以是任意 commit-sha,不需要等打 release tag——
# "Build once, promote across environments" 这条只针对 UAT/Prod。
set -euo pipefail
IMAGE_TAG=${1:?"必须传一个镜像 tag,比如某次 main 分支的 commit-sha"}
# 09 文档的脚本里直接用了 $CI_REGISTRY_IMAGE,但这个变量只在 GitLab job 里存在,
# 本机手动执行时是空的(set -u 下会直接报错)。这里改成可覆盖的显式变量。
REGISTRY_IMAGE=${REGISTRY_IMAGE:-"conti.azurecr.io/conti-backend"}
NAMESPACE=${NAMESPACE:-"retailapp-dev"}
echo ">> 目标:${REGISTRY_IMAGE}:${IMAGE_TAG}${NAMESPACE}"
kubectl create namespace "$NAMESPACE" --dry-run=client -o yaml | kubectl apply -f -
# Dev 的假密钥。key 名和 application.yml 里的 ${SECURITY_JWT_SECRET}/${DB_PASSWORD} 对齐——
# 09 文档的脚本写的是 SECURITY_JWT_KEYS_V1,与 07 文档的 Secret 示例(SECURITY_JWT_SECRET
# 不一致,这里按应用实际读的那个名字来。
# JWT 密钥是 base64,解码后必须 ≥ 32 字节,否则 JwtProperties 启动时就拒绝。
kubectl create secret generic conti-backend-secret -n "$NAMESPACE" \
--from-literal=SECURITY_JWT_SECRET="ZGV2LW9ubHktZmFrZS1zZWNyZXQtYXQtbGVhc3QtMzItYnl0ZXMtbG9uZw==" \
--from-literal=DB_PASSWORD="dev-only-fake-password" \
--from-literal=F6_API_KEY="dev-only-fake-api-key" \
--dry-run=client -o yaml | kubectl apply -f -
kubectl apply -f k8s/rbac.yaml
kubectl apply -f k8s/configmap-dev.yaml -n "$NAMESPACE"
# 用 sed 把镜像替换掉再 apply,而不是"apply 之后再 kubectl set image"——
# 后者每跑一次都会先把镜像重置成 __TAG__ 占位符(触发一次 ImagePullBackOff)再改回来。
sed "s|registry.example.com/conti-backend:__TAG__|${REGISTRY_IMAGE}:${IMAGE_TAG}|" \
k8s/deployment-dev.yaml | kubectl apply -f -
# 迁移失败会让新 Pod 起不来、这里超时退出,但线上(Dev)服务不受影响——
# maxUnavailable: 0 保证旧 Pod 还在跑。这个失败模式是刻意选的,
# 比"迁移半途成功、服务带着不一致的 schema 上线"要好得多。
kubectl rollout status deployment/conti-backend -n "$NAMESPACE" --timeout=180s
echo ">> 完成。查看日志:kubectl logs -f deployment/conti-backend -n ${NAMESPACE}"