#!/usr/bin/env bash # scripts/deploy-dev.sh # # 把某个已经推到 ACR 的镜像部署到 Dev 环境(公司内网 Ubuntu 服务器上的 k3s 集群)。 # 见 09-build-deploy.md「Dev 环境怎么部署」。 # # 用法: # ./scripts/deploy-dev.sh # # 前提: # - 已连上公司 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}"