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

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

1.1 概述

Jenkins+Docker+SpringCloud持续集成说明.png

  • 大致流程说明:
  • 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 微服务项目说明

微服务项目说明.png

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

  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
  1. sudo chmod +x /usr/local/bin/docker-compose
  • 查看Docker Compose是否安装成功:
  1. docker-compose version

3.2.3 安装Harbor

  1. wget https://github.com/goharbor/harbor/releases/download/v2.1.3/harbor-offline-installer-v2.1.3.tgz
  • 解压Harbor:
  1. tar -zxvf harbor-offline-installer-v2.1.3.tgz -C /usr/local
  • 修改Harbor的配置:
  1. cd /usr/local/harbor
  1. mv harbor.yml.tmpl harbor.yml
  1. vim harbor.yml
  1. # 修改部分
  2. hostname: 192.168.18.102
  3. http:
  4. port: 85
  5. # 将https注释掉
  6. # https:
  7. # https port for harbor, default is 443
  8. # port: 443
  9. # The path of cert and key files for nginx
  10. # certificate: /your/certificate/path
  11. # private_key: /your/private/key/path
  • 安装Harbor:
  1. ./prepare
  1. ./install.sh
  • 启动、停止、重新启动Harbor:
  1. # 启动
  2. docker-compose up -d
  1. # 停止
  2. docker-compose stop
  1. # 重新启动
  2. docker-compose restart

3.2.4 访问Harbor

3.3 在Harbor中创建用户和项目

3.3.1 创建项目

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

Harbor新建项目.png

3.3.2 创建用户

Harbor创建用户.png

Harbor创建用户2.png

创建用户为:xudaxian/Xudaxian12345678。

3.3.3 给私有项目分配用户

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

给私有项目分配用户.png

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

3.3.4 以新用户登录Harbor

以新用户登录Harbor.png

3.4 把镜像上传到Harbor

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

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

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

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

  • 推送镜像:
  1. 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信任列表中:
  1. vim /etc/docker/daemon.json
  1. {
  2. "exec-opts": ["native.cgroupdriver=systemd"],
  3. "insecure-registries": ["192.168.18.102:85"],
  4. "registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"]
  5. }
  • 重启Docker:
  1. systemctl daemon-reload
  1. systemctl restart docker
  • 重启Harbor:
  1. cd /usr/local/harbor
  1. docker-compose restart
  • 再次执行推送命令,提示权限不足:
  1. docker push 192.168.18.102:85/xudaxian-mall/mysql:5.7

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

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

Docker命令登录Harbor.png

  • 推送镜像:
  1. 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信任列表中
  1. vim /etc/docker/daemon.json
  1. {
  2. "exec-opts": ["native.cgroupdriver=systemd"],
  3. "insecure-registries": ["192.168.18.102:85"],
  4. "registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"]
  5. }
  • 重启Docker:
  1. systemctl daemon-reload
  1. systemctl restart docker

3.5.3 Docker命令登录Harbor

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

3.5.4 拉取镜像

  • 拉取镜像:
  1. 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:
  1. //定义git凭证ID
  2. def git_auth = "bacbbbb1-2df9-470d-adf8-5cb6dc496807"
  3. //git的url地址
  4. def git_url = "git@192.168.209.100:develop_group/jenkinscloud.git"
  5. node {
  6. stage('拉取代码') {
  7. checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
  8. }
  9. }

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

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

4.3.3 修改Jenkins构建脚本

  • Jenkinsfile:
  1. //定义git凭证ID
  2. def git_auth = "bacbbbb1-2df9-470d-adf8-5cb6dc496807"
  3. //git的url地址
  4. def git_url = "git@192.168.209.100:develop_group/jenkinscloud.git"
  5. node {
  6. stage('拉取代码') {
  7. checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
  8. }
  9. stage('代码审查') {
  10. //定义当前Jenkins的SonarQubeScanner工具的环境
  11. def scannerHome = tool 'sonarqube-scanner'
  12. //引用当前Jenkins的SonarQube环境
  13. withSonarQubeEnv('sonarqube-8.6.0') {
  14. sh """
  15. cd ${project_name}
  16. ${scannerHome}/bin/sonar-scanner
  17. """
  18. }
  19. }
  20. //如果有公共子工程
  21. // stage('编译,安装公共的子工程') {
  22. // sh "mvn -f jenkinscloud-common clean install"
  23. // }
  24. }

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

4.4 编译打包微服务工程

  • Jenkinsfile:
  1. //定义git凭证ID
  2. def git_auth = "bacbbbb1-2df9-470d-adf8-5cb6dc496807"
  3. //git的url地址
  4. def git_url = "git@192.168.209.100:develop_group/jenkinscloud.git"
  5. node {
  6. stage('拉取代码') {
  7. checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
  8. }
  9. stage('代码审查') {
  10. //定义当前Jenkins的SonarQubeScanner工具的环境
  11. def scannerHome = tool 'sonarqube-scanner'
  12. //引用当前Jenkins的SonarQube环境
  13. withSonarQubeEnv('sonarqube-8.6.0') {
  14. sh """
  15. cd ${project_name}
  16. ${scannerHome}/bin/sonar-scanner
  17. """
  18. }
  19. }
  20. //如果有公共子工程
  21. // stage('编译,安装公共的子工程') {
  22. // sh "mvn -f jenkinscloud-common clean install"
  23. // }
  24. stage('编译,打包微服务工程') {
  25. sh "mvn -f ${project_name} clean install"
  26. }
  27. }

编译打包微服务工程.png

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

4.5 使用Docker编译、生成镜像

4.5.1 前提说明

  • 利用dockerfile-maven-plugin插件来构建Docker镜像。
  • 因为我用的是JDK11,而JDK9以上就移除了javax.activation.activation的jar包,所以需要在每个微服务工程都加上依赖:
  1. <dependency>
  2. <groupId>javax.xml.bind</groupId>
  3. <artifactId>jaxb-api</artifactId>
  4. <version>2.3.0</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>com.sun.xml.bind</groupId>
  8. <artifactId>jaxb-core</artifactId>
  9. <version>2.3.0</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>com.sun.xml.bind</groupId>
  13. <artifactId>jaxb-impl</artifactId>
  14. <version>2.3.0</version>
  15. </dependency>
  16. <dependency>
  17. <groupId>javax.activation</groupId>
  18. <artifactId>activation</artifactId>
  19. <version>1.1.1</version>
  20. </dependency>

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

  • pom.xml
  1. <build>
  2. <plugins>
  3. <plugin>
  4. <groupId>com.spotify</groupId>
  5. <artifactId>dockerfile-maven-plugin</artifactId>
  6. <version>1.4.13</version>
  7. <configuration>
  8. <repository>${project.artifactId}</repository>
  9. <tag>${project.version}</tag>
  10. <buildArgs>
  11. <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
  12. </buildArgs>
  13. </configuration>
  14. </plugin>
  15. </plugins>
  16. </build>

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

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

4.5.4 修改Jenkinsfile

  • Jenkinsfile:
  1. //定义git凭证ID
  2. def git_auth = "bacbbbb1-2df9-470d-adf8-5cb6dc496807"
  3. //git的url地址
  4. def git_url = "git@192.168.209.100:develop_group/jenkinscloud.git"
  5. node {
  6. stage('拉取代码') {
  7. checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
  8. }
  9. stage('代码审查') {
  10. //定义当前Jenkins的SonarQubeScanner工具的环境
  11. def scannerHome = tool 'sonarqube-scanner'
  12. //引用当前Jenkins的SonarQube环境
  13. withSonarQubeEnv('sonarqube-8.6.0') {
  14. sh """
  15. cd ${project_name}
  16. ${scannerHome}/bin/sonar-scanner
  17. """
  18. }
  19. }
  20. //如果有公共子工程
  21. // stage('编译,安装公共的子工程') {
  22. // sh "mvn -f jenkinscloud-common clean install"
  23. // }
  24. stage('编译,打包微服务工程') {
  25. // 修改部分
  26. // dockerfile:build 可以触发插件的执行
  27. sh "mvn -f ${project_name} clean install dockerfile:build"
  28. }
  29. }

4.6 上传镜像到Harbor镜像仓库

4.6.1 给镜像打tag

  • Jenkinsfile:
  1. //定义git凭证ID
  2. def git_auth = "bacbbbb1-2df9-470d-adf8-5cb6dc496807"
  3. //git的url地址
  4. def git_url = "git@192.168.209.100:develop_group/jenkinscloud.git"
  5. //定义tag
  6. def tag = "1.0"
  7. // 定义Harbor的URL地址
  8. def harbor_url = "192.168.209.102:85"
  9. // 镜像库项目名称
  10. def harbor_project = "xudaxian-mall"
  11. node {
  12. stage('拉取代码') {
  13. checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
  14. }
  15. stage('代码审查') {
  16. //定义当前Jenkins的SonarQubeScanner工具的环境
  17. def scannerHome = tool 'sonarqube-scanner'
  18. //引用当前Jenkins的SonarQube环境
  19. withSonarQubeEnv('sonarqube-8.6.0') {
  20. sh """
  21. cd ${project_name}
  22. ${scannerHome}/bin/sonar-scanner
  23. """
  24. }
  25. }
  26. //如果有公共子工程
  27. // stage('编译,安装公共的子工程') {
  28. // sh "mvn -f jenkinscloud-common clean install"
  29. // }
  30. stage('编译,打包微服务工程') {
  31. // dockerfile:build 可以触发插件的执行
  32. sh "mvn -f ${project_name} clean install dockerfile:build "
  33. }
  34. stage('上传镜像') {
  35. //定义镜像的名称
  36. def imageName = "${project_name}:${tag}"
  37. //给镜像打上标签
  38. sh "docker tag ${imageName} ${harbor_url}/${harbor_project}/${imageName}"
  39. }
  40. }

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中:
  1. //定义git凭证ID
  2. def git_auth = "bacbbbb1-2df9-470d-adf8-5cb6dc496807"
  3. //git的url地址
  4. def git_url = "git@192.168.209.100:develop_group/jenkinscloud.git"
  5. //定义tag
  6. def tag = "1.0"
  7. // 定义Harbor的URL地址
  8. def harbor_url = "192.168.209.102:85"
  9. // 镜像库项目名称
  10. def harbor_project = "xudaxian-mall"
  11. // Harbor的登录凭证id
  12. def harbor_auth = "767a60c2-c423-4737-a455-228a7e38ead7"
  13. node {
  14. stage('拉取代码') {
  15. checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
  16. }
  17. stage('代码审查') {
  18. //定义当前Jenkins的SonarQubeScanner工具的环境
  19. def scannerHome = tool 'sonarqube-scanner'
  20. //引用当前Jenkins的SonarQube环境
  21. withSonarQubeEnv('sonarqube-8.6.0') {
  22. sh """
  23. cd ${project_name}
  24. ${scannerHome}/bin/sonar-scanner
  25. """
  26. }
  27. }
  28. //如果有公共子工程
  29. // stage('编译,安装公共的子工程') {
  30. // sh "mvn -f jenkinscloud-common clean install"
  31. // }
  32. stage('编译,打包微服务工程') {
  33. // dockerfile:build 可以触发插件的执行
  34. sh "mvn -f ${project_name} clean install dockerfile:build "
  35. }
  36. stage('上传镜像') {
  37. //定义镜像的名称
  38. def imageName = "${project_name}:${tag}"
  39. //给镜像打上标签
  40. sh "docker tag ${imageName} ${harbor_url}/${harbor_project}/${imageName}"
  41. //把镜像推送到Harbor
  42. withCredentials([usernamePassword(credentialsId: "${harbor_auth}", passwordVariable: 'password', usernameVariable: 'username')]) {
  43. // 登录到Harbor
  44. sh "docker login -u ${username} -p ${password} ${harbor_url}"
  45. //镜像的上传
  46. sh "docker push ${harbor_url}/${harbor_project}/${imageName}"
  47. sh "echo '镜像上传到Harbor仓库中成功'"
  48. }
  49. }
  50. }

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目录:
  1. cd /root/.ssh
  • 将公钥发给部署服务器:
  1. ssh-copy-id 192.168.18.103
  • 在配置远程部署服务器的Path to key中配置私钥的路径:
  1. /root/.ssh/id_rsa

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

  • 进入/usr/local目录:
  1. cd /usr/local
  • 编写deploy.sh脚本:
  1. vim deploy.sh
  1. #! /bin/sh
  2. #接收外部参数
  3. harbor_url=$1
  4. harbor_project_name=$2
  5. project_name=$3
  6. tag=$4
  7. port=$5
  8. imageName=$harbor_url/$harbor_project_name/$project_name:$tag
  9. echo "$imageName"
  10. #查询容器是否存在,存在则删除
  11. containerId=`docker ps -a | grep -w ${project_name}:${tag} | awk '{print $1}'`
  12. if [ "$containerId" != "" ] ; then
  13. #停掉容器
  14. docker stop $containerId
  15. #删除容器
  16. docker rm $containerId
  17. echo "成功删除容器"
  18. fi
  19. #查询镜像是否存在,存在则删除
  20. imageId=`docker images | grep -w $project_name | awk '{print $3}'`
  21. if [ "$imageId" != "" ] ; then
  22. #删除镜像
  23. docker rmi -f $imageId
  24. echo "成功删除镜像"
  25. fi
  26. # 登录Harbor
  27. docker login -u xudaxian -p Xudaxian12345678 $harbor_url
  28. # 下载镜像
  29. docker pull $imageName
  30. # 启动容器
  31. docker run -di -p $port:$port $imageName
  32. echo "容器启动成功"
  • 设置权限:
  1. chmod +x deploy.sh

4.7.4 在Jenkins中设置参数

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

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

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

  • Jenkinfile:
  1. //定义git凭证ID
  2. def git_auth = "7d5c4945-2533-41e2-bd47-5dd97eb37f38"
  3. //git的url地址
  4. def git_url = "git@192.168.18.100:develop_group/jenkinscloud.git"
  5. //定义tag
  6. def tag = "1.0"
  7. // 定义Harbor的URL地址
  8. def harbor_url = "192.168.18.102:85"
  9. // 镜像库项目名称
  10. def harbor_project = "xudaxian-mall"
  11. // Harbor的登录凭证id
  12. def harbor_auth = "b6cf3cb5-8a33-457d-93da-65c46f0135b2"
  13. // 定义远程执行命令
  14. def execCommand = "/usr/local/deploy.sh $harbor_url $harbor_project $project_name $tag $port"
  15. node {
  16. stage('拉取代码') {
  17. checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
  18. }
  19. stage('代码审查') {
  20. //定义当前Jenkins的SonarQubeScanner工具的环境
  21. def scannerHome = tool 'sonarqube-scanner'
  22. //引用当前Jenkins的SonarQube环境
  23. withSonarQubeEnv('sonarqube-8.6.0') {
  24. sh """
  25. cd ${project_name}
  26. ${scannerHome}/bin/sonar-scanner
  27. """
  28. }
  29. }
  30. //如果有公共子工程
  31. // stage('编译,安装公共的子工程') {
  32. // sh "mvn -f jenkinscloud-common clean install"
  33. // }
  34. stage('编译,打包微服务工程') {
  35. // dockerfile:build 可以触发插件的执行
  36. sh "mvn -f ${project_name} clean install dockerfile:build "
  37. }
  38. stage('上传镜像') {
  39. //定义镜像的名称
  40. def imageName = "${project_name}:${tag}"
  41. //给镜像打上标签
  42. sh "docker tag ${imageName} ${harbor_url}/${harbor_project}/${imageName}"
  43. //把镜像推送到Harbor
  44. withCredentials([usernamePassword(credentialsId: "${harbor_auth}", passwordVariable: 'password', usernameVariable: 'username')]) {
  45. // 登录到Harbor
  46. sh "docker login -u ${username} -p ${password} ${harbor_url}"
  47. //镜像的上传
  48. sh "docker push ${harbor_url}/${harbor_project}/${imageName}"
  49. sh "echo '镜像上传到Harbor仓库中成功'"
  50. }
  51. }
  52. //删除本地镜像
  53. sh "docker rmi -f ${imageName}"
  54. sh "docker rmi -f ${harbor_url}/${arbor_project}/${imageName}"
  55. stage('拉取镜像和发布应用') {
  56. // 远程部署调用进行项目部署
  57. 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)])
  58. }
  59. }

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

  • 略。

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

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