首先安装Jenkins
我这里使用docker-compose安装Jenkins
version: '3.7'
services:
jenkins:
#image: jenkinszh/jenkins-zh:latest
image: jenkinsci/blueocean
container_name: jenkins-blueocean
environment:
- TZ=Asia/Shanghai
volumes:
# jdk自己下载
- ./jdk1.8.0_311:/data/jdk1.8.0_311
#自定义的脚本
- ./shell-js:/data/shell-js:rw
- ./local/jenkins/jenkins_home:/var/jenkins_home:rw
#第三方jar
- ./repo:/data/repo:rw
- /var/run/docker.sock:/var/run/docker.sock
- /usr/bin/docker:/usr/bin/docker
- /usr/lib/x86_64-linux-gnu/libltdl.so.7:/usr/lib/x86_64-linux-gnu/libltdl.so.7
ports:
- "8099:8080"
expose:
- "8080"
- "50000"
privileged: true
user: root
restart: always
command:
- --httpPort=8080
- --prefix=/jenkins
执行:docker-compose up -d
执行一些Jenkins需要的插件
创建流水线
配置流水线:设置参数
配置流水线:设置脚本
配置流水线: Jenkinsfile编写
import groovy.json.JsonSlurperClassic
pipeline {
agent any
//动态参数
environment{
HARBOR_HOST = "127.0.0.1"
BUILD_VERSION = createVersion()
//服务器
service_name = "service-name"
service_host = "127.0.0.1"
service_user = "root"
service_password = "root123"
service_allowAnyHosts = true
project_branch = "dev"
nacos_url = "nacos:8848"
git_value = "zhangsan"
git_branch = "dev"
}
//设置工具 maven jdk
tools {
// Install the Maven version configured as "M3" and add it to the path.
maven "M3"
jdk "JDK1.8"
}
//设置参数
options {
timestamps() //设置在项目打印日志时带上对应时间
disableConcurrentBuilds() //不允许同时执行流水线,被用来防止同时访问共享资源等
timeout(time: 20, unit: 'MINUTES') // 设置流水线运行超过n分钟,Jenkins将中止流水线
buildDiscarder(logRotator(numToKeepStr: '10')) // 表示保留n次构建历史
}
stages {
stage('init') {
steps{
script{
//路径处理
println env.WORKSPACE
dir("${env.WORKSPACE}/testdata"){ //切换到当前工作目录下的testdata目录
sh "pwd" //sh命令可以 sh "command..." 也可以 sh("command....")
}
sh("ls -al ${env.WORKSPACE}")
deleteDir() // clean up current work directory //清空目录
sh("ls -al ${env.WORKSPACE}")
//开始处理
def projectNameChoose="${checkBuild}"
echo "projectNameChoose = $projectNameChoose"
if("$projectNameChoose" != ''){
echo "多线执行"
def branches = [:]
for (p_name in projectNameChoose.tokenize(',')){
def objectName = "${p_name}"
branches["${objectName}"] = {
try {
stage("${objectName}"){
// sh "mkdir ./${objectName}"
dir("./${objectName}"){
echo "objectName = ${objectName}"
//git clone
def gitUrl = 'http://github.com/zhangsan/$git_value.git'
git credentialsId:'515903eb-6acc-4bea-9565-10fd54aa845b',url: gitUrl,branch:'$git_branch'
//mvn install
sh "mvn package -Dmaven.test.skip -U -pl ${git_value}"
sh "docker build -f /data/shell-js/Dockerfile -t ${objectName}:$BUILD_VERSION --build-arg JAR_PATH=${git_value}/target/${git_value} --build-arg JAR_PORT=8080 ."
sh "docker tag ${objectName}:$BUILD_VERSION ${HARBOR_HOST}/dev/${objectName}:$BUILD_VERSION "
sh "docker login ${HARBOR_HOST} -u admin -p Harbor12345"
sh "docker push ${HARBOR_HOST}/dev/${objectName}:$BUILD_VERSION"
sh "docker rmi ${objectName}:$BUILD_VERSION"
def remote = [:]
remote.name = "$service_name"
remote.host = "$service_host"
remote.user = "$service_user" // 变量是注入到环境变量中的
remote.password = "$service_password" // 变量是注入到环境变量中的
remote.allowAnyHosts = "$service_allowAnyHosts"
sshCommand remote: remote, command: "/opt/docker-compose-spring/compose-spring.sh ${objectName} $BUILD_VERSION ${project_branch} ${nacos_url} 8080"
try {
sh "docker images | grep '${objectName}' | awk '{print \$3}'"
sh "docker rmi \$(docker images | grep '${objectName}' | awk '{print \$3}')"
}catch(Exception e){
echo "删除失败"
}
}
}
}catch(Exception e){
currentBuild.result = 'FAILURE'
}
}
}
// //异步执行
timestamps {
parallel branches
}
}
}
}
}
}
}
def createVersion() {
// 定义一个版本号作为当次构建的版本,输出结果 20201116165759_1
return new Date().format('yyyyMMddHHmmss') + "_${env.BUILD_ID}"
}
配置流水线: compose-spring.sh 编写
#!/bin/bash
application_name=$1
application_version=$2
profiles_active=$3
server_addr=$4
server_port=$5
echo "application_name=$application_name application_version = $application_version profiles_active = $profiles_active server_addr=$server_addr server_port = $server_port "
if [ ! -d "/data/$application_name" ];then
echo "文件夹不存在"
mkdir /data/$application_name/
touch /data/$application_name/docker-compose.yml
else
echo "文件夹存在"
docker-compose -f /data/$application_name/docker-compose.yml stop $application_name
echo y | docker-compose -f /data/$application_name/docker-compose.yml rm $application_name
rm -rf /data/$application_name
mkdir /data/$application_name/
touch /data/$application_name/docker-compose.yml
fi
# 部分需要扩大内存
memory="2G"
if [ "linux-spring" = "$application_name" ];then
memory="4G"
fi
echo "删除$application_name历史镜像"
{ # try
echo "$application_name历史images"
docker images | grep "$application_name" | awk '{print $3}'
echo "开始删除$application_name历史images"
docker rmi $(docker images | grep "$application_name" | awk '{print $3}')
} || { # catch
# save log for exception
echo "$application_name暂无可删除镜像"
}
echo "生成 $application_name docker-compose.yml"
cat > /data/$application_name/docker-compose.yml << EOF
version: '3.7'
services:
${application_name}:
image: 127.0.0.1:8080/dev/${application_name}:${application_version}
container_name: ${application_name}
environment:
- TZ=Asia/Shanghai
- spring.profiles.active=${profiles_active}
- spring.cloud.nacos.config.server-addr=${server_addr}
- server.port=${server_port}
- LOG_FILE=${application_name}
- LOG_PATH=/var/log/${application_name}
volumes:
- /var/log/${application_name}:/var/log/${application_name}
ports:
- "${server_port}:${server_port}"
privileged: true
user: root
restart: always
deploy:
resources:
limits:
cpus: "0.5"
memory: ${memory}
reservations:
cpus: "0.1"
memory: 500M
networks:
application:
aliases:
- ${application_name}
networks:
application:
name: linux
driver: bridge
EOF