一、Jenkins的安装
docker run \ -u root \ -d \ -p 8080:8080 \ -p 50000:50000 \ -v jenkins-data:/var/jenkins_home \ -v /etc/localtime:/etc/localtime:ro \ -v /var/run/docker.sock:/var/run/docker.sock \ --restart=always \ jenkinsci/blueocean
命令解释:
docker run \ -u root \ -d \ -p 8080:8080 \ #web控制台的端口 -p 50000:50000 \ #集群间通信的端口 -v jenkins-data:/var/jenkins_home \ #最重要的目录,这里面包含着Jenkins的所有目录(以文件的方式存数据),注意备份,恢复Jenkins的时候只需要挂上这个目录就可以直接恢复之前的Jenkins的所有配置 -v /etc/localtime:/etc/localtime:ro \ #Jenkins推荐的镜像内部时区不是中国时间,所以我们把宿主机的时间挂到Jenkins容器内 -v /var/run/docker.sock:/var/run/docker.sock \ #将宿主机的docker命令挂到Jenkins中,从而再Jenkins中可以直接使用docker命令 --restart=always \ #随docker开机自启 jenkinsci/blueocean #推荐的版本(安装了blueocean插件)
如果想挂载宿主机上的jdk或者mvn环境,就执行:
docker run \ -u root \ -d \ -p 8080:8080 \ -p 50000:50000 \ -v jenkins-data:/var/jenkins_home \ -v /etc/localtime:/etc/localtime:ro \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /usr/local/jdk11:/opt/java/openjdk \ -v /usr/local/maven:/usr/local/maven \ -v /var/maven/.m2:/var/maven/.m2 \ --restart=always \ jenkinsci/blueocean
1、获得解锁密码
安装成功后,访问 ip:8080,就可以打开Jenkins的管理界面了,需要找到默认的解锁密码:
因为我们的Jenkins核心目录已经挂在出来了,所以可以不需要进到docker容器中进行查看:
直接cat查看:
[root@mycentos1 _data]# cat /var/lib/docker/volumes/jenkins-data/_data/secrets/initialAdminPassword ba7ecefed8d14d3caa2b5f47ff8ec9d5
然后就进入了Jenkins的后台啦!
2、安装推荐的插件
3、创建管理员用户
一路确认,最后退出一下,使用我们创建的admin账号密码进行登录即可!
二、Jenkins+Gitlab Webhook实现自动构建
1、新建流水线任务
2、在项目下的“构建触发器”添加认证令牌(不需要webhook自动构建的就不需要)
3、为Jenkins创建一个用户,专门用于Webhook钩子鉴权
Dashboard ——> 系统管理 ——> 管理用户 ——> 新建用户
4、使用jiguiquan新用户登录Jenkins,并创建自己的API Token令牌
5、在Gitlab的项目管理中添加Webhook钩子:JENKINS_URL/job/demo1/build?token=TOKEN_NAME
http://jiguiquan:11b97077cdb3b837e7361c54867cedc7c5@192.168.56.10:8080/job/demo1/build?token=jiguiquan
之后保存,此WebHook即可正常使用!
三、Jenkins的使用
1、Jenkinsfile的编写并环境检查
参考官方文档:https://www.jenkins.io/zh/doc/book/pipeline/
//流水线的脚本(声明式、脚本式) pipeline{ //全部的CICD流程都需要在这里定义 //any: 任何一个代理机器闲着都可以立即执行此流水线任务 agent any //定义一些环境信息 environment { aaa = "1111" bbb = "2222" } //定义流水线的加工流程 stages { stage('检查环境') { steps { echo "检查环境..." sh 'java -version' sh 'git --version' sh 'docker version' sh 'mvn -v' } } stage('编译') { steps { echo "编译..." echo "${aaa}" echo "$bbb" sh 'pwd && ls -alh' sh 'printenv' } } stage('测试') { steps { echo "测试..." } } stage('打包') { steps { echo "打包..." } } stage('部署') { steps { echo "部署..." } } } }
如果还是不会写的话,Jenkins平台贴心地提供了“脚本片段生成器”,位于:
Dashboard ——> 项目 ——> 流水线语法(片段生成器,指令生成器)
但是,当我们执行流水线的时候发现,检查环境部分,其他几个都正常,就是最后的mvn -v无法正常执行,
由此我们可以得到以下结论:
Jenkins自带了Java环境——因为Jenkins是用Java写的;
Jenkins自带了git环境——Jenkins既然能从gitlab上拉代码,足以说明一切;
Jenkins自带了Docker环境——因为我们挂在进去的;
Jenkins没有自带maven环境
2、为Jenkins安装Docker Pipeline插件
Jenkins在执行每一步的Steps的时候不可避免的需要一些环境的支持,如maven,或者其他环境等;
而我们不可能在Jenkins里面刚开始就安装很多环境,这样工作量比较大;
我们可以选择在执行相应步骤的时候才准备一个临时代理环境来执行,在每一个stage的时候借助一个基础的docker环境来完成!
所以,我们需要为Jenkins安装一个Docker Pipeline插件!(从而避免安装很多环境)
Dashboard ——> 系统管理 ——> 插件管理
3、借助Docker Pipeline插件+自定义代理 实现无环境情况下兼容任何场景
pipeline{ agent any environment { aaa = '111' } stages { stage('编译打包') { agent { docker { image 'maven:3-alpine'} } steps { sh 'pwd && ls -alh' sh 'mvn -v' //打包jar sh 'mvn clean install -DskipTests' } } stage('生成镜像') { steps { echo "测试docker命令是否正常..." sh 'docker version' sh 'pwd && ls -alh' } } } }
使用了上面自定义agent代理后,我们再次跑一遍流水线:
可以看到,现在就可以正常完成了,但是还有一些问题需要我们去优化解决:
-
mvn拉取依赖的时候是从maven官方仓库拉取的,太慢了,我们最好能把它换成阿里云的镜像仓库;
-
每一次执行的时候都要重新拉取依赖,而不是如我们所想只有第一次才从远程仓库拉取;
四、自定义maven代理使用过程中的优化
我们解决上面提到的两个问题:
mvn拉取依赖的时候是从maven官方仓库拉取的,太慢了,我们最好能把它换成阿里云的镜像仓库;
每一次执行的时候都要重新拉取依赖,而不是如我们所想只有第一次才从远程仓库拉取;
1、在jenkins_home挂载的目录下创建maven的配置文件settings.xml
在jenkins_home挂载的目录下,创建所有的appconfig目录,其中包括maven的自定义配置settings.xml:
cd /var/lib/docker/volumes/jenkins-data/_data mkdir appconfig/maven/ cd appconfig/maven/ vi settings.xml
内容如下:
<?xml version="1.0" encoding="UTF-8"?> <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"> <localRepository>/root/.m2</localRepository> <pluginGroups> </pluginGroups> <proxies> </proxies> <servers> </servers> <mirrors> <mirror> <id>nexus-aliyun</id> <mirrorOf>central</mirrorOf> <name>Nexus Aliyun</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> </mirror> </mirrors> <profiles> </profiles> </settings>
2、将配置文件的指定的<localRepository>地址挂载到宿主机的绝对路径下,方便重复使用下载好的jar包
pipeline{ agent any environment { aaa = '111' } stages { stage('编译打包') { agent { docker { image 'maven:3-alpine' // 将临时启动的maven容器的本地仓库挂载到宿主机的固定目录下 args '-v /var/maven/.m2:/root/.m2' } } steps { sh 'pwd && ls -alh' sh 'mvn -v' //打包jar, 指定使用我们自定义的maven配置文件 sh 'mvn clean package -s /var/jenkins_home/appconfig/maven/settings.xml -DskipTests' } } stage('生成镜像') { steps { echo "测试docker命令是否正常..." sh 'docker version' sh 'pwd && ls -alh' } } } }
3、运行校验效果:
至此,我们的Jenkins使用maven代理打包工作被优化得速度飞起!
以后再使用Jenkins的过程中,所有的可变配置项全部放在jenkins-home之下,这样以后要恢复Jenkins的时候只需要备份一下Jenkins-home的挂载目录即可,增强移植性!
Jenkins在解析流水线期间,可以任意访问jenkins_home目录下的文件,以及相关环境信息!
五、最佳Java项目实践
1、准备一个Springboot项目cicd-demo
2、编写一个Dockerfile文件:
FROM openjdk:8-jre-alpine LABEL maintainer="jiguiquan@163.com" COPY target/*.jar /app.jar RUN apk add -U tzdata; \ ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime; \ echo 'Asia/Shanghai' > /etc/timezone; \ touch /app.jar; ENV JAVA_OPTS="" ENV PARAMS="" EXPOSE 9090 ENTRYPOINT ["sh", "-c", "java -Djava.security.egd=file:/dev/./urandom $JAVA_OPTS -jar /app.jar $PARAMS"]
3、编写一个Jenkinsfile文件:
pipeline{ agent any environment { WS = "${WORKSPACE}" } stages { stage('maven编译') { agent { docker { image 'maven:3-alpine' args '-v /var/maven/.m2:/root/.m2' } } steps { sh "echo 在默认的工作目录下执行mvn命令: ${WS}" sh "cd ${WS} && mvn clean package -s /var/jenkins_home/appconfig/maven/settings.xml -DskipTests" } } stage('生成镜像') { steps { sh 'docker build -t cicd-demo:v1 .' } } stage('部署') { steps { sh 'docker images' sh 'docker rm -f cicd-demo && docker rmi -f $(docker images -q -f dangling=true)' sh 'docker run -d -p 9090:9090 --name cicd-demo cicd-demo:v1' } } } }
4、流水线执行效果:
5、访问对象项目暴露的接口
一切OK!大功告成!
补充1:配置阿里云docker镜像仓库的账号密码:
补充2:input确认框如何实现?
补充3、流水线中增加用户输入和选择交互项
pipeline{ agent any environment { WS = "${WORKSPACE}" //引用Jenkins配置的全局密钥信息 ALIYUN_SECRET = credentials("aliyun-docker-repo") } stages { stage('maven编译') { agent { docker { image 'maven:3-alpine' args '-v /var/maven/.m2:/root/.m2' } } steps { sh "echo 在默认的工作目录下执行mvn命令: ${WS}" sh "cd ${WS} && mvn clean package -s /var/jenkins_home/appconfig/maven/settings.xml -DskipTests" } } stage('生成镜像') { steps { sh 'docker build -t cicd-demo .' } } stage('推送镜像到aliyun') { input { message '需要将镜像推送到阿里云仓库吗?' ok '需要,赶紧部署' parameters { text defaultValue: 'v1.0', description: '生产环境需要部署的版本', name: 'APP_VERSION' choice choices: ['bj-01', 'sh-02', 'hz-03'], description: '部署的大区', name: 'DEPLOY_WHERE' } } steps { echo "${APP_VERSION}" echo "${DEPLOY_WHERE}" script { //groovy脚本 def where = "${DEPLOY_WHERE}" if (where == "bj-01"){ echo "帮我部署到北京大区" }else if(where == "sh-02"){ echo "帮我部署到上海大区" }else{ echo "帮我部署到杭州大区" } } sh "docker login -u ${ALIYUN_SECRET_USR} -p ${ALIYUN_SECRET_PSW} registry.cn-hangzhou.aliyuncs.com" sh "docker tag cicd-demo registry.cn-hangzhou.aliyuncs.com/jiguiquan/cicd-demo:${APP_VERSION}" sh 'docker push registry.cn-hangzhou.aliyuncs.com/jiguiquan/cicd-demo:${APP_VERSION}' } } stage('部署') { steps { sh 'docker images' sh 'docker rm -f cicd-demo' sh 'docker run -d -p 9090:9090 --name cicd-demo cicd-demo' } } } }
用户参与环节效果:
非常NICE!
补充四、使用宿主机的JDK+MAVEN环境
1、在宿主机上安装了JDK+MAVEN后,执行以下命令,安装Jenkins:
docker run \ -u root \ -d \ -p 8080:8080 \ -p 50000:50000 \ -v jenkins-data:/var/jenkins_home \ -v /etc/localtime:/etc/localtime:ro \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /usr/local/jdk11:/opt/java/openjdk \ -v /usr/local/maven:/usr/local/maven \ -v /var/maven/.m2:/var/maven/.m2 \ --restart=always \ jenkinsci/blueocean
2、在Jenkins内安装JDK+MAVEN(管理Jenkins ——> 全局工具配置)
3、配置环境变量:
之后就可以在jenkins中使用java + mvn命令了