软件开发最初是由两个团队共同组成:(没有采用DevOps之前)
没有采用DevOps的缺点:
采用DevOps的优点?
整体的软件开发流程:
为了保证整体流程可以高效的完成,各个阶段都有比较常见的工具,如下图:
// 所有脚本命令包含在pipeline{}中
pipeline {
// 指定任务在哪个Jenkins集群节点中执行(Jenkins是支持分布式)
// 这里的agent any是指该任务可以在任何Jenkins集群节点上执行。
agent any
// 声明全局变量,格式为:key='value'
environment{
host = '192.168.184.80'
}
// 存放所有任务的合集
stages {
// 单个任务1
stage('任务1') {
// 实现任务的具体流程
steps {
echo '做任务1'
}
}
// 单个任务2
stage('任务2') {
// 实现任务的具体流程
steps {
echo '做任务2'
}
}
// 单个任务3
stage('任务3') {
// 实现任务的具体流程
steps {
echo '做任务3'
}
}
}
}
pipeline {
agent any
// 存放所有任务的集合
stages {
stage('拉取Git仓库代码') {
steps {
echo '拉取Git仓库代码 - SUCCESS'
}
}
stage('通过maven构建项目') {
steps {
echo '通过maven构建项目 - SUCCESS'
}
}
stage('通过SonarQube做代码质量检测') {
steps {
echo '通过SonarQube做代码质量检测 - SUCCESS'
}
}
stage('通过Docker制作自定义镜像') {
steps {
echo '通过Docker制作自定义镜像 - SUCCESS'
}
}
stage('将自定义镜像推送到Harbor仓库') {
steps {
echo '将自定义镜像推送到Harbor仓库 - SUCCESS'
}
}
stage('通过Publish Over SSH通知目标服务器') {
steps {
echo '通过Publish Over SSH通知目标服务器 - SUCCESS'
}
}
}
}
1:配置git参数:(根据tag去拉取代码)
2:生成拉取git代码的流水线语法:
checkout([$class: 'GitSCM', branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[url: 'http://192.168.184.70:8929/root/mytest.git']]])
sh '/var/jenkins_home/maven/bin/mvn clean package -DskipTests'
sh '/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=${JOB_NAME} -Dsonar.java.binaries=./target/ -Dsonar.login=7ad2200f7cca90c37a909fdba8db049ac700909f'
sh '''mv ./target/*.jar ./docker/
docker build -t ${JOB_NAME}:${tag} ./docker/'''
environment{
harborAddress = '192.168.184.80:80'
harborRepo = 'repo'
harborUser = 'admin'
harborPasswd = 'Harbor12345'
}
sh '''docker login -u ${harborUser} -p ${harborPasswd} ${harborAddress}
docker tag ${JOB_NAME}:${tag} ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}
docker push ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}'''
4:防止Jenkins内部不能使用Docker,所以重新设置一下权限:(有时候即使设置了权限也会自动变回来,导致pipeline报错)
[root@centos7-jenkins harbor]# cd /var/run/
[root@centos7-jenkins run]# chown root:root docker.sock
[root@centos7-jenkins run]# chmod o+rw docker.sock
5:将上面生成的语法放到Jenkinsfile的对应位置上去,然后上传到gitlab即可。
vi /root/deploy.sh
内容如下:
harbor_addr=$1
harbor_repo=$2
project=$3
version=$4
host_port=$5
container_port=$6
imageName=$harbor_addr/$harbor_repo/$project:$version
containerId=`docker ps -a | grep ${project} | awk '{print $1}'`
if [ "$containerId" != "" ] ; then
docker stop $containerId
docker rm $containerId
fi
tag=`docker images | grep ${project} | awk '{print $2}'`
if [[ "$tag" =~ "$version" ]] ; then
docker rmi -f $imageName
fi
docker login -u admin -p Harbor12345 $harbor_addr
docker pull $imageName
docker run -d -p $host_port:$container_port --name $project $imageName
echo "SUCCESS"
chmod a+x /root/deploy.sh
[root@centos7-jenkins ~]# mv /root/deploy.sh /usr/bin/
5:生成流水线语法:
deploy.sh $harborAddress $harborRepo $JOB_NAME $tag $host_port $container_port
6:将生成的语法放到Jenkinsfile的对应位置上去,然后上传到gitlab即可。(⭐注意这里有个坑!⭐)
⭐下面的是修改之后的,并且是测试通过的流水线语法!!:
sshPublisher(publishers: [sshPublisherDesc(configName: 'mytest', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "deploy.sh $harborAddress $harborRepo $JOB_NAME $tag $host_port $container_port", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
post {
success {
dingtalk (
robot: 'Jenkins-dingding',
type:'MARKDOWN',
title: "success: ${JOB_NAME}",
text: ["- 成功构建:${JOB_NAME}项目!\n- 版本:${tag}\n- 持续时间:${currentBuild.durationString}\n- 任务:#${JOB_NAME}"]
)
}
failure {
dingtalk (
robot: 'Jenkins-dingding',
type:'MARKDOWN',
title: "fail: ${JOB_NAME}",
text: ["- 失败构建:${JOB_NAME}项目!\n- 版本:${tag}\n- 持续时间:${currentBuild.durationString}\n- 任务:#${JOB_NAME}"]
)
}
}
pipeline {
agent any
environment{
harborAddress = '192.168.184.80:80'
harborRepo = 'repo'
harborUser = 'admin'
harborPasswd = 'Harbor12345'
}
// 存放所有任务的集合
stages {
stage('拉取Git仓库代码') {
steps {
checkout([$class: 'GitSCM', branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[url: 'http://192.168.184.70:8929/root/mytest.git']]])
}
}
stage('通过maven构建项目') {
steps {
sh '/var/jenkins_home/maven/bin/mvn clean package -DskipTests'
}
}
stage('通过SonarQube做代码质量检测') {
steps {
sh '/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=${JOB_NAME} -Dsonar.java.binaries=./target/ -Dsonar.login=7ad2200f7cca90c37a909fdba8db049ac700909f'
}
}
stage('通过Docker制作自定义镜像') {
steps {
sh '''mv ./target/*.jar ./docker/
docker build -t ${JOB_NAME}:${tag} ./docker/'''
}
}
stage('将自定义镜像推送到Harbor仓库') {
steps {
sh '''docker login -u ${harborUser} -p ${harborPasswd} ${harborAddress}
docker tag ${JOB_NAME}:${tag} ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}
docker push ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}'''
}
}
stage('通过Publish Over SSH通知目标服务器') {
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: 'mytest', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "deploy.sh $harborAddress $harborRepo $JOB_NAME $tag $host_port $container_port", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
}
post {
success {
dingtalk (
robot: 'Jenkins-dingding',
type:'MARKDOWN',
title: "success: ${JOB_NAME}",
text: ["- 成功构建:${JOB_NAME}项目!\n- 版本:${tag}\n- 持续时间:${currentBuild.durationString}\n- 任务:#${JOB_NAME}"]
)
}
failure {
dingtalk (
robot: 'Jenkins-dingding',
type:'MARKDOWN',
title: "fail: ${JOB_NAME}",
text: ["- 失败构建:${JOB_NAME}项目!\n- 版本:${tag}\n- 持续时间:${currentBuild.durationString}\n- 任务:#${JOB_NAME}"]
)
}
}
}