采用jenkins pipeline实现自动构建并部署至k8s
(给ImportNew加星标,提高Java技能)
链接:www.jianshu.com/p/2d89fd1b4403
前言
提交spring boot项目代码并打上git tag,上传代码及tag至gitlab
gitlab通过webhook自动触发jenkins执行任务
jenkins获取代码,执行代码编译、构建docker镜像、上传docker镜像至harbor镜像仓库、执行kubectl命令部署至k8s。
本文中采用jenkins pipeline执行整个jenkins的构建过程,在pipeline中使用docker执行maven构建。文中构建的docker镜像的tag直接采用git中的tag。
下面的示例中,jenkins版本为2.121.3,gitlab版本为10.0.2-ce,如果使用的版本不一致可能会有部分设置差异。
部署Jenkins
docker run \-d \-u root \-p 8080:8080 \-v jenkins_home:/var/jenkins_home \-v /var/run/docker.sock:/var/run/docker.sock \jenkinsci/blueocean
2. 访问 http://localhost:8080 地址,等待出现下面解锁界面。
注:由于后面jenkins pipeline任务会上传docker镜像至harbor仓库,如果harbor使用http需要在/etc/docker/daemon.json中将地址配置到insecure-registries;如果harbor使用自签名https证书,需要将ca证书放入/etc/docker/certs.d/目录下。设置完需要重启docker服务。
准备java示例工程
创建spring boot示例工程
import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;public class HomeController {public String hello() {return "Hello!";}}2. 修改application配置文件,设置端口。
spring.application.name=pipeline-demoserver.port=400803. 编译运行,访问 http://localhost:40080 地址可以看到示例运行结果。
添加Dockerfile
FROM openjdk:8-jdk-alpine#构建参数ARG JAR_FILEARG WORK_PATH="/opt/demo"# 环境变量ENV JAVA_OPTS="" \JAR_FILE=${JAR_FILE}#设置时区RUN apk update && apk add ca-certificates && \apk add tzdata && \ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \echo "Asia/Shanghai" > /etc/timezoneCOPY target/$JAR_FILE $WORK_PATH/WORKDIR $WORK_PATHENTRYPOINT exec java $JAVA_OPTS -jar $JAR_FILE
添加k8s的Deployment配置
apiVersion: apps/v1kind: Deploymentmetadata:name: {APP_NAME}-deploymentlabels:app: {APP_NAME}spec:replicas: 1selector:matchLabels:app: {APP_NAME}template:metadata:labels:app: {APP_NAME}spec:containers:name: {APP_NAME}image: {IMAGE_URL}:{IMAGE_TAG}ports:containerPort: 40080env:name: SPRING_PROFILES_ACTIVEvalue: {SPRING_PROFILE}
添加Jenkinsfile
environment中变量说明,environment的文档说明参见:https://jenkins.io/zh/doc/book/pipeline/jenkinsfile/#%E5%A4%84%E7%90%86%E5%87%AD%E8%AF%81 。
HARBOR_CREDS为harbor镜像仓库的用户密码,数据保存为jenkins的“username and password”类型的凭据,用credentials方法从凭据中获取。使用时通过HARBOR_CREDS_USR获取用户名,HARBOR_CREDS_PSW获取密码。
K8S_CONFIG为k8s中kubectl命令的yaml配置文件内容,数据保存为jenkins的“Secret Text”类型的凭据,用credentials方法从凭据中获取。这里保存的yaml配置文件内容以base64编码格式保存,在设置凭据时先要进行base64编码。(此base64编码是非必须的,如果直接保存原文,下面Jenkinsfile中需要去掉base64 -d 解码)
GIT_TAG变量通过执行sh命令获取当前git的tag值。由于后面构建docker镜像时使用git的tag作为镜像的标签,所以这个变量也不能为空。
parameters中变量说明
DOCKER_IMAGE:docker镜像名,包含harbor项目名称。
APP_NAME:k8s中的标签名称,对应k8s的yaml模板中的{APP_NAME}。
K8S_NAMESPACE:k8s中的namespace名称,执行kubectl命令会部署至此命名空间。
stages说明:
Maven Build:使用docker的方式执行maven命令,args参数中将.m2目录映射出来,避免执行时重复从远端获取依赖;stash步骤中将jar文件保存下来,供后面的stage使用。
Docker Build:unstash获取jar文件。通过sh依次执行docker命令登录harbor、构建镜像、上传镜像、移除本地镜像。构建镜像时,会获取jar文件名传入JAR_FILE参数。
Deploy:使用docker的方式执行kubectl命令。在执行前先将K8S_CONFIG中的内容进行base64解密并存为~/.kube/config配置文件,然后执行sed命令将k8s-deployment.tpl文件中“{参数名}”形式参数替换为实际的参数值,最后执行kubectl命令部署至k8s。
parameters中的参数在pipeline任务执行一次后,第二次执行时可以在界面上修改参数值。
这里的stage都是一个接一个自动执行,如果需要手动执行可以使用input指令实现。参见:https://jenkins.io/zh/doc/book/pipeline/syntax/#input
// 需要在jenkins的Credentials设置中配置jenkins-harbor-creds、jenkins-k8s-config参数pipeline {agent anyenvironment {HARBOR_CREDS = credentials('jenkins-harbor-creds')K8S_CONFIG = credentials('jenkins-k8s-config')GIT_TAG = sh(returnStdout: true,script: 'git describe --tags --always').trim()}parameters {string(name: 'HARBOR_HOST', defaultValue: '172.23.101.66', description: 'harbor仓库地址')string(name: 'DOCKER_IMAGE', defaultValue: 'tssp/pipeline-demo', description: 'docker镜像名')string(name: 'APP_NAME', defaultValue: 'pipeline-demo', description: 'k8s中标签名')string(name: 'K8S_NAMESPACE', defaultValue: 'demo', description: 'k8s的namespace名称')}stages {stage('Maven Build') {when { expression { env.GIT_TAG != null } }agent {docker {image 'maven:3-jdk-8-alpine'args '-v $HOME/.m2:/root/.m2'}}steps {sh 'mvn clean package -Dfile.encoding=UTF-8 -DskipTests=true'stash includes: 'target/*.jar', name: 'app'}}stage('Docker Build') {when {allOf {expression { env.GIT_TAG != null }}}agent anysteps {unstash 'app'sh "docker login -u ${HARBOR_CREDS_USR} -p ${HARBOR_CREDS_PSW} ${params.HARBOR_HOST}"sh "docker build --build-arg JAR_FILE=`ls target/*.jar |cut -d '/' -f2` -t ${params.HARBOR_HOST}/${params.DOCKER_IMAGE}:${GIT_TAG} ."sh "docker push ${params.HARBOR_HOST}/${params.DOCKER_IMAGE}:${GIT_TAG}"sh "docker rmi ${params.HARBOR_HOST}/${params.DOCKER_IMAGE}:${GIT_TAG}"}}stage('Deploy') {when {allOf {expression { env.GIT_TAG != null }}}agent {docker {image 'lwolf/helm-kubectl-docker'}}steps {sh "mkdir -p ~/.kube"sh "echo ${K8S_CONFIG} | base64 -d > ~/.kube/config"sh "sed -e 's#{IMAGE_URL}#${params.HARBOR_HOST}/${params.DOCKER_IMAGE}#g;s#{IMAGE_TAG}#${GIT_TAG}#g;s#{APP_NAME}#${params.APP_NAME}#g;s#{SPRING_PROFILE}#k8s-test#g' k8s-deployment.tpl > k8s-deployment.yml"sh "kubectl apply -f k8s-deployment.yml --namespace=${params.K8S_NAMESPACE}"}}}}配置jenkins pipeline任务
新建pipeline任务
配置 pipeline任务
配置k8s的kube.config配置信息
apiVersion: v1kind: Configclusters:- name: "test"cluster:server: "https://xxxxx"api-version: v1certificate-authority-data: "xxxxxx"users:- name: "user1"user:token: "xxxx"contexts:- name: "test"context:user: "user1"cluster: "test"current-context: "test"
可以在linux中采用下面命令将kubectl的yaml配置文件进行base64编码。
base64 kube-config.yml > kube-config.txt
然后类似上一步,在jenkins凭据中增加配置文件内容。在凭据设置界面,类型选择为“Secret text”,ID设置为“jenkins-k8s-config”(此处的ID必须与Jenkinsfile中的保持一致),Secret设置为上面经过base64编码后的配置文件内容。
测试pipeline任务
设置gitlab自动触发jenkins
jenkins中安装gitlab插件
jenkins中配置gitlab插件
webhook测试
看完本文有收获?请转发分享给更多人
关注「ImportNew」,提升Java技能
好文章,我在看❤️
