Gitee+Jenkins+https
Jenkins master 安装
使用docker镜像安装,docker-compose.yml文件如下:
version: "3.9"
services:
jenkins:
image: jenkins/jenkins:lts-jdk11
container_name: jenkins
environment:
TZ: Asia/Shanghai
JENKINS_SLAVE_AGENT_PORT: 25001
JENKINS_OPTS: --httpPort=-1 --httpsPort=443 --httpsKeyStore=/var/lib/jenkins/xxx.xxxx.com.jks --httpsKeyStorePassword=xxxxxxxxxxx
ports:
- "25001:25001"
- "443:443"
volumes:
- /data/Jenkins/cert:/var/lib/jenkins
- /data/Jenkins/data:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock
通过域名访问Jenkins,默认账户admin,密码/var/jenkins_home/secret/initialAdminPassword
Jenkins agent 安装
系统管理-》节点管理-》新建节点
由于agent在内网,启动方式通过Java Web 启动代理
创建流水线项目
- 添加插件
- 配置gitee
系统管理-》系统配置: - 新建任务
新建一个流水线任务,Gitee链接选择上步骤配置的链接名 - 触发器勾选Gitee webhook构建触发,根据需要勾选下方策略
- 生成Gitee WebHook密码,用于在gitee页面配置
- 上两步获取的信息在图中填写
- 配置git 仓库和账户信息
- 所有分支匹配该流水线,指定分支填写*/*
- 测试
在gitee 设置webhook页面点击测试
问题1
描述:启动Jenkins agent 时,日志显示无法识别master的证书,但在浏览器使用https 访问Jenkins master无异常
解决方法:在adopopenjdk 中导入https证书
keytool -input -keystore /usr/local/jdk/lib/security/cacerts -file xxxx.xxx.com.crt --trustcacert
然后输入changeit
最终agent连接master成功
分析:该问题原因猜测为问题2的原因,并未验证
问题2
描述:gitee 调用https 的Jenkins时显示如下
但在页面使用https访问Jenkins无异常
分析思路如下:
- 咨询gitee技术支持原因,提示证书不完整,在myssl.com查询得知证书不完整,所以gitee作为客户端去验证服务端的证书,提示不认识的CA ,猜测问题1原因也是如此
- 确认证书问题,使用静态页面+nginx配置证书,在myssl.com验证,证书完整;使用Jenkins配置https,在myssl.com,证书不完整;下载两次完整证书链,发现两次证书链不一致,甚至Jenkins 配置https之后,在myssl.com 查询到的证书链与腾讯云申请的原文件不一致。怀疑Jenkins配置https启动之后,证书被篡改
- 切换证书,有cert+key套餐,换成jks+keystorePass.txt套餐
- 在myssl.com查询,证书链完整,gitee通过webhook调用Jenkins成功
问题三
描述:Jenkinsfile 调用企业微信群机器人接口发送消息,可以发送markdown语法的消息,但是由于引号问题和json,消息发送始终不完整
解决方法:
script {
def commitinfo= new JsonSlurper().parseText(jsonBody)
def buildinfo="【"+JOB_NAME+"】"+" <font color='warning'> 构建失败!</font> \n 提交人员: "+giteeUserName+" \n 提交分支: "+giteeBranch+"\n 提交时间: "+commitinfo.commits.timestamp+" \n GIT_COMMIT: "+GIT_COMMIT+" \n [详情地址]("+BUILD_URL+"console)"
def buildjson='{"msgtype": "markdown","markdown": { "content": "'+buildinfo+'"}}'
def response = httpRequest acceptType: 'APPLICATION_JSON',contentType: 'APPLICATION_JSON_UTF8',httpMode: 'POST',requestBody: buildjson,url:"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=企业微信提供的key"
}
最终消息:
注意点
- 需要安装HTTP Request插件
- 显示中文contentType 为APPLICATION_JSON_UTF8 (去人家源码的地方查出来这个值)
最终Jenkinsfile 简略版
import groovy.json.JsonOutput
import groovy.json.JsonSlurper
pipeline {
agent {
label 'In_agent1'
}
environment {
PKGPATH="/data/downloads/pkg/${env.JOB_NAME}"
INSTALLPATH="/data/app/${env.JOB_NAME}"
}
stages {
stage('步骤1') {
agent {
docker {
image 'maven:3.6.3-adoptopenjdk-11'
label 'In_agent1'
args '-v /data/maven/repo:/root/.m2/repository -v /usr/bin/docker:/usr/bin/docker -v /var/run/docker.sock:/var/run/docker.sock'
}
}
steps {
sh """
xxxxxxx
"""
}
}
stage('步骤2') {
agent {
docker {
image 'maven:3.6.3-adoptopenjdk-11'
label 'In_agent1'
args '-v /data/maven/repo:/root/.m2/repository -v /usr/bin/docker:/usr/bin/docker -v /var/run/docker.sock:/var/run/docker.sock'
}
}
steps {
sh """
CONTAINERID=`head -1 /proc/self/cgroup | cut -d/ -f3 | cut -c1-6`
docker run -d --name \$BUILD_TAG-redis --net=container:\$CONTAINERID flit-redis:6.2.1
docker run -d --name \$BUILD_TAG-influxdb --net=container:\$CONTAINERID influxdb:1.8.4-alpine
mvn test
docker stop \$BUILD_TAG-redis
docker stop \$BUILD_TAG-influxdb
docker rm \$BUILD_TAG-redis
docker rm \$BUILD_TAG-influxdb
"""
}
}
stage('步骤3') {
agent {
docker {
image 'maven:3.6.3-adoptopenjdk-11'
label 'In_agent1'
args '-v /data/maven/repo:/root/.m2/repository -v /usr/bin/docker:/usr/bin/docker -v /var/run/docker.sock:/var/run/docker.sock'
}
}
steps {
sh """
xxxxxxxxxx
"""
}
}
stage('步骤4') {
when {
beforeAgent true
expression { giteeBranch == 'master' || giteeBranch ==~/.*tags.*/ }
}
agent {
docker {
label 'In_agent1'
image 'alpine-ssh:latest'
}
}
environment {
PKGVERSION=sh(script: "less pom.xml | grep '<revision>' | cut -d'<' -f2 | cut -d'>' -f2", returnStdout: true).trim()
}
steps {
sh '''
xxxxxxxxxxxx
'''
script {
if ( giteeBranch ==~/.*tags.*/ ) {
sh "xxxxxxxxxxxx"
}
}
}
post {
failure {
script {
def commitinfo= new JsonSlurper().parseText(jsonBody)
def buildinfo="【"+JOB_NAME+"】"+" <font color='warning'> 构建失败!</font> \n 提交人员: "+giteeUserName+" \n 提交分支: "+giteeBranch+"\n 提交时间: "+commitinfo.commits.timestamp+" \n GIT_COMMIT: "+GIT_COMMIT+" \n [详情地址]("+BUILD_URL+"console)"
def buildjson='{"msgtype": "markdown","markdown": { "content": "'+buildinfo+'"}}'
def response = httpRequest acceptType: 'APPLICATION_JSON',contentType: 'APPLICATION_JSON_UTF8',httpMode: 'POST',requestBody: buildjson,url:"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxxxxxxxx"
}
}
cleanup {
dir("${workspace}") {
deleteDir()
}
}
}
}
stage('步骤5') {
steps {
xxxxxxxx
}
post {
always {
script {
def commitinfo= new JsonSlurper().parseText(jsonBody)
def buildinfo="【"+JOB_NAME+"】"+" <font color='info'> 构建成功!</font> \n 提交人员: "+giteeUserName+" \n 提交分支: "+giteeBranch+"\n 提交时间: "+commitinfo.commits.timestamp+" \n GIT_COMMIT: "+GIT_COMMIT+" \n [详情地址]("+BUILD_URL+"console)"
def buildjson='{"msgtype": "markdown","markdown": { "content": "'+buildinfo+'"}}'
def response = httpRequest acceptType: 'APPLICATION_JSON',contentType: 'APPLICATION_JSON_UTF8',httpMode: 'POST',requestBody: buildjson,url:"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxxxxxxx"
}
}
}
}
}
}