对于Jenkins的入门
实现考虑在Docker平台上安装
对应的Docker命令为
docker run \
-u root \
–rm \
-d \
-p 8080:8080 \
-p 50000:50000 \
-v jenkins-data:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
jenkinsci/blueocean
对于–rm我们有必要去掉
对于/var/jenkins_home Jenkins的家目录,包含了所有的配置
dockerhub上面的第一位的Jenkins已经被废弃了
建议使用上面的jenkinsci作为镜像
进行了docker run之后,就可以创建第一个管理员用户了
然后我们利用一个Java的部署,进行了Jenkins的实战
实现代码的本地修改,提交到远程git,触发Jenkins完成自动化的部署
整体的前期准备工作如下
在准备好一个git项目之后
可以进行创建一个流水线
在对应的Dashboard中点击创建流水线即可,我们这次是利用git项目进行代码同步
所以流水线上可以选择SCM
输入对应的Repository URL即可
在定义了项目之后
流水线的创建是必要的
流水线的主要工作是
先去git位置拉取代码
然后解析代码中的Jenkinsfile文件
按照Jenkinsfile指定的流水线进行加工项目
对于Jenkinsfile的书写来说,如果有部分的语法的不熟悉
Jenkins提供了对应的语法帮助,在流水线语法下的片段生成器中
比如我们尝试在Jenkinsfile中发送一个mail
好了,回到正题
我们继续说下Pipline的基础语法
pipeline {
agent any environment { CC = ‘clang’ } stages { stage(‘构建’) { steps { echo “$abc” } } } } |
上面的语法中
agent any 表示,是否有代理,any表示可以在任何的工作节点上执行
environment声明了环境变量
stages下的stage表示不同的阶段
steps表示具体的操作
然后我们尝试编写一个如果git上进行了修改,自动触发构建的相关实现
不过在此之前,我们可以利用
sh ‘mvn -v’,等方式测试当前Jenkins打包的环境.利用env查看所有的环境变量
其中环境变量比较重要的点有:
Jenkins的/var/jenkins_home,还有当前的WORKSPACE 工作空间,/var/jenkins_home/workspace/java-demo
WORKSPACE_TMP 这个环境变量对应的是临时目录,还有jenkins_url 指定了Jenkins相关的路径
那么我们说下如何进行远程构建触发
希望的效果是,远程的github代码提交了,Jenkins流水线自动触发构建
整体的流程如下
1.确保Jenkins主机能被git仓库访问
2.在Jenkins中创建一个用户,并登陆上这个用户,获取这个用户的Token
3.在github中创建一个webhook
指定webhook远程触发的路径即可,设置的路径需要加上第二部的Token
http://xxxxuser:113620edce6200b9c78ecadb26e9cf122e@139.198.186.134:8080/job/dev ops-java-demo/build?token=leifengyang
这样每次github在push了之后,就会触发远程的仓库构建
其次是我们进入了实际jar包的构建流程
首先在Build阶段,需要使用maven进行打包成jar
设置在之前的阶段,我们需要git来进行拉取&切换分支
在之后的打包成镜像的阶段,我们还需要docker-cli来进行打包操作,对于这些基础的环境,并不建议在宿主机上或者Jenkins上进行设置安装,而是通过JenkinsFile来进行规定
可以进行如下的JenkinsFile的声明,来进行对应阶段的环境增加
需要注意,需要在Jenkins的管理中安装docker,docekr pipeline两个插件
可以考虑修改jenkins插件源
除了这几个插件,还有些插件是推荐安装的
pipeline {
agent any stages { stage(‘构建’) { agent { docker ‘maven:3-alpine’ //进行挂载 args ‘-v /var/jenkins_home/maven/.m2:/root/.m2’ } steps { sh “mvn –version” } } stage(‘Test’) { agent { docker ‘openjdk:8-jre’ //进行挂载 } steps { sh “java -version” } } } } |
上面agent any,是不同阶段可以指定不同的环境,不指定也可以
如果设置为agent none,则每个阶段必须要指定一个环境
然后我们进行了mvn –version
可以考虑尝试进行打包,在构建阶段,加上
sh ‘mvn clean package -Dmaven.test.skip=true’
然后运行打包
但是在打包过程中,会发现实际链接的远程仓库是官方自带的仓库,不是我们所期待的阿里云仓库
为了实现利用阿里云远程仓库打包的意图,我们最好能够指定使用自定义的xml,我们如何将配置文件挂载进某个步骤中呢?尤其是我们还利用docker image启动的不同阶段
实际上可以从不同的step中访问到Jenkins的home目录,这是因为
实际上Docker将新启动的maven容器挂在到了Jenkins的mount namespace中了
而Jenkins的home目录实际上被挂载上了宿主机的一个目录上
我可以可以在宿主机上的对应home目录加上对应的maven setting.xml,从而让maven拿到这个setting.xml
sh ‘mvn clean package -s “/var/jenkins_home/appconfig/maven/settings.xml” -Dmaven.test.skpi=true’
而且在settings.xml中,我么设定了localRepository中
<localRepository>/root/.m2</localRepository>
为了方便下次打包直接利用
pipeline {
agent any stages { stage(‘构建’) { agent { docker ‘maven:3-alpine’ //进行挂载,讲仓库挂载到docker volume上 args ‘-v /var/jenkins_home/maven/.m2:/root/.m2’ //进行挂载,讲仓库挂载到宿主机上 args ‘ -v maven-repo:/root/.m2’ } steps { sh “mvn –version” } } stage(‘Test’) { agent { docker ‘openjdk:8-jre’ //进行挂载 } steps { sh “java -version” } } } } |
这样就进行了Maven加速
上面的-v 其实就是docker的参数,Jenkins会原封不动的传进去
但是使用了Maven这样的一个镜像进行打包的话,存在一个问题
就是对于Jenkins中的临时容器,Jenkins会更换为了一个临时的工作目录,比如我们正常的workspace为 java-demo,那么临时文件为java-demo@2
如果考虑使用Jenkins提供的 ${ WORKSPACE}来进行打包的话
Maven中的workspace也是java-demo@2
而且因为切换到了临时目录,所以之后的步骤,对于Maven打好的包无法拿到
也就是默认工作目录下没有target
所以解决方案可以为
定义一个全局变量 WS=${WORKSPACE}
然后在maven打包阶段
cd ${WS} && maven clean package
除此之外,还可以配置邮件的发送
只要在系统设置中配置管理员的邮箱
然后就可以再代码生成器部分,生成邮件发送相关代码
并且利用片段生成器下的 Generate Declarative Directive进行生成
选取Post下的if Failure表示失败之后该怎么做
post {
failure {
// One or more steps need to be included within each condition’s block.
}
}
全局凭证可以用来配合推送镜像
在首页可以设置凭据,其中有全局凭据
使用方法如下
使用一个助手函数 credentials() 获取到对应的凭证,基本如下
AN_ACCESS_KEY = credentials(‘my_access’)
接下来就会被分解为
AN_ACCESS_KEY_USER/AN_ACCESS_KEY_PASSWORD 两个环境变量
stage(‘推送镜像’){
steps{
sh ‘docker login -u &{xxx_user} -p {xxxx_pwd} xxx.com‘
}
}
在之后,我们说下input
input是需要用户和Jenkins进行交互,从而控制业务线接下来的路线选择
我们可以在流水线语法生成器中进行找到
一个常见的事例如下
input message: ‘需要推送远程镜像吗?’, ok: ‘需要’, parameters: [text(defaultValue: ‘v1.0’, description: ‘生产环境需要部署的版本’, name: ‘APP_VER’)]
对于上面的parameter
我们可以在后续的step中拿到病使用
stage(‘推送镜像’){
input message: ‘需要推送远程镜像吗?’, ok: ‘需要’, parameters: [text(defaultValue: ‘v1.0’, description: ‘生产环境需要部署的版本’, name: ‘APP_VER’)]
steps {
echo “$APP_VER”
}
}
这是基本的input使用
更为进阶的使用是在parameter中声明一个下拉框,进行选择提交的
//step外面这么写
input {
message “需要推送远程镜像吗?”
ok “需要”
parameters {
string(name: ‘APP_VER’, defaultValue: ‘v1.0’, description: ‘生产环境需要部署的版本’)
choice choices: [‘bj-01’, ‘sh-02’, ‘wuhan-01’], description: ‘部署的大区’, name: ‘DEPLOY_WHERE’
}
}
后续的可以利用对应的脚本来根据上述选择的 bj-01 sh-02 做出不同的判断
我们可以在steps中声明一个
script {
}
里面进行脚本的语法定义
脚本里面可以使用Jenkins自身提供的语法,或者自己编写groovy脚本
script {
def where = “${DEPLOY_WHERE}”
if (where == “bj-01”){
sh “echo 我帮你部署到 bj-01 区了”
}else if(where == “sh-02”){
sh “echo 我帮你部署到 sh-02 区了”
}else{
sh “echo 没人要的,我帮你部署到 wuhan-01 区了”
sh “docker push registry.cn-hangzhou.aliyuncs.com/lfy/java-devops-demo:${APP_VER}”
withCredentials([usernamePassword(credentialsId: ‘aliyun-docker-repo’, passwordVariable: ‘ali_pwd’, usernameVariable: ‘ali_user’)]) {
sh “docker login -u ${ali_user} -p ${ali_pwd} registry.cn-hangzhou.aliyuncs.com”
sh “docker tag java-devops-demo registry.cn-hangzhou.aliyuncs.com/lfy/java-devops-demo:${APP_VER}”
}
}
}
利用一个groovy的脚本来进行不同操作的控制
接下来如果还想要进阶的使用JenkinsFile
其实Git在进行WebHook的触发时候,可以发送这次有哪些更新了, add了哪些 modift了哪些, delete了哪些
而Jenkins的Generic Webhook Trigger 可以进行多分支,多微服务的不同构建
对模块进行不同粒度的持续集成
甚至到了最后可以做到别人提交一个issue,jenkins触发后生成一个fix分支,去进行修改部署