可能会出现IP地址不统一的情况,那是因为是在两台电脑上配置的,不影响操作,只需要注意即可。

1 Jenkins+Docker+SpringCloud持续集成说明

1.1 概述

四、Jenkins Docker SpringCloud微服务持续集成(上) - 图1

  • 大致流程说明:
  • 四、Jenkins Docker SpringCloud微服务持续集成(上) - 图2开发人员每天将代码提交到Gitlab代码仓库。
  • 四、Jenkins Docker SpringCloud微服务持续集成(上) - 图3Jenkins从Gitlab中拉取项目代码,编译并打成jar包,然后构建Docker镜像,将镜像上传到Harbor私有仓库。
  • 四、Jenkins Docker SpringCloud微服务持续集成(上) - 图4Jenkins发送SSH远程命令,让生产部署服务器从Harbor私有仓库拉取镜像到本地,然后创建容器。
  • 四、Jenkins Docker SpringCloud微服务持续集成(上) - 图5最后,用户可以访问到容器。

1.2 服务器列表

服务器名称 IP地址 安装的软件
代码托管服务器 192.168.18.100 Gitlab(已安装)
持续集成服务器 192.168.18.101 Jenkins(已安装)、Maven(已安装)、Docker18.06.1-ce
Docker仓库服务器 192.168.18.102 Docker18.06.1-ce、Harbor2.1.3
生产服务器 192.168.18.103 Docker18.06.1-ce

2 微服务项目说明

四、Jenkins Docker SpringCloud微服务持续集成(上) - 图6

3 环境准备

3.1 Docker安装

3.2 Harbor的安装

3.2.1 前提说明

  • Harbor是在IP为192.168.18.102的服务器上安装的,并且使用的Docker Compose进行安装,而Docker Compose依赖于Docker,所以需要先安装Docker。
  • 关闭防火墙。

3.2.2 安装Docker Compose

  • 安装Docker Compose(网速不够,请点这里📎docker-compose.zip):
    1. sudo curl -L https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
  • 查看Docker Compose是否安装成功:
    docker-compose version
    

3.2.3 安装Harbor

  • 下载Harbor(网络不够,请点这里📎harbor-offline-installer-v2.1.3.tgz):

    wget https://github.com/goharbor/harbor/releases/download/v2.1.3/harbor-offline-installer-v2.1.3.tgz
    
  • 解压Harbor:

    tar -zxvf harbor-offline-installer-v2.1.3.tgz -C /usr/local
    
  • 修改Harbor的配置:

    cd /usr/local/harbor
    
mv harbor.yml.tmpl harbor.yml
vim harbor.yml
# 修改部分
hostname: 192.168.18.102
http:
  port: 85
# 将https注释掉  
# https:
  # https port for harbor, default is 443
  #  port: 443
  # The path of cert and key files for nginx
 # certificate: /your/certificate/path
 # private_key: /your/private/key/path
  • 安装Harbor:
    ./prepare
    
./install.sh
  • 启动、停止、重新启动Harbor:
    # 启动
    docker-compose up -d
    
# 停止
docker-compose stop
# 重新启动
docker-compose restart

3.2.4 访问Harbor

3.3 在Harbor中创建用户和项目

3.3.1 创建项目

  • Harbor的项目分为公开和私有。
  • 公开项目:所有的用户都可以访问,通常存放公共的镜像,默认有一个library公开项目。
  • 私有项目:只有授权用户才可以访问,通常存在项目本身的镜像。
  • 我们可以为微服务创建一个项目:

四、Jenkins Docker SpringCloud微服务持续集成(上) - 图7

3.3.2 创建用户

四、Jenkins Docker SpringCloud微服务持续集成(上) - 图8

四、Jenkins Docker SpringCloud微服务持续集成(上) - 图9
创建用户为:xudaxian/Xudaxian12345678。

3.3.3 给私有项目分配用户

  • 进入xudaxian-mall项目—>成员。

四、Jenkins Docker SpringCloud微服务持续集成(上) - 图10

角色 权限说明
访客 对于指定的项目拥有只读权限
开发人员 对于指定的项目拥有读写权限
维护人员 对于指定的项目拥有读写权限,创建webhooks
项目管理员 除了读写权限,同时拥有用户管理/镜像扫描等管理权限

3.3.4 以新用户登录Harbor

四、Jenkins Docker SpringCloud微服务持续集成(上) - 图11

3.4 把镜像上传到Harbor

  • 先拉取一个镜像,比如MySQL5.7。
docker pull mysql:5.7
  • 查询镜像:
docker images

把镜像上传到Harbor之查看镜像.png

  • 给镜像打tag:
docker tag mysql:5.7 192.168.18.102:85/xudaxian-mall/mysql:5.7

把镜像上传到Harbor之给镜像打tag.png

  • 推送镜像:
docker push 192.168.18.102:85/xudaxian-mall/mysql:5.7

把镜像上传到Harbor之推送镜像.png

之所以报错,是因为Docker没有将Harbor加入到信任列表中。

  • 在服务器192.168.18.101和192.168.18.102以及192.168.18.103把Harbor地址加入到Docker信任列表中:
vim /etc/docker/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "insecure-registries": ["192.168.18.102:85"],
  "registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"]
}
  • 重启Docker:
systemctl daemon-reload
systemctl restart docker
  • 重启Harbor:
cd /usr/local/harbor
docker-compose restart
  • 再次执行推送命令,提示权限不足:
docker push 192.168.18.102:85/xudaxian-mall/mysql:5.7

把镜像上传到Harbor之推送镜像提示权限不足.png

  • 登录Harbor:
docker login -u xudaxian -p Xudaxian12345678 192.168.18.102:85

Docker命令登录Harbor.png

  • 推送镜像:
docker push 192.168.18.102:85/xudaxian-mall/mysql:5.7

Docker将镜像上传到Harbor.png

Docker将镜像上传到Harbor2.png

3.5 从Harbor上拉取镜像

3.5.1 前提说明

  • 服务器的IP是192.168.18.103。

3.5.2 把Harbor地址加入到Docker信任列表中

  • 把Harbor地址加入到Docker信任列表中
vim /etc/docker/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "insecure-registries": ["192.168.18.102:85"],
  "registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"]
}
  • 重启Docker:
systemctl daemon-reload
systemctl restart docker

3.5.3 Docker命令登录Harbor

  • Docker命令登录Harbor:
    docker login -u xudaxian -p Xudaxian12345678 192.168.18.102:85
    

3.5.4 拉取镜像

  • 拉取镜像:
    docker pull 192.168.18.102:85/xudaxian-mall/mysql:5.7
    

4 微服务持续集成

4.1 项目代码上传到Gitlab

  • 在IDEA操作即可,参考之前的步骤,将微服务的代码上传到Gitlab中。

微服务持续集成之项目代码上传到Gitlab中.png

4.2 从Gitlab拉取项目源码

4.2.1 在Jenkins中新建和微服务同名的流水线项目

在Jenkins中新建和微服务同名的流水线项目.png

4.2.2 创建Jenkinsfile文件

  • Jenkinsfile:
//定义git凭证ID
def git_auth = "bacbbbb1-2df9-470d-adf8-5cb6dc496807"
//git的url地址
def git_url = "git@192.168.209.100:develop_group/jenkinscloud.git"

node {
    stage('拉取代码') {
        checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
    }
}

从Gitlab拉取项目源码之创建Jenkinsfile.png

4.3 提交到SonarQube代码审查

4.3.1 在Jenkins的项目jenkinscloud,添加一个参数

在Jenkins的项目jenkinscloud,添加一个参数.png

在Jenkins的项目jenkinscloud,添加一个参数2.png

在Jenkins的项目jenkinscloud,添加一个参数3.png

4.3.2 在每个微服务的根目录中添加sonar-project.properties文件

  • jenkinscloud-eureka微服务的根目录添加sonar-project.properties文件,内容如下:
# must be unique in a given SonarQube instance
sonar.projectKey=jenkinscloud-eureka
# this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1.
sonar.projectName=jenkinscloud-eureka 
sonar.projectVersion=1.0
# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
# This property is optional if sonar.modules is set.
sonar.sources=.
sonar.exclusions=**/test/**,**/target/**
sonar.java.binaries=.

sonar.java.source=11
sonar.java.target=11
# sonar.java.libraries=**/target/classes/**
# Encoding of the source code. Default is default system encoding
sonar.sourceEncoding=UTF-8
  • jenkinscloud-order微服务的根目录添加sonar-project.properties文件,内容如下:
# must be unique in a given SonarQube instance
sonar.projectKey=jenkinscloud-order
# this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1.
sonar.projectName=jenkinscloud-order
sonar.projectVersion=1.0
# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
# This property is optional if sonar.modules is set.
sonar.sources=.
sonar.exclusions=**/test/**,**/target/**
sonar.java.binaries=.

sonar.java.source=11
sonar.java.target=11
# sonar.java.libraries=**/target/classes/**
# Encoding of the source code. Default is default system encoding
sonar.sourceEncoding=UTF-8
  • jenkinscloud-product微服务的根目录添加sonar-project.properties文件,内容如下:
# must be unique in a given SonarQube instance
sonar.projectKey=jenkinscloud-product
# this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1.
sonar.projectName=jenkinscloud-product
sonar.projectVersion=1.0
# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
# This property is optional if sonar.modules is set.
sonar.sources=.
sonar.exclusions=**/test/**,**/target/**
sonar.java.binaries=.

sonar.java.source=11
sonar.java.target=11
# sonar.java.libraries=**/target/classes/**
# Encoding of the source code. Default is default system encoding
sonar.sourceEncoding=UTF-8

在每个微服务的根目录中添加sonar-project.properties文件.png

4.3.3 修改Jenkins构建脚本

  • Jenkinsfile:
//定义git凭证ID
def git_auth = "bacbbbb1-2df9-470d-adf8-5cb6dc496807"
//git的url地址
def git_url = "git@192.168.209.100:develop_group/jenkinscloud.git"

node {
    stage('拉取代码') {
        checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
    }
    stage('代码审查') {
        //定义当前Jenkins的SonarQubeScanner工具的环境
        def scannerHome = tool 'sonarqube-scanner'
        //引用当前Jenkins的SonarQube环境
        withSonarQubeEnv('sonarqube-8.6.0') {
          sh """
               cd ${project_name}
               ${scannerHome}/bin/sonar-scanner
          """
        }
    }
    //如果有公共子工程
//     stage('编译,安装公共的子工程') {
//        sh "mvn -f jenkinscloud-common clean install"
//     }
}

如果有jenkinscloud-common公共子工程,那么需要将spring-boot-maven-plugin插件从总工程移动到各个微服务工程,否则jenkinscloud-common公共子工程继承了总工程之后,spring-boot-maven-plugin插件会报错,因为找不到启动类。

4.4 编译打包微服务工程

  • Jenkinsfile:
//定义git凭证ID
def git_auth = "bacbbbb1-2df9-470d-adf8-5cb6dc496807"
//git的url地址
def git_url = "git@192.168.209.100:develop_group/jenkinscloud.git"

node {
    stage('拉取代码') {
        checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
    }
    stage('代码审查') {
        //定义当前Jenkins的SonarQubeScanner工具的环境
        def scannerHome = tool 'sonarqube-scanner'
        //引用当前Jenkins的SonarQube环境
        withSonarQubeEnv('sonarqube-8.6.0') {
          sh """
               cd ${project_name}
               ${scannerHome}/bin/sonar-scanner
          """
        }
    }
    //如果有公共子工程
//     stage('编译,安装公共的子工程') {
//        sh "mvn -f jenkinscloud-common clean install"
//     }
    stage('编译,打包微服务工程') {
       sh "mvn -f ${project_name} clean install"
    }

}

编译打包微服务工程.png

需要将每个微服务工程都编译打包。

4.5 使用Docker编译、生成镜像

4.5.1 前提说明

  • 利用dockerfile-maven-plugin插件来构建Docker镜像。
  • 因为我用的是JDK11,而JDK9以上就移除了javax.activation.activation的jar包,所以需要在每个微服务工程都加上依赖:
<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.3.0</version>
</dependency>
<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-core</artifactId>
    <version>2.3.0</version>
</dependency>
<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
    <version>2.3.0</version>
</dependency>
<dependency>
    <groupId>javax.activation</groupId>
    <artifactId>activation</artifactId>
    <version>1.1.1</version>
</dependency>

4.5.2 在每个微服务的pom.xml中加入dockerfile-maven-plugin插件

  • pom.xml
    <build>
        <plugins>
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>dockerfile-maven-plugin</artifactId>
                <version>1.4.13</version>
                <configuration>
                    <repository>${project.artifactId}</repository>
                    <tag>${project.version}</tag>
                    <buildArgs>
                        <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
                    </buildArgs>
                </configuration>
            </plugin>
        </plugins>
    </build>

4.5.3 在每个微服务根目录下新建Dockerfile文件

  • Dockerfile:
FROM openjdk 
ARG JAR_FILE
COPY ${JAR_FILE} app.jar 
# 注意每个项目公开的端口不一样
EXPOSE 9000
ENTRYPOINT ["java","-jar","/app.jar"]

4.5.4 修改Jenkinsfile

  • Jenkinsfile:
//定义git凭证ID
def git_auth = "bacbbbb1-2df9-470d-adf8-5cb6dc496807"
//git的url地址
def git_url = "git@192.168.209.100:develop_group/jenkinscloud.git"

node {
    stage('拉取代码') {
        checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
    }
    stage('代码审查') {
        //定义当前Jenkins的SonarQubeScanner工具的环境
        def scannerHome = tool 'sonarqube-scanner'
        //引用当前Jenkins的SonarQube环境
        withSonarQubeEnv('sonarqube-8.6.0') {
          sh """
               cd ${project_name}
               ${scannerHome}/bin/sonar-scanner
          """
        }
    }
    //如果有公共子工程
//     stage('编译,安装公共的子工程') {
//        sh "mvn -f jenkinscloud-common clean install"
//     }
    stage('编译,打包微服务工程') {
       // 修改部分 
       // dockerfile:build 可以触发插件的执行
       sh "mvn -f ${project_name} clean install dockerfile:build"
    }
}

4.6 上传镜像到Harbor镜像仓库

4.6.1 给镜像打tag

  • Jenkinsfile:
//定义git凭证ID
def git_auth = "bacbbbb1-2df9-470d-adf8-5cb6dc496807"
//git的url地址
def git_url = "git@192.168.209.100:develop_group/jenkinscloud.git"
//定义tag
def tag = "1.0"
// 定义Harbor的URL地址
def harbor_url = "192.168.209.102:85"
// 镜像库项目名称
def harbor_project = "xudaxian-mall"
node {
    stage('拉取代码') {
        checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
    }
    stage('代码审查') {
        //定义当前Jenkins的SonarQubeScanner工具的环境
        def scannerHome = tool 'sonarqube-scanner'
        //引用当前Jenkins的SonarQube环境
        withSonarQubeEnv('sonarqube-8.6.0') {
          sh """
               cd ${project_name}
               ${scannerHome}/bin/sonar-scanner
          """
        }
    }
    //如果有公共子工程
//     stage('编译,安装公共的子工程') {
//        sh "mvn -f jenkinscloud-common clean install"
//     }
    stage('编译,打包微服务工程') {
       // dockerfile:build 可以触发插件的执行
       sh "mvn -f ${project_name} clean install dockerfile:build "
    }

    stage('上传镜像') {
       //定义镜像的名称
       def imageName = "${project_name}:${tag}"
       //给镜像打上标签
       sh "docker tag ${imageName} ${harbor_url}/${harbor_project}/${imageName}"

    }
}

4.6.2 在Jenkins中配置登录Harbor的凭证信息

将Harbor的认证信息配置到Jenkins中.png

将Harbor的认证信息配置到Jenkins中2.png

将Harbor的认证信息配置到Jenkins中3.png

767a60c2-c423-4737-a455-228a7e38ead7

4.6.3 通过片段生成器生成流水线脚本

通过片段生成器生成流水线脚本.png

  • 并将生成的流水线脚本复制的Jenkinsfile中:
//定义git凭证ID
def git_auth = "bacbbbb1-2df9-470d-adf8-5cb6dc496807"
//git的url地址
def git_url = "git@192.168.209.100:develop_group/jenkinscloud.git"
//定义tag
def tag = "1.0"
// 定义Harbor的URL地址
def harbor_url = "192.168.209.102:85"
// 镜像库项目名称
def harbor_project = "xudaxian-mall"
// Harbor的登录凭证id
def harbor_auth = "767a60c2-c423-4737-a455-228a7e38ead7"
node {
    stage('拉取代码') {
        checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
    }
    stage('代码审查') {
        //定义当前Jenkins的SonarQubeScanner工具的环境
        def scannerHome = tool 'sonarqube-scanner'
        //引用当前Jenkins的SonarQube环境
        withSonarQubeEnv('sonarqube-8.6.0') {
          sh """
               cd ${project_name}
               ${scannerHome}/bin/sonar-scanner
          """
        }
    }
    //如果有公共子工程
//     stage('编译,安装公共的子工程') {
//        sh "mvn -f jenkinscloud-common clean install"
//     }
    stage('编译,打包微服务工程') {
       // dockerfile:build 可以触发插件的执行
       sh "mvn -f ${project_name} clean install dockerfile:build "
    }

    stage('上传镜像') {
       //定义镜像的名称
       def imageName = "${project_name}:${tag}"
       //给镜像打上标签
       sh "docker tag ${imageName} ${harbor_url}/${harbor_project}/${imageName}"
       //把镜像推送到Harbor
       withCredentials([usernamePassword(credentialsId: "${harbor_auth}", passwordVariable: 'password', usernameVariable: 'username')]) {
           // 登录到Harbor
           sh "docker login -u ${username} -p ${password} ${harbor_url}"
           //镜像的上传
           sh "docker push ${harbor_url}/${harbor_project}/${imageName}"

           sh "echo '镜像上传到Harbor仓库中成功'"
       }

    }
}

4.6.4 将镜像发布到Harbor中

将镜像发布到Harbor中.png

Harbor仓库中查看已经上传的镜像.png

4.7 拉取镜像和发布应用

4.7.1 前提说明

  • 192.168.18.103已经安装了Docker,并且Docker已经设置了信任Harbor私有仓库。
  • 192.168.18.103的防火墙已经关闭。
  • 安装Jenkins的那台服务器(192.168.18.101)已经安装了 Publish Over SSH插件,以便给生产部署的服务器执行SSH远程调用。

拉取镜像和发布应用前提说明.png

4.7.2 配置远程部署服务器

  • 在192.168.18.101中配置远程部署服务器(192.168.18.103):

配置远程部署服务器.png

因为我将所有服务器的防火墙关闭,但是在实际生产环境下,需要通过ssh公钥和私钥来匹配使用,前面已经生成过公钥和私钥,将公钥发给部署服务器。操作步骤如下:

  • 进入/root/.ssh目录:
  • 将公钥发给部署服务器:
  • 在配置远程部署服务器的Path to key中配置私钥的路径:
cd /root/.ssh
ssh-copy-id 192.168.18.103
/root/.ssh/id_rsa

4.7.3 在远程部署服务器创建部署的脚本

  • 进入/usr/local目录:
cd /usr/local
  • 编写deploy.sh脚本:
vim deploy.sh
#! /bin/sh
#接收外部参数
harbor_url=$1
harbor_project_name=$2
project_name=$3
tag=$4
port=$5

imageName=$harbor_url/$harbor_project_name/$project_name:$tag

echo "$imageName"

#查询容器是否存在,存在则删除
containerId=`docker ps -a | grep -w ${project_name}:${tag}  | awk '{print $1}'`
if [ "$containerId" !=  "" ] ; then
    #停掉容器
    docker stop $containerId

    #删除容器
    docker rm $containerId

    echo "成功删除容器"
fi

#查询镜像是否存在,存在则删除
imageId=`docker images | grep -w $project_name  | awk '{print $3}'`

if [ "$imageId" !=  "" ] ; then

    #删除镜像
    docker rmi -f $imageId

    echo "成功删除镜像"
fi

# 登录Harbor
docker login -u xudaxian -p Xudaxian12345678 $harbor_url

# 下载镜像
docker pull $imageName

# 启动容器
docker run -di -p $port:$port $imageName

echo "容器启动成功"
  • 设置权限:
chmod +x deploy.sh

4.7.4 在Jenkins中设置参数

  • 将端口作为外部的参数,在Jenkins中配置。

将端口作为外部的参数,在Jenkins中配置.png

4.7.5 修改Jenkinsfile文件添加拉取镜像和发布应用的部署

  • Jenkinfile:
//定义git凭证ID
def git_auth = "7d5c4945-2533-41e2-bd47-5dd97eb37f38"
//git的url地址
def git_url = "git@192.168.18.100:develop_group/jenkinscloud.git"
//定义tag
def tag = "1.0"
// 定义Harbor的URL地址
def harbor_url = "192.168.18.102:85"
// 镜像库项目名称
def harbor_project = "xudaxian-mall"
// Harbor的登录凭证id
def harbor_auth = "b6cf3cb5-8a33-457d-93da-65c46f0135b2"
// 定义远程执行命令
def execCommand = "/usr/local/deploy.sh $harbor_url $harbor_project $project_name $tag $port"
node {
    stage('拉取代码') {
        checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
    }
    stage('代码审查') {
        //定义当前Jenkins的SonarQubeScanner工具的环境
        def scannerHome = tool 'sonarqube-scanner'
        //引用当前Jenkins的SonarQube环境
        withSonarQubeEnv('sonarqube-8.6.0') {
          sh """
               cd ${project_name}
               ${scannerHome}/bin/sonar-scanner
          """
        }
    }
    //如果有公共子工程
//     stage('编译,安装公共的子工程') {
//        sh "mvn -f jenkinscloud-common clean install"
//     }
    stage('编译,打包微服务工程') {
       // dockerfile:build 可以触发插件的执行
       sh "mvn -f ${project_name} clean install dockerfile:build "
    }

    stage('上传镜像') {
       //定义镜像的名称
       def imageName = "${project_name}:${tag}"
       //给镜像打上标签
       sh "docker tag ${imageName} ${harbor_url}/${harbor_project}/${imageName}"
       //把镜像推送到Harbor
       withCredentials([usernamePassword(credentialsId: "${harbor_auth}", passwordVariable: 'password', usernameVariable: 'username')]) {
           // 登录到Harbor
           sh "docker login -u ${username} -p ${password} ${harbor_url}"
           //镜像的上传
           sh "docker push ${harbor_url}/${harbor_project}/${imageName}"

           sh "echo '镜像上传到Harbor仓库中成功'"
       }

    }

    //删除本地镜像
    sh "docker rmi -f ${imageName}"
    sh "docker rmi -f ${harbor_url}/${arbor_project}/${imageName}"

    stage('拉取镜像和发布应用') {
        // 远程部署调用进行项目部署
        sshPublisher(publishers: [sshPublisherDesc(configName: '192.168.18.103', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "${execCommand}", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
    }
}

4.8 需要更改各个微服务的application.yml文件的IP地址

  • 略。

4.9 重新启动微服务持续集成流程

  • 为什么?因为先前容器中的IP还是localhost,而不是远程部署服务器的IP地址。