kra-new/deploy/Jenkinsfile

161 lines
8.2 KiB
Groovy
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

pipeline {
agent any
options {
disableConcurrentBuilds()
}
environment {
// ══════════════════════════════════════════════════════════════════
// 项目级参数 —— 基于 kra 模板的新项目只需修改本块。
// 这些变量自动 export 到 shell由 envsubst 白名单渲染进 k8s 清单。
// ══════════════════════════════════════════════════════════════════
APP_NAME = 'kra' // 派生:服务名/Secret名/库名/hostPath/镜像后缀
IMAGE_REPO = 'library/kra' // Harbor 中镜像仓库路径
REGISTRY = '192.168.200.132'
BIN_NAME = 'kratos-admin' // Makefile build 的产物名
KRA_REPLICAS = '3'
KRA_FRONTEND_NODEPORT = '30080'
KRA_BACKEND_NODEPORT = '30081'
KRA_MYSQL_IMAGE = 'docker.m.daocloud.io/library/mysql:8.4'
KRA_REDIS_IMAGE = 'docker.m.daocloud.io/library/redis:7-alpine'
GO_IMAGE = 'docker.m.daocloud.io/golang:1.25'
NODE_IMAGE = 'docker.m.daocloud.io/node:20-slim'
PNPM_VERSION = '10.15.1'
CACHE_DIR = '/var/lib/kra-ci-cache' // Jenkins 宿主机依赖缓存根目录
// 集群映射dev -> 测试集群, main -> 生产集群)
DEV_CLUSTER_HOST = '192.168.200.128'
PROD_CLUSTER_HOST = '192.168.200.129'
// Jenkins 凭据 ID新项目若沿用同一套凭据可不改
CRED_HARBOR_PUSH = 'harbor-library-push'
CRED_KUBECONFIG_DEV = 'kra-rke2-128-kubeconfig'
CRED_KUBECONFIG_PROD = 'kra-rke2-129-kubeconfig'
CRED_MYSQL_PASSWORD = 'kra-mysql-root-password'
CRED_JWT_SIGNING_KEY = 'kra-jwt-signing-key'
// k8s 清单渲染白名单:只替换列出的变量,避免误伤清单内 shell 变量(如 probe 里的 $MYSQL_ROOT_PASSWORD
K8S_RENDER_VARS = '$KRA_APP $KRA_NAMESPACE $KRA_ENV $KRA_BACKEND_IMAGE $KRA_FRONTEND_IMAGE $KRA_REPLICAS $KRA_FRONTEND_NODEPORT $KRA_BACKEND_NODEPORT $KRA_MYSQL_IMAGE $KRA_REDIS_IMAGE $BIN_NAME'
}
stages {
stage('Select environment') {
steps {
script {
// 分支来源优先级:
// 1) env.gitlabBranch —— GitLab Jenkins 集成/webhook 触发时由 gitlab-plugin 注入push payload 的 ref
// 2) env.BRANCH_NAME —— 多分支流水线场景
// 3) JOB_NAME —— 手动触发兜底:名字以 -dev 结尾按 dev 部署,否则默认 main
def branch = env.gitlabBranch ?: env.BRANCH_NAME
if (!branch) {
branch = env.JOB_NAME.endsWith('-dev') ? 'dev' : 'main'
}
echo "gitlabBranch='${env.gitlabBranch ?: ''}' BRANCH_NAME='${env.BRANCH_NAME ?: ''}' -> resolved branch='${branch}'"
env.KRA_BRANCH = branch
if (branch == 'dev') {
env.KRA_NAMESPACE = "${env.APP_NAME}-dev"
env.KRA_ENV = 'development'
env.KRA_CLUSTER_HOST = env.DEV_CLUSTER_HOST
env.KUBECONFIG_CREDENTIALS = env.CRED_KUBECONFIG_DEV
} else if (branch == 'main') {
env.KRA_NAMESPACE = "${env.APP_NAME}-prod"
env.KRA_ENV = 'production'
env.KRA_CLUSTER_HOST = env.PROD_CLUSTER_HOST
env.KUBECONFIG_CREDENTIALS = env.CRED_KUBECONFIG_PROD
} else {
error("Unsupported branch: ${branch}. Only dev and main deploy.")
}
}
}
}
stage('Checkout branch') {
steps {
// job 的 SCM branch spec 固定(如 */main集成触发时按实际推送分支重新检出
// 保证单 job 同时服务 dev/main 两个环境。
checkout([$class: 'GitSCM',
branches: [[name: "*/${env.KRA_BRANCH}"]],
userRemoteConfigs: [[credentialsId: 'gitlab-root-http', url: 'http://192.168.200.130/root/kra.git']]])
}
}
stage('Test') {
steps {
sh '''
set -eu
HOST_WORKSPACE=$(printf '%s' "$WORKSPACE" | sed 's#/var/jenkins_home#/opt/jenkins#')
docker run --rm -e GOPROXY=https://goproxy.cn,direct \\
-v "$HOST_WORKSPACE:/src" \\
-v "$CACHE_DIR/go-mod:/go/pkg/mod" \\
-v "$CACHE_DIR/go-build:/root/.cache/go-build" \\
-w /src "$GO_IMAGE" sh -c "git config --global --add safe.directory /src && go test ./... && make build"
'''
sh '''
set -eu
HOST_WORKSPACE=$(printf '%s' "$WORKSPACE" | sed 's#/var/jenkins_home#/opt/jenkins#')
docker run --rm \\
-e COREPACK_NPM_REGISTRY=https://registry.npmmirror.com \\
-v "$HOST_WORKSPACE/web:/app" \\
-v "$CACHE_DIR/pnpm-store:/root/.local/share/pnpm/store" \\
-v "$CACHE_DIR/corepack:/root/.cache/node/corepack" \\
-w /app "$NODE_IMAGE" bash -lc "corepack enable && corepack prepare pnpm@$PNPM_VERSION --activate && pnpm install --frozen-lockfile && pnpm build"
# 前端 Nginx 配置模板渲染proxy_pass 指向 ${APP_NAME}-backend 服务)。
# KRA_APP 必须在此显式导出envsubst 会把未设置的变量替换为空串。
export KRA_APP="$APP_NAME"
envsubst '$KRA_APP' < web/.docker-compose/nginx/conf.d/my.conf > web/nginx.k8s.conf
'''
}
}
stage('Build and push images') {
steps {
script {
env.IMAGE_TAG = "${env.KRA_BRANCH}-${env.GIT_COMMIT.take(12)}"
}
withCredentials([usernamePassword(credentialsId: env.CRED_HARBOR_PUSH, usernameVariable: 'HARBOR_USER', passwordVariable: 'HARBOR_PASSWORD')]) {
sh '''
set -eu
echo "$HARBOR_PASSWORD" | docker login "$REGISTRY" --username "$HARBOR_USER" --password-stdin
docker build --build-arg BIN_NAME="$BIN_NAME" -t "$REGISTRY/$IMAGE_REPO-backend:$IMAGE_TAG" .
docker build -t "$REGISTRY/$IMAGE_REPO-frontend:$IMAGE_TAG" web
docker push "$REGISTRY/$IMAGE_REPO-backend:$IMAGE_TAG"
docker push "$REGISTRY/$IMAGE_REPO-frontend:$IMAGE_TAG"
docker logout "$REGISTRY"
'''
}
}
}
stage('Deploy to Rancher cluster') {
steps {
withCredentials([file(credentialsId: "${env.KUBECONFIG_CREDENTIALS}", variable: 'KUBECONFIG_FILE'),
string(credentialsId: env.CRED_MYSQL_PASSWORD, variable: 'KRA_MYSQL_ROOT_PASSWORD'),
string(credentialsId: env.CRED_JWT_SIGNING_KEY, variable: 'KRA_JWT_SIGNING_KEY'),
usernamePassword(credentialsId: env.CRED_HARBOR_PUSH, usernameVariable: 'HARBOR_USER', passwordVariable: 'HARBOR_PASSWORD')]) {
sh '''
set -eu
export KUBECONFIG="$KUBECONFIG_FILE"
kubectl create namespace "$KRA_NAMESPACE" --dry-run=client -o yaml | kubectl apply -f -
kubectl -n "$KRA_NAMESPACE" create secret docker-registry harbor-registry \\
--docker-server="$REGISTRY" --docker-username="$HARBOR_USER" --docker-password="$HARBOR_PASSWORD" \\
--dry-run=client -o yaml | kubectl apply -f -
kubectl -n "$KRA_NAMESPACE" create secret generic "${APP_NAME}-runtime" \\
--from-literal=mysql-root-password="$KRA_MYSQL_ROOT_PASSWORD" \\
--from-literal=database-source="root:${KRA_MYSQL_ROOT_PASSWORD}@tcp(${APP_NAME}-mysql:3306)/${APP_NAME}?charset=utf8mb4&parseTime=True&loc=Local" \\
--from-literal=jwt-signing-key="$KRA_JWT_SIGNING_KEY" \\
--from-literal=redis-addr="${APP_NAME}-redis:6379" \\
--dry-run=client -o yaml | kubectl apply -f -
export KRA_APP="$APP_NAME"
export KRA_BACKEND_IMAGE="$REGISTRY/$IMAGE_REPO-backend:$IMAGE_TAG"
export KRA_FRONTEND_IMAGE="$REGISTRY/$IMAGE_REPO-frontend:$IMAGE_TAG"
envsubst "$K8S_RENDER_VARS" < deploy/k8s/kra.yaml | kubectl apply -f -
kubectl -n "$KRA_NAMESPACE" rollout status deployment/${APP_NAME}-backend --timeout=10m
kubectl -n "$KRA_NAMESPACE" rollout status deployment/${APP_NAME}-frontend --timeout=10m
'''
}
}
}
}
}