-
docker安装jenkins,安装方式不再复述。使用的本地gitlab管理代码,springboot项目
-
启动jenkins
docker run -u root \
-d \
-p 4900:8080 \ 访问端口
-p 50000:50000 \
-v /home/jenkins:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /home/apache-maven-3.6.3:/usr/local/maven \
-v /home/apache-maven-3.6.3/repository:/usr/local/maven_repository \
-v /home/jdk1.8.0_241:/usr/local/java \ 可以不用,自带jdk java -verbose查看目录
--name jenkins \
a20 镜像名称
如果不指定root,容器内写入操作会权限不足,或者docker exec -it -u root jenkins /bin/bash 进入容器。
jdk地址可以不用映射到宿主机,maven映射后发现在容器内还是不能使用mvn命令,但是脚本是可以的
-
系统管理 --> 全局工具配置
①maven配置,两个都选择文件系统中的settings文件 路径/usr/local/maven/conf/settings.xml
②JDK安装,使用java -verbose最后两行查看jdk地址,写在这就好了
③maven /usr/local/maven 启动时指定映射到本机的地址
JAVA_HOME我写的容器内安装的jdk路径,然后容器内profile也添加了JAVA_HOME,但是没起作用。索性也就用java -verbose中的地址了。
profile不用配置maven
然后应用保存 -
创建项目,选择多分支流水线
分支源 我写的gitlab项目地址,凭据添加,password类型,gitlab登录的用户名和密码
然后应用保存 -
扫描多分支流水线,就出现分支了,然后点分支名称进去可以触发构建
-
JenkinsFile,DockerFile,start.sh编写,三个文件都在根目录下
思路:mvn打包成jar,JenkinsFile脚本根据DockerFile把jar打成镜像,然后推送镜像仓库(harbor等)。启动start.sh(拉取镜像并run)
JenkinsFile
pipeline {
agent any
//全局的环境变量
environment {
registryUrl = "harbor地址"
registry_user = "harbor账号"
registry_pass = "harbor密码"
env = "test"
//指定版本号,否则每次都新版本号
tag = "0.0.1"
}
//预定义pipeline专有的配置信息
options {
timestamps()
disableConcurrentBuilds() //不允许同时执行流水线
buildDiscarder(logRotator(numToKeepStr: '3')) //表示保留n次构建历史
}
//gitlab webhook触发器 这一步还在测试
triggers {
gitlab(
triggerOnPush: true, //代码有push动作就会触发job
triggerOnMergeRequest: true,//代码有merge动作就会触发job
branchFilterType: "All", //只有符合条件的分支才会触发构建 “All/NameBasedFilter/RegexBasedFilter”
includeBranchesSpec: "${JOB_BASE_NAME}" //基于branchFilterType值,输入期望包括的分支的规则
)
}
stages {
//打印信息
stage('Print Message') {
steps {
echo "workspace: ${WORKSPACE} build_id: ${tag} branch(gitlab分支名): ${BRANCH_NAME}"
echo "registuryUrl: ${registryUrl}"
}
}
//mvn打包
stage('Packaging project') {
steps {
echo "mvn打包"
script {
try {
//刚开始使用mvn clean package 提示找不到mvn,所以就这样指定地址,指定配置文件
sh ' /usr/local/maven/bin/mvn -s /usr/local/maven/conf/settings.xml -gs /usr/local/maven/conf/settings.xml clean package'
} catch (err) {
echo 'mvn打包失败'
}
}
}
}
//构建,推送镜像
stage('Build & Push Image to Harbor') {
steps {
echo "构建,推送镜像"
dir('./') { //指定工作目录
script {
try {
sh 'pwd'
sh 'cp ./target/${JOB_NAME%%/*}-0.0.1-SNAPSHOT.jar ./${JOB_NAME%%/*}.jar'
sh 'docker build -t ${registryUrl}/${JOB_NAME%%/*}:${tag} .'
sh 'docker login ${registryUrl} -u ${registry_user} -p ${registry_pass}'
sh 'docker tag ${registryUrl}/${JOB_NAME%%/*}:${tag} ${registryUrl}/${JOB_NAME%%/*}/${JOB_NAME%%/*}:${tag}'
sh 'docker push ${registryUrl}/${JOB_NAME%%/*}/${JOB_NAME%%/*}:${tag}'
sh 'docker rmi ${registryUrl}/${JOB_NAME%%/*}/${JOB_NAME%%/*}:${tag}'
} catch (err) {
echo "构建失败"
}
}
}
//推送镜像后,删除工作空叫初Jenkinsfile & start.sh 以外所有文件
sh '''rm -rf `ls | egrep -v '(Jenkinsfile|start.sh)'` '''
}
}
stage('Deploy to the Target server') {
steps {
//设置远程部署超过40s,将终止该步骤
// timeout(time:40,unit,'SECONDS'){
//部署到${env}环境,授权
sh 'chmod u+x start.sh'
sh './start.sh ${JOB_NAME%%/*} ${registryUrl}/${JOB_NAME%%/*}/${JOB_NAME%%/*}:${tag} ${BRANCH_NAME}'
// }
}
}
stage('Delete Workspace') {
steps {
echo "清理工作目录: ${WORKSPACE}"
deleteDir()
}
}
}
}
如果需要自动构建,在jenkins项目–>具体分支–>查看配置–>构建触发器,有一个URL,–>高级 生成token,然后在gitlab上面项目–>设置–>集成 写上刚才项目URL,token,然后ok。
只写URL和Secret Token这两个就好了
Dockerfile
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ADD demo.jar test.jar
#编译镜像时运行的脚本,这里是授权并运行脚本
RUN sh -c 'touch /test.jar'
ENTRYPOINT [ "java", "-jar", "test.jar"]
EXPOSE 8060
start.sh
#!/bin/bash
#ENV
#Harbor
registryUrl=harbor地址
registry_user="harbor用户名"
registry_pass="harbor密码"
# 启动时跟的参数 $1 $2 $3
project_name=$1
image_name=$2
env=$3
node_user=root
if [ "${env}" == master ]; then
node1=192.168.1.22
elif [ "${env}" == test ]; then
node1=192.168.1.22
else
echo '没有${env}环境'
fi
echo "project_name: $1, image_name: $2, env: $3, node1: $node1"
ssh $node_user@$node1 docker login -u ${registry_user} -p ${registry_pass} ${registryUrl}
ssh $node_user@$node1 docker pull $image_name && docker rm -f $project_name || true
ssh $node_user@$node1 docker run -itd --name=$project_name --net=host -e TZ="Asia/Shanghai" $image_name
ssh $node_user@$node1 docker image prune -af
–net=host:容器中暴露的什么端口,宿主机就是什么端口;
docker image prune -af 删除未使用镜像
由于Pipeline(流水线)需要在目标服务器(例如:192.168.1.105)上执行操作,因此需要通过ssh连接。
(1)首先需要在Jenkins容器里面生成ssh的公钥密钥;
docker exec -it jenkins /bin/bash -c 'ssh-keygen -C "root@目标ip"'
(2)然后自行复制jenkins容器的公钥(/root/.ssh/id_rsa.pub)文件内容到目标服务器的/root/.ssh/authorized_keys文件中。
注意第一次连接目标服务器会提示一个交互动作(提示输入“yes”或者“no”继续操作),可以进入容器内ssh root&目标ip ls 看一下是否可以连接,正常的话会输出 ls 命令结果。
大功告成了。