基于devops利用微服务引入三方服务---多分支持续集成

1.创建分支及必须的脚本文件

以工程consumer为例
创建分支production、development

git branch production   
git branch development   
git checkout production   
git push -u origin production    
git checkout development   
git push -u origin development  
git checkout master   

查看代码仓库是否已经推送
07jenkins29

在创建多分支流水线之前查看代码结构
07jenkins36

创建应用所需的基础镜像文件
cat Dockerfile

FROM 192.168.0.152:8082/jre8:alphine
ADD target/*jar /tmp/
WORKDIR /tmp

CMD java -jar $(ls *.jar)

创建多分支流水线的pipeline
cat Jenkinsfile

pipeline {
    agent any
    tools {
        maven 'maven' 
    }
    environment {
                CI = 'true'
                 GROUP = readMavenPom().getGroupId()
                ARTIFACT = readMavenPom().getArtifactId()
                VERSION = readMavenPom().getVersion()
    }
    stages {
        stage('build master') {
            when {
                branch 'master'
            }
            steps {
                sh 'mvn clean install'
            }
        }
        stage('build development') {
            when {
                branch 'development' 
            }
            steps {
                sh 'mvn clean install'
            }
        }
        stage('build production') {
            when {
                branch 'production'  
            }
            steps {
                sh 'mvn clean install'
            }
        }
        stage('push image') {
            steps {
               script {
                    docker.withRegistry("http://192.168.0.152:8082",'01385c55-7871-4868-a03a-889c4dc403ec') {
                    def customimage = docker.build("${GROUP}-${ARTIFACT}:${VERSION}")
                    customimage.push()
                    }
                }
            }
        } 
       stage('master deploy') {
           when {
                branch 'master'
            }
           steps {
                  sh './jenkins/scripts/master-deploy.sh'
           }
      }
       stage('development deploy') {
           when {
                branch 'development'
            }
           steps {
                  sh './jenkins/scripts/development-deploy.sh'
           }
      }
       stage('production deploy') {
           when {
                branch 'production'
            }
           steps {
                  sh './jenkins/scripts/production-deploy.sh'
           }
      }
    }
}

创建各分支部署脚本
这里以production分支为例
cat jenkins/scripts/production-deploy.sh

#!/bin/bash

jarfile=$(echo $(ls target/*jar) | awk -F '/' '{print $2}')
jarname=${jarfile%.*}
tag=${jarname#*-}
cat <<EOF>>  docker-compose.yml
version: "3.4"
services:
  consumer:
    image: 192.168.0.152:8082/com.teng-consumer:$tag
    networks:
      - service_overlay
      - monitor_overlay
      - database_overlay
      - elk_overlay
    ports:
      - 8084:8084
    volumes:
      -  "/etc/localtime:/etc/localtime:ro"
    deploy:
      placement:
        constraints: [node.hostname==node150]
      restart_policy:
        condition: any
        delay: 5s
        max_attempts: 3
networks:
  service_overlay:
    external: true
  monitor_overlay:
    external: true
  database_overlay:
    external: true
  elk_overlay:
    external: true
EOF
scp docker-compose.yml root@192.168.0.150:/root/docker/consumer
ssh root@192.168.0.150 'cd /root/docker/consumer &&  docker stack deploy -c docker-compose.yml  150'

该脚本有三处需要注意

  • 需要对jenkins容器配置到swarm主节点的免密传输
  • 因为这里设置的是将服务部署在主节点且jenkins也部署在主节点,故脚本中没有进行应用镜像的pull操作,如果微服务部署到非主节点脚本中需要进行镜像拉取
  • 脚本里创建的docker-compose.yml文件要传到目标节点进行部署,故需要在服务部署的节点上事先创建服务运行的目录,这里是/root/docker/consumer

免密传输
docker exec -it jenkins_container_name bash
ssh-copy-id -i /var/jenkins_home/.ssh/id_rsa.pub root@192.168.0.150

2.创建多分支流水线

在创建前先清空各个分支的Jenkinsfile,等初始化完成了多分支流水线任务后,再将前面创建Jenkinsfile的内容添加进来

访问jenkins站点,打开blueocean,

07jenkins37

点击确定就会开始构建,最后正常的状态是如下图所示
07jenkins38

3.测试各个分支

以production分支为例,添加脚本到Jenkinsfile ,在multi-consumer点击运行
07jenkins39

4.更新应用

更新应用也就是要更新应用镜像,一般会针对某个分支进行重新打包编译生成新的镜像进行发布
还是以production为例,将pom.xml里的version升级为0.0.7-production,提交最新改动到gitlab仓库

修改发布脚本中的发布命令添加参数--prune
docker stack deploy -c docker-compose.yml --prune 150
重新执行流水线分支production

5.自动构建配置

多分支没有比较具体的自动触发插件,这里就直接使用gitlab的webhook来触发,配置gitlab
07jenkins40

注意连接中的multi-consumer为多分支流水线任务名称,配置好后,执行测试“push event” ,发现三个分支流水线同时开始运行,说明触发成功

如果提交变更到具体的某个分支则只会触发对应的分支进行构建,当然为了更为灵活的出发构建还可以在pipeline脚本中使用判断限制来告诉jenkins哪些分支出发后才能正常运行,哪些分支即时触发了构建但会返回错误不再进行后续的操作,最终的脚本如下
cat Jenkinsfile

pipeline {
    agent any
    tools {
        maven 'maven' 
    }
    environment {
                CI = 'true'
                 GROUP = readMavenPom().getGroupId()
                ARTIFACT = readMavenPom().getArtifactId()
                VERSION = readMavenPom().getVersion()
    }
    stages {
        
       stage('pipeline环境准备') {
            steps {
                script {
                    echo "开始构建"
                    if(!env.BRANCH_NAME.startsWith('production') && !env.BRANCH_NAME.startsWith('development')){
                        error("自动构建分支名称必须以production或development开头,当前分支名称为: ${env.BRANCH_NAME}")
                    }
                 }
            }
         }
        stage('build master') {
            when {
                branch 'master'
            }
            steps {
                sh 'mvn clean install'
            }
        }
        stage('build development') {
            when {
                branch 'development' 
            }
            steps {
                sh 'mvn clean install'
            }
        }
        stage('build production') {
            when {
                branch 'production'  
            }
            steps {
                sh 'mvn clean install'
            }
        }
        stage('push image') {
            steps {
               script {
                    docker.withRegistry("http://192.168.0.152:8082",'01385c55-7871-4868-a03a-889c4dc403ec') {
                    def customimage = docker.build("${GROUP}-${ARTIFACT}:${VERSION}")
                    customimage.push()
                    }
                }
            }
        } 
       stage('master deploy') {
           when {
                branch 'master'
            }
           steps {
                  sh './jenkins/scripts/master-deploy.sh'
           }
      }
       stage('development deploy') {
           when {
                branch 'development'
            }
           steps {
                  sh './jenkins/scripts/development-deploy.sh'
           }
      }
       stage('production deploy') {
           when {
                branch 'production'
            }
           steps {
                  sh './jenkins/scripts/production-deploy.sh'
           }
      }
    }
}

6.测试代码

multi-consumer