前言

本节需要对jenkinsfile有点了解,对dockerfile有点了解,对shell有点了解,对docker有点了解

执行流程

  1. jenkins拉取代码仓库中的代码
  2. jenkins执行jenkinsfile文件(可指定文件名)
  3. 先在jenkins所在的服务器将拉取的项目build成docker镜像
  4. 将镜像发布到镜像仓库(我这里是腾讯云配置的私有仓库)
  5. 在应用服务器的节点上将该镜像拉取下来(私有仓库需要用户名/密码)
  6. 在应用服务器上执行该镜像

一、jenkins配置

创建一个Pipeline SCM项目 jenkins项目名为springboot-test (和发布的工程名保持一致)

Definition选择 【Pipeline Script from SCM】

Branch Specifier(blank for 'any'):选择分支

Additional Behaviours: 添加邮箱通知的发送者 【这里没有写】

Script Path: 填写使用项目中的Jenkinsfile文件的名字

二、应用工程配置

在工程的根目录下创建Dockerfile文件和Jenkins_docker文件

jenkinsfile_docker文件内容如下

// docker集成docker部署
pipeline {
agent {label 'master'}
tools{
maven 'maven'
} environment {
GIT_PROJECT_ADDR="git@gitee.com:uncleqiao/springboot-test.git" //项目的git地址
JENKINS_WORKSPACE="/root/.jenkins/workspace" //jenkins存放文件的地址
PROJECT_NAME="${JOB_NAME}" // 项目名
JAR_NAME="springboot-test-0.0.1-SNAPSHOT.jar" // 项目生成的jar的名字
IMAGE_NAME="springboot-test" // 镜像名一般和项目名相同
IMAGE_ADDR="ccr.ccs.tencentyun.com/qiao_namespace/${IMAGE_NAME}" // 镜像的位置
VERSION_ID="${BUILD_ID}"
}
stages {
stage('pullCode'){
steps{
echo 'This is a pullCode step'
//git branch: "${BRANCH}", credentialsId: '1001', url: "${GIT_PROJECT_ADDR}"
checkout scm
}
}
stage('Build') {
steps{
echo 'This is a Build step'
// 在有Jenkinsfile同一个目录下(项目的根目录下)
sh 'mvn clean package -Dmaven.test.skip=true'
}
}
// 创建目录(如果不存在),并把jar文件上传到该目录下
stage('ssh') {
steps{
echo 'push jar to target server'
sh '''
ole_image_id=`docker images|grep ${IMAGE_NAME}|grep ${VERSION_ID}|awk '{print $3}'`
if [[ -n "${ole_image_id}" ]]; then
docker rmi -f ${ole_image_id}
fi docker build -f Dockerfile --build-arg jar_name=${JAR_NAME} -t ${IMAGE_NAME}:${VERSION_ID} . new_image_id=`docker images|grep ${IMAGE_NAME}|grep ${VERSION_ID}|awk '{print $3}'`
sudo docker tag ${new_image_id} ${IMAGE_ADDR}:${VERSION_ID}
sudo docker push ${IMAGE_ADDR}:${VERSION_ID}
'''
}
}
stage('run') {
// 在应用服务器节点 test
agent {
node {
label 'test'
//customWorkspace "${SERVER_TARGET_PATH}" //此参数会初始化目录 注意填写
}
}
options {
// 不让它切换到节点上自动从仓库拉取项目
skipDefaultCheckout()
}
steps {
echo 'pull image and docker run'
withEnv(['JENKINS_NODE_COOKIE=dontKillMe']) {
sh '''
sudo docker login --username=yourusername --password=yourpassword ccr.ccs.tencentyun.com
sudo docker pull ${IMAGE_ADDR}:${VERSION_ID} container_id=`docker ps|grep ${IMAGE_ADDR}:${VERSION_ID}|awk '{print $1}'`
if [ -n "${container_id}" ]; then
docker rm -f "${container_id}"
fi old_pid=`ps -ef|grep ${JAR_NAME}|grep -v grep|awk '{print $2}'`
if [[ -n $old_pid ]]; then
kill -9 $old_pid
fi old_image=`docker images|grep ${IMAGE_ADDR}|grep ${VERSION_ID}`
if [[ -n $old_image ]]; then
old_image_id=`echo ${old_image}|awk '{print $3}'`
docker rmi -f ${old_image_id}
fi sudo docker run --name "${PROJECT_NAME}_${VERSION_ID}" -p 9001:8081 -d ${IMAGE_ADDR}:${VERSION_ID}
'''
}
}
}
}
}

注意:

  • if [ -n str ] 这个命令在使用的时候如果str为空,也是true,可以使用 if [ -n ${str} -a "${str}x" != "x" ]或者使用if [[ -n ${str} ]]来判断
  • shell语法中,$()` 和 `` (两个单引号) 可以在子shell中执行命令,但是这儿$()不支持
  • idea没有jenkinsfile的语法提示,很容易出错,这个很难受

步骤一:拉取项目 在【pullCode】步骤中

checkout scm , 这个scm是创建jenkins流水线时选择的,属于特殊变量,代表了你的仓库信息,自动从仓库中获取项目

步骤二: 【Build】

将拉取下来的项目进行编译并打包

步骤三:【build_image】 将打包好的项目build成docker镜像,然后推送到镜像仓库(这里可以分成两步)

# 获取已经存在的镜像
ole_image_id=`docker images|grep ${IMAGE_NAME}|grep ${VERSION_ID}|awk '{print $3}'`
# 删掉存在的镜像
if [[ -n "${ole_image_id}" ]]; then
docker rmi -f ${ole_image_id}
fi
# 通过项目根目录下的Dokcerfile来构建镜像 -f filename --build-arg <key=value> 给Dockerfile传递参数
# -t 镜像的名称:版本 这里我将jenkins的构建次数当作镜像的版本
docker build -f Dockerfile --build-arg jar_name=${JAR_NAME} -t ${IMAGE_NAME}:${VERSION_ID} . # 获取构建好的镜像的id
new_image_id=`docker images|grep ${IMAGE_NAME}|grep ${VERSION_ID}|awk '{print $3}'` # 根据生成的镜像,tag出一个名称空间不同的镜像(腾讯云能识别的镜像)
sudo docker tag ${new_image_id} ccr.ccs.tencentyun.com/qiao_namespace/${IMAGE_NAME}:${VERSION_ID} # 将镜像仓库能够试别的镜像推送到仓库
sudo docker push ccr.ccs.tencentyun.com/qiao_namespace/${IMAGE_NAME}:${VERSION_ID}

步骤四:【run】应用服务器拉取项目并且运行, 这一步要选择节点(应用服务器,如果是集群,就不用节点用scp登陆吧)

# 登陆到镜像仓库
sudo docker login --username=yourusername --password=yourpassword ccr.ccs.tencentyun.com
# 从仓库中拉取刚才生成的镜像
sudo docker pull ccr.ccs.tencentyun.com/qiao_namespace/${IMAGE_NAME}:${VERSION_ID} # 查看已经存在的容器, 存在则删掉 存在则删掉 这里应该是一个数组,有点小问题,待修改
container_id=`docker ps|grep ${IMAGE_ADDR}:${VERSION_ID}|awk '{print $1}'`
if [ -n "${container_id}" ]; then
docker rm -f "${container_id}"
fi
# 查看已经运行的同版本的项目, 存在则删掉 这里应该是一个数组,有点小问题,待修改
pid=`ps -ef|grep ${JAR_NAME}|grep -v grep|awk '{print $2}'`
if [[ -n $pid ]]; then
kill -9 $pid
fi
# 查看已经存在的镜像, 存在则删掉 这里应该是一个数组,有点小问题,待修改
old_image=`docker images|grep ${IMAGE_ADDR}|grep ${VERSION_ID}`
if [[ -n $old_image ]]; then
old_image_id=`echo ${old_image}|awk '{print $3}'`
docker rmi -f ${old_image_id}
fi
# 运行容器
sudo docker run --name "${PROJECT_NAME}_${VERSION_ID}" -p 9001:8081 -d ${IMAGE_ADDR}:${VERSION_ID}

Dockerfile

文件内容如下

FROM ccr.ccs.tencentyun.com/qiao_namespace/myjdk8:v1

# 默认jar包的名字 注意分隔符为 :-  这里是由jenkinsfile中build dockerfile时传递过来的
ARG jar_name={jar_name:-springboot-test-0.0.1-SNAPSHOT.jar} # RUN 用于容器内部执行命令
RUN mkdir -p /usr/local/project
WORKDIR /usr/local/project # 将项目放到/usr/local/project下
COPY ./target/springboot-test-0.0.1-SNAPSHOT.jar ./ EXPOSE 8081 CMD java -jar -Dserver.port=8081 springboot-test-0.0.1-SNAPSHOT.jar

执行完毕后我们登陆到应用服务器

看到容器已经启动,docker exec 进入到容器看到文件是存在的

最新文章

  1. Python中获取当前日期的格式
  2. Codeigniter 3.0 相关文档 part two
  3. sqlite实现oracle的rownum功能
  4. TCP状态转换图详解
  5. 今天逛VC驿站 的收获
  6. PostgreSQL Insight Monitor pgstat
  7. intellij idea 10.5介绍
  8. Intellij Idea 12 生成serialVersionUID的方法
  9. Web中的监听器【Listener】
  10. team geek
  11. Python自动化运维之28、Django(二)
  12. WIN7/8系统下程序接收不到WM_COPYDATA 消息的原因和解决
  13. Android高手进阶——Adapter深入理解与优化
  14. Linux中挂载Windows共享出来的目录
  15. Java虚拟机一 运行时数据区(栈、堆、方法区等)
  16. servlet进行用户名和密码校验
  17. 关于vue的混入使用
  18. PAT A1104 Sum of Number Segments (20 分)——数学规律,long long
  19. Windows Server 2016 路由和远程访问
  20. The difference between Spring Tool Suite and Spring IDE

热门文章

  1. SQL基础-过滤数据
  2. HTML之微信全屏播放视频
  3. sublime 添加到右键菜单
  4. Pandas使用实用技巧
  5. mysql e的n次幂exp()
  6. (一)Cisco DHCP Snooping原理(转载)
  7. Activiti task claim concurrent
  8. 算法名称 Alias Method
  9. 最稳定万能vip视频解析接口 支持HTTPS
  10. 使用office365 world2016发布编辑备份你的博客