Jenkins项目部署
1、docker安装
2、nexus安装和docker私服配置
3、Jenkins安装和配置
4、Jenkins基本项目部署
5、jenkins使用pipeline部署项目到docker
文章目录
前言
最近公司的项目采用了Jenkins的流水线pipeline脚本来部署项目,今天也写过博客记录一下。
项目部署,首先要安装Jenkins及相关插件(Subversion、Publish over SSH、Pipeline)以及安装配置Docker,部署采用两台centos7的linux服务器来进行的,A服务器上需要安装Jenkins,docker,maven,jdk1.8,B服务器需要安装docker,jdk1.8以及docker私服,我这里是使用nexus来配置的docker私服
一、配置Jenkins
在创建流水线任务前,我们还需要一些环境配置,项目我们就先配置一下。
1.配置JDK和MAVEN
在jenkins系统,Manage Jenkins ->Global Tool Configuration中配置
在该配置下找到JDK和MAVEN的配置项,根据要求填写配置
这样子JDK和MAVEN就配置好了,其实就是配置JDK和MAVEN的安装路径,一般配置错误了,会出现警告,如:
2.配置用户凭证
配置用户凭证,就相当于登录需要的用户权限,这里要配置的是远程centos服务器的登录用户名密码还有SVN拉取代码需要的用户名和密码。
在jenkins系统,Manage Jenkins ->Manage Credentials->添加凭据
两次配置都是这样子的,新增两次配置,分别输入远程服务器和svn的用户名和密码保存就可以了。
3.配置Publish over SSH远程连接
配置这个SSH的远程连接目录,主要是等下部署时需要连接这个服务器,访问一些文件进行项目部署。
在jenkins系统,Manage Jenkins ->Configure System中配置Publish over SSH
这样子配置了以后,发现是连接不了的,因为没有密码,我们点击高级,选择Use password authentication, or use a different key,就可以配置密码了,然后测试连接,发现就可以了。
连接成功以后,我们就可以开始正式进行流水线项目构建了。
二、创建pipeline任务以及配置
大家可以先看看pipeline的概述,语法,我在网上随便找了个博客,大家随便看看:pipeline概述
1.创建pipeline任务
选择流水线或者pipeline任务,创建。
2.设置参数
创建以后,我们首先需要设置一些参数,等下部署的时候,可以动态的变更。
首先在首页选择刚刚创建的任务,进去后选择配置
勾选This project is parameterized,添加一个string类型的参数
我这里由于需要4个参数,所以我们添加4个string类型的参数
参数设置后以后,就可以编写pipeline脚本了。
3.编写pipeline脚本
脚本主要处理流程如下
从SVN取得代码->打包镜像->上传镜像->部署
Jenkins提供了流水线语法生成功能
3.1.从svn拉取代码
在流水线语法中选择checkout:Check out form version control
如何点击生成流水线脚本,复制脚本
3.2.打包镜像
删除本地已存在镜像,打包生成新镜像,这里是直接编写linux,shell命令
sh '''
containerStr=`docker ps -a | grep -w ${imageName} | awk '{print $1}'`
imageStr=`docker images | grep -w $imageName | awk '{print $3}'`
agent=/root/.jenkins/workspace/CPSDEMO/${single_project_name}/agent
echo "container id:$containerStr"
echo "image id:$imageStr"
echo "agent path:$agent"
if [ "$imageStr" != "" ] ; then
if [ "$containerStr" != "" ] ; then
#停掉容器
docker stop `docker ps -a | grep -w ${imageName} | awk '{print $1}'`
#删除容器
docker rm `docker ps -a | grep -w ${imageName} | awk '{print $1}'`
#删除镜像
docker rmi --force ${imageName}
else
#删除镜像
docker rmi --force ${imageName}
fi
fi
mvn -f ${project_name}/pom.xml clean install dockerfile:build -Dautoconfig.skip=true -Dmaven.test.skip=false -Dmaven.test.failure.ignore=true
'''
3.3.上传镜像
删除仓库老镜像、重命名镜像、上传重命名新镜像
sh '''
#(1)判断本地是否已存在该项目的镜像,存在则先删除
regName=${registry_url}/$imageName
imageStr=`docker images | grep -w $regName | awk '{print $3}'`
if [ "$imageStr" != "" ] ; then
#将仓库中的镜像名称删除
docker rmi ${registry_url}/${imageName}:$tag
fi
#(2)必须要先将镜像的名称给变成 域名或ip/镜像名
docker tag ${imageName}:${tag} ${registry_url}/$imageName
#(3)删除本地镜像
docker rmi $imageName:${tag}
#(4)推送到本地的仓库上
docker push ${registry_url}/$imageName
'''
3.4.部署镜像
部署需要流水线语法来自动生成,我们在流水线语法中选择sshPublisher:Send build artifacts over SSH
填写信息后,点击生成流水线脚本,复制到pipeline脚本中,这里脚本命令中的deploy_image.sh文件,在执行pipeline脚本时,会找到该文件,执行部署的相关命令,同时该文件还引用了一个删除镜像的脚本delete_image.sh文件关闭运行的项目容器和删除镜像,在使用sh文件时,请先给他们授权,chmod 777 deploy_image.sh,chmod 777 delete_image.sh
3.5.完整脚本代码
pipeline脚本
pipeline {
agent any
environment {
def imageName = "${group_id}/${project_name}"
def tag="latest"
}
parameters {
string(name:'group_id', defaultValue: 'xxx', description: '项目groupId')
string(name:'registry_url', defaultValue: '192.168.2.364:8088', description: '镜像仓库地址')
string(name:'port', defaultValue: '8801', description: '部署镜像端口')
}
tools {
maven "maven"
}
stages {
stage('从svn拉取代码') {
steps {
checkout([$class: 'SubversionSCM', additionalCredentials: [], excludedCommitMessages: '', excludedRegions: '', excludedRevprop: '', excludedUsers: '', filterChangelog: false, ignoreDirPropChanges: false, includedRegions: '', locations: [[cancelProcessOnExternalsFail: true, credentialsId: 'b3aedbd2-88e2-47e5-a493-66026f5d3bc6', depthOption: 'infinity', ignoreExternalsOption: true, local: '.', remote: 'https://192.168.4.625/svn/Demo']], quietOperation: true, workspaceUpdater: [$class: 'UpdateUpdater']])
}
}
// maven 编译依赖项目
stage('编译项目依赖') {
steps {
script {
sh '''
mvn -f pom.xml clean install -Dautoconfig.skip=true -Dmaven.test.skip=true -Dmaven.test.failure.ignore=true
'''
}
}
}
// 本地镜像删除(如果存在)、生成新镜像
stage('打包上传镜像') {
steps {
script {
sh '''
str1=`docker ps -a | grep -w ${imageName} | awk '{print $1}'`
str2=`docker images | grep -w $imageName | awk '{print $3}'`
if [ "$str2" != "" ] ; then
if [ "$str1" != "" ] ; then
#停掉容器
docker stop `docker ps -a | grep -w ${imageName} | awk '{print $1}'`
#删除容器
docker rm `docker ps -a | grep -w ${imageName} | awk '{print $1}'`
#删除镜像
docker rmi --force ${imageName}
else
#删除镜像
docker rmi --force ${imageName}
fi
fi
#打包镜像
mvn -f ${project_name}/pom.xml clean install dockerfile:build -Dautoconfig.skip=true -Dmaven.test.skip=false -Dmaven.test.failure.ignore=true
'''
}
}
}
//删除仓库老镜像、重命名镜像、上传重命名新镜像
stage('上传镜像') {
steps {
script {
sh '''
#(1)判断本地是否已存在该项目的镜像,存在则先删除
imgName=${registry_url}/$imageName
str=`docker images | grep -w $imgName | awk '{print $3}'`
if [ "$str" != "" ] ; then
#将仓库中的镜像名称删除
docker rmi ${registry_url}/${imageName}:$tag
fi
#(2)必须要先将镜像的名称给变成 域名或ip/镜像名
docker tag ${imageName}:${tag} ${registry_url}/$imageName
#(3)删除本地镜像
docker rmi $imageName:${tag}
#(4)推送到本地的仓库上
docker push ${registry_url}/$imageName
'''
}
}
}
// 实际部署的机器上运行,把已经运行的镜像停止、删除.从镜像仓库下载新镜像、运行、启动新镜像
stage('部署镜像') {
steps {
script {
sshPublisher(publishers: [sshPublisherDesc(configName: 'server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "/usr/local/work/sh/deploy_image.sh $imageName $tag $port $port $registry_url", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
}
}
}
deploy_image.sh文件
#! /bin/sh
registryAddr=$5
imageName=${registryAddr}/$1
tag=$2
imagePort=$3
hostPort=$4
#不用停止WEB服务就可以清空nohup.out的命令
#Linux下还有一个特殊的文件/dev/null,它就像一个无底洞,所有重定向到它的信息都会消失得无影无踪
cp /dev/null nohup.out
#停掉容器、删除容器、删除镜像
/usr/local/del/delete_image.sh $imageName $tag
#pull镜像
docker pull $imageName:$tag
#运行镜像
docker run --net=host -d -p ${imagePort}:${hostPort} -t ${imageName}:$tag
delete_image.sh文件
#! /bin/sh
#镜像名称
imageName=$1
tag=$2
#得到容器或镜像信息
str1=`docker ps -a | grep -w ${imageName}:${tag} | awk '{print $1}'`
str2=`docker images | grep -w $imageName | awk '{print $3}'`
if [ "$str2" != "" ] ; then
if [ "$str1" != "" ] ; then
#停掉容器
docker stop `docker ps -a | grep -w ${imageName}:${tag} | awk '{print $1}'`
#删除容器
docker rm `docker ps -a | grep -w ${imageName}:${tag} | awk '{print $1}'`
#删除镜像
docker rmi --force ${imageName}:${tag}
else
#删除镜像
docker rmi --force ${imageName}:${tag}
fi
fi
这就是全部的构建文件了,里面的一些语法可以自己先百度了解了解,不然可能有点看不懂,一步步来。
4.执行构建任务
最后,就保存配置,返回项目,填写项目信息,开始构建
构建时你也可以点击查看日志,最后这个构建步骤没有报红,说明已经成功了,你就可以尝试使用ip:端口访问你的项目,注意端口是否放行
总结
上面就是Jenkins使用pipeline部署项目的全部步骤了,其中最核心的其实就是pipeline语法,还有动态参数的获取和定义参数这些,所以不了解语法,建议先去网上学习一下。