本脚本适用于基于Jenkins和Kubernetes的多模块微服务一键部署流水线,涵盖从Maven打包到Docker镜像构建及K8s滚动发布的完整流程。脚本基于通用Docker部署脚本优化,特别适合单工程下多module的微服务项目。
脚本变量
定义、设置变量主要是为了形成通用型脚本,部署多个服务尤其微服务时,编写好一个流水线脚本后,其他流水线可以直接复制使用,只需修改此处变量即可。
注意:部分变量嵌套使用MODULE_NAME、MODULE_PATH变量复用相同参数,使用前请确认变量设置与工程结构一致。
environment {
// 模块信息
MODULE_NAME = "xxx-service" // 模块名称
MODULE_PATH = "./${MODULE_NAME}" // 模块路径,适用于微服务多module
// Git仓库配置
GIT_URL = 'git@git.xxx.com:xxx.git' // 替换为你的代码仓库
GIT_KEY_ACR_CRED = 'git-ssh-key'
BRANCH = 'master'
// Docker镜像相关配置
DOCKER_IMAGE_REGISTRY = 'registry.xxx.aliyuncs.com' // 替换为你的镜像仓库
DOCKER_IMAGE_ACR_CRED = 'docker-cred'
IMAGE_PRE_NAME = 'xxxx' // 镜像名称前缀
IMAGE_NAME = "${MODULE_NAME}" // 镜像名称
DOCKERFILE = "${MODULE_PATH}/Dockerfile" // 用来构建镜像的dockerfile文件
// Kubernetes相关配置
KUBERNETES_CONFIG = "kubernetes-config" // Kubernetes配置文件凭证
RESOURCE_NAME = "${MODULE_NAME}" // 资源类型名称,这里为deployment名称
CONTAINER_NAME = "${MODULE_NAME}" // 容器名称
}
工具设置
配置构建代码的Maven工具:
tools {
// Install the Maven version configured as "M3" and add it to the path.
maven "Maven3"
}
拉取代码
从代码仓库拉取指定分支的源代码:
stage('Checkout') {
steps {
git branch: BRANCH,
url: GIT_URL,
credentialsId: GIT_KEY_ACR_CRED
}
}
打包
针对多module微服务项目,使用Maven指定模块打包命令,避免构建不相关模块,并指定生产环境配置:
stage('Package') {
steps {
// 执行Maven打包命令,只打包指定模块
sh "mvn -pl ${MODULE_PATH} -am -B clean package -Ppro -Dfile.encoding=UTF-8 -DskipTests=true"
}
}
构建、推送Docker镜像
使用时间戳为镜像设置唯一标签,完成镜像构建、推送和本地清理:
stage('Build Docker Image') {
steps {
script {
// 生成时间戳
def timestamp = new Date().format('yyyyMMddHHmm', TimeZone.getTimeZone('Asia/Shanghai'))
def imageTag = "${IMAGE_NAME}:${timestamp}"
def fullImageNameWithTimestamp = "${DOCKER_IMAGE_REGISTRY}/${IMAGE_PRE_NAME}/${imageTag}"
// 使用Docker构建镜像
echo "Building Docker image: ${fullImageNameWithTimestamp}"
sh "docker build -t ${fullImageNameWithTimestamp} -f ${DOCKERFILE} ${MODULE_PATH}"
withCredentials([usernamePassword(credentialsId: DOCKER_IMAGE_ACR_CRED, usernameVariable:'REG_USER', passwordVariable:'REG_PASS')]) {
// 登录到镜像仓库
echo "Login Docker..."
sh "docker login --username $REG_USER -p $REG_PASS ${DOCKER_IMAGE_REGISTRY}"
// 推送镜像
echo "Push Docker Image ${fullImageNameWithTimestamp}"
sh "docker push ${fullImageNameWithTimestamp}"
// 推送完成后,删除本地镜像
echo "Remove Docker Imag ${fullImageNameWithTimestamp}"
sh "docker rmi ${fullImageNameWithTimestamp}"
}
// 输出构建信息
echo "Successfully built and pushed image: ${fullImageNameWithTimestamp}"
// 将镜像名称保存到环境变量,供后续步骤使用
env.BUILT_IMAGE = fullImageNameWithTimestamp
}
}
}
部署到Kubernetes集群
通过凭证连接Kubernetes集群并更新部署镜像,触发滚动发布:
stage('Deploy to Remote Kubernetes') {
steps {
script {
withCredentials([file(credentialsId: KUBERNETES_CONFIG, variable:'KUBECONFIG')]) {
// 设置KUBECONFIG环境变量
sh "export KUBECONFIG=$KUBECONFIG"
// 更新Deployment中的镜像信息
// kubectl set image <资源类型>/<资源名称> <容器名称>=<新镜像>:<标签>
sh "kubectl set image deployment/${RESOURCE_NAME} ${CONTAINER_NAME}=${BUILT_IMAGE}"
}
}
}
}
完整流水线脚本
pipeline {
agent any
environment {
// 模块信息
MODULE_NAME = "xxx-servcie" // 模块名称
MODULE_PATH = "./${MODULE_NAME}" // 模块路径,适用于微服务多module
// Git仓库配置
GIT_URL = 'git@git.xxx.com:xxx.git' // 替换为你的代码仓库
GIT_KEY_ACR_CRED = 'git-ssh-key'
BRANCH = 'master'
// Docker镜像相关配置
DOCKER_IMAGE_REGISTRY = 'registry.xxx.aliyuncs.com' // 替换为你的镜像仓库
DOCKER_IMAGE_ACR_CRED = 'docker-cred'
IMAGE_PRE_NAME = 'xxxx' // 镜像名称前缀
IMAGE_NAME = "${MODULE_NAME}" // 镜像名称
DOCKERFILE = "${MODULE_PATH}/Dockerfile" // 用来构建镜像的dockerfile文件
// Kubernetes相关配置
KUBERNETES_CONFIG = "kubernetes-config" // Kubernetes配置文件凭证
RESOURCE_NAME = "${MODULE_NAME}" // 资源类型名称,这里为deployment名称
CONTAINER_NAME = "${MODULE_NAME}" // 容器名称
}
tools {
// Install the Maven version configured as "M3" and add it to the path.
maven "Maven3"
}
stages {
stage('Checkout') {
steps {
git branch: BRANCH,
url: GIT_URL,
credentialsId: GIT_KEY_ACR_CRED
}
}
stage('Package') {
steps {
// 执行Maven打包命令,只打包指定模块
sh "mvn -pl ${MODULE_PATH} -am -B clean package -Ppro -Dfile.encoding=UTF-8 -DskipTests=true"
}
}
stage('Build Docker Image') {
steps {
script {
// 生成时间戳
def timestamp = new Date().format('yyyyMMddHHmm', TimeZone.getTimeZone('Asia/Shanghai'))
def imageTag = "${IMAGE_NAME}:${timestamp}"
def fullImageNameWithTimestamp = "${DOCKER_IMAGE_REGISTRY}/${IMAGE_PRE_NAME}/${imageTag}"
// 使用Docker构建镜像
echo "Building Docker image: ${fullImageNameWithTimestamp}"
sh "docker build -t ${fullImageNameWithTimestamp} -f ${DOCKERFILE} ${MODULE_PATH}"
withCredentials([usernamePassword(credentialsId: DOCKER_IMAGE_ACR_CRED, usernameVariable:'REG_USER', passwordVariable:'REG_PASS')]) {
// 登录到镜像仓库
echo "Login Docker..."
sh "docker login --username $REG_USER -p $REG_PASS ${DOCKER_IMAGE_REGISTRY}"
// 推送镜像
echo "Push Docker Image ${fullImageNameWithTimestamp}"
sh "docker push ${fullImageNameWithTimestamp}"
// 推送完成后,删除本地镜像
echo "Remove Docker Imag ${fullImageNameWithTimestamp}"
sh "docker rmi ${fullImageNameWithTimestamp}"
}
// 输出构建信息
echo "Successfully built and pushed image: ${fullImageNameWithTimestamp}"
// 将镜像名称保存到环境变量,供后续步骤使用
env.BUILT_IMAGE = fullImageNameWithTimestamp
}
}
}
stage('Deploy to Remote Kubernetes') {
steps {
script {
withCredentials([file(credentialsId: KUBERNETES_CONFIG, variable:'KUBECONFIG')]) {
// 设置KUBECONFIG环境变量
sh "export KUBECONFIG=$KUBECONFIG"
// 更新Deployment中的镜像
// kubectl set image <资源类型>/<资源名称> <容器名称>=<新镜像>:<标签>
sh "kubectl set image deployment/${RESOURCE_NAME} ${CONTAINER_NAME}=${BUILT_IMAGE}"
}
}
}
}
}
}