zoukankan      html  css  js  c++  java
  • Jenkins+Docker+SpringCloud微服务持续集成(单机版)

    Jenkins+Docker+SpringCloud微服务持续集成(单机版)

    作者:运维人在路上

    个人博客https://www.cnblogs.com/hujinzhong

    微信公众号:运维人在路上

    Bilibili账号https://space.bilibili.com/409609392

    个人简介:本人是一枚大型电商平台的运维工程师,对开发及运维有一定了解,现分享技术干货,欢迎大家交流!

    一、持续集成流程说明

    1.1、流程图解

    image-20210326150947724

    大致流程说明

    1)开发人员每天把代码提交到Gitlab代码仓库

    2)Jenkins从Gitlab中拉取项目源码,编译并打成jar包,然后构建成Docker镜像,将镜像上传到Harbor私有仓库。

    3)Jenkins发送SSH远程命令,让生产部署服务器到Harbor私有仓库拉取镜像到本地,然后创建容器。

    4)最后,用户可以访问到容器

    1.2、服务列表

    说明:红色代表需要安装,黑色代表已安装

    服务器名称 ip地址 安装的软件
    代码托管服务器 10.0.0.101 Gitlab
    持续集成服务器 10.0.0.102 Jenkins,Maven,Docker
    Docker镜像仓库 10.0.0.101 Docker,Harbor
    生产部署服务器 10.0.0.103 Docker

    二、项目源码概述

    2.1、项目架构

    项目架构:前后端分离

    后端技术栈:SpringBoot+SpringCloud+SpringDataJpa(Spring全家桶)

    微服务项目结构

    image-20210322153051656

    • tensquare_parent:父工程,存放基础配置
    • tensquare_common:通用工程,存放工具类
    • tensquare_eureka_server:SpringCloud的Eureka注册中心
    • tensquare_zuul:SpringCloud的网关服务
    • tensquare_admin_service:基础权限认证中心,负责用户认证(使用JWT认证)
    • tensquare_gathering:一个简单的业务模块,活动微服务相关逻辑

    数据库结构

    image-20210322153219973

    • tensquare_user:用户认证数据库,存放用户账户数据,对应tensquare_admin_service微服务
    • tensquare_gathering:活动微服务数据库。对应tensquare_gathering微服务

    2.2、后台服务本地运行部署测试

    1)逐一启动微服务(eureka--zuul)

    image-20210322153734587

    2)使用postman测试功能是否可用

    首先获取token令牌:

    image-20210322153908976

    携带token测试微服务功能:

    image-20210322154113635

    3)本地jar包部署(以eureka为例)

    导入spring-boot-maven-plugin插件

    <plugin>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>
    

    image-20210322160933559

    打包后在target下产生jar包

    image-20210322160444583

    本地运行微服务的jar包:java -jar **.jar

    image-20210322164638364

    2.3、前端web网站本地部署测试

    前端技术栈:NodeJS+VueJS+ElementUI,使用Visual Studio Code打开源码

    # 修改本地测试连接后台网关地址
    BASE_API: '"http://127.0.0.1:10020"' // 管理员网关
    # 本地运行
    npm install
    npm run dev
    npm run build	# 打包
    
    # 默认密码:admin/123456
    

    image-20210322171105008

    三、环境准备

    3.1、Docker安装及基本使用

    3.1.1、Docker介绍

    Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。

    Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。

    容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。

    image-20210326145402509
    虚拟机 容器
    占用磁盘空间 非常大,GB级 小,甚至KB级
    启动速度 慢,分钟级 快,秒级
    运行形态 运行于Hypervisor上 直接运行在宿主机内核上
    并发性能 一台宿主机上十几个,最多几十个 上百个,甚至数百上千个
    性能 逊于宿主机 接近宿主机本地进程
    资源利用率

    总结:Docker技术就是让我们更加高效轻松地将任何应用在Linux服务器部署和使用

    3.1.2、Docker安装配置

    [root@tomcat ~]# docker_install_pro.sh
    #!/bin/sh
    curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
    wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo
    sed -i 's#download.docker.com#mirrors.tuna.tsinghua.edu.cn/docker-ce#g' /etc/yum.repos.d/docker-ce.repo
    yum install docker-ce lrzsz -y
    docker version
    mkdir -p /etc/docker/ && touch /etc/docker/daemon.json
    cat >/etc/docker/daemon.json <<EOF
    {
      "registry-mirrors": ["https://t09ww3n9.mirror.aliyuncs.com"]
    }
    EOF
    systemctl start docker
    systemctl enable docker
    

    3.1.3、Docker基本命令

    1)镜像命令

    镜像:相当于应用的安装包,在Docker部署的任何应用都需要先构建成为镜像

    docker search 镜像名称 	# 搜索镜像
    docker pull 镜像名称   	# 拉取镜像
    docker images 			#查看本地所有镜像
    docker rmi -f 镜像名称 	#删除镜像
    docker pull openjdk:8-jdk-alpine
    

    2)容器命令

    容器:容器是由镜像创建而来。容器是Docker运行应用的载体,每个应用都分别运行在Docker的每个容器中

    docker run -i 镜像名称:标签 # 运行容器(默认是前台运行)
    docker ps # 查看运行的容器
    docker ps -a 	# 查询所有容器
    docker exec -it 容器ID/容器名称 /bin/bash 	# 进入容器内部
    docker start/stop/restart 容器名称/ID  # 启动/停止/重启容器
    docker rm -f 容器名称/ID # 删除容器
    

    常用参数说明

    -i:运行容器

    -d:后台守方式运行(守护式)

    --name:给容器添加名称

    -p:公开容器端口给当前宿主机

    -v:挂载目录

    3.1.4、Dockerfile

    Dockerfifile的作用:它可以让用户个性化定制Docker镜像。因为工作环境中的需求各式各样,网络上的镜像很难满足实际的需求

    Dockerfile常用命令

    命令 作用
    FROM image_name:tag 基础镜像
    MAINTAINER user_name 声明镜像的作者
    ENV key value 设置环境变量 (可以写多条)
    RUN command 编译镜像时运行的脚本(可以写多条)
    CMD 设置容器的启动命令
    ENTRYPOINT 设置容器的入口程序
    ADD source_dir/file dest_dir/file 将宿主机的文件复制到容器内,如果是一个压缩文件,将会在复制后自动解压
    COPY source_dir/file dest_dir/file 和ADD相似,但是如果有压缩文件并不能解压
    WORKDIR path_dir 设置工作目录
    ARG 设置编译镜像时加入的参数
    VOLUMN 设置容器的挂载卷

    镜像构建:新镜像是从基础镜像一层一层叠加生成的。每安装一个软件,就在现有镜像的基础上增加一层

    image-20210326151057346

    RUN、CMD、ENTRYPOINT的区别

    • RUN:用于指定 docker build 过程中要运行的命令,即是创建 Docker 镜像(image)的步骤
    • CMD:设置容器的启动命令, Dockerfifile 中只能有一条 CMD 命令,如果写了多条则最后一条生效,CMD不支持接收docker run的参数。
    • ENTRYPOINT:入口程序是容器启动时执行的程序, docker run 中最后的命令将作为参数传递给入口程序 ,ENTRYPOINY类似于 CMD 指令,但可以接收docker run的参数

    实例:官方MySQL官方镜像Dockerfile

    # 地址:https://github.com/mysql/mysql-docker
    
    FROM oraclelinux:7-slim
    
    ARG MYSQL_SERVER_PACKAGE=mysql-community-server-minimal-5.7.33
    ARG MYSQL_SHELL_PACKAGE=mysql-shell-8.0.22
    
    # Install server
    RUN yum install -y https://repo.mysql.com/mysql-community-minimal-release-el7.rpm 
          https://repo.mysql.com/mysql-community-release-el7.rpm 
      && yum-config-manager --enable mysql57-server-minimal 
      && yum install -y 
          $MYSQL_SERVER_PACKAGE 
          $MYSQL_SHELL_PACKAGE 
          libpwquality 
      && yum clean all 
      && mkdir /docker-entrypoint-initdb.d
    
    VOLUME /var/lib/mysql
    
    COPY docker-entrypoint.sh /entrypoint.sh
    COPY healthcheck.sh /healthcheck.sh
    ENTRYPOINT ["/entrypoint.sh"]
    HEALTHCHECK CMD /healthcheck.sh
    EXPOSE 3306 33060
    CMD ["mysqld"]
    

    使用Dockerfile制作微服务镜像:Dockerfile制作一个Eureka注册中心的镜像

    # 1、上传Eureka的微服务jar包到Linux服务器
    [root@tomcat eureka]# ll
    -rw-r--r-- 1 root root 44759968 Mar 22 16:41 tensquare_eureka_server-1.0-SNAPSHOT.jar
    
    # 2、编写Dockerfile
    [root@tomcat eureka]# cat Dockerfile 
    FROM openjdk:8-jdk-alpine
    ARG JAR_FILE
    COPY ${JAR_FILE} app.jar
    EXPOSE 10086
    ENTRYPOINT ["java","-jar","/app.jar"]
    
    # 3、构建镜像
    [root@tomcat eureka]# docker build --build-arg JAR_FILE=tensquare_eureka_server-1.0-SNAPSHOT.jar -t eureka:v1 .
    [root@tomcat eureka]# docker images
    REPOSITORY   TAG            IMAGE ID       CREATED          SIZE
    eureka       v1             18faab929e00   24 seconds ago   150MB
    openjdk      8-jdk-alpine   a3562aa0b991   22 months ago    105MB
    
    # 4、创建容器
    [root@tomcat eureka]# docker run -id --name=eureka -p 10086:10086 eureka:v1
    [root@tomcat eureka]# docker ps -a
    CONTAINER ID   IMAGE       COMMAND                CREATED         STATUS         PORTS                      NAMES
    9d6b37aab12f   eureka:v1   "java -jar /app.jar"   3 seconds ago   Up 2 seconds   0.0.0.0:10086->10086/tcp   eureka
    
    # 5、访问容器:http://10.0.0.103:10086/
    

    3.2、Harbor镜像仓库安装及使用

    3.2.1、Harbor简介

    image-20210323095706862

    Harbor(港口,港湾)是一个用于存储和分发Docker镜像的企业级Registry服务器。除了Harbor这个私有镜像仓库之外,还有Docker官方提供的Registry。相对Registry,Harbor具有很多优势:

    1. 提供分层传输机制,优化网络传输 Docker镜像是是分层的,而如果每次传输都使用全量文件(所以用FTP的方式并不适合),显然不经济。必须提供识别分层传输的机制,以层的UUID为标识,确定传输的对象。
    2. 提供WEB界面,优化用户体验 只用镜像的名字来进行上传下载显然很不方便,需要有一个用户界面可以支持登陆、搜索功能,包括区分公有、私有镜像。
    3. 支持水平扩展集群 当有用户对镜像的上传下载操作集中在某服务器,需要对相应的访问压力作分解。
    4. 良好的安全机制 企业中的开发团队有很多不同的职位,对于不同的职位人员,分配不同的权限,具有更好的安全性。

    3.2.2、Harbor安装

    # 1、安装docker(参考之前的步骤)
    
    # 2、安装docker-compose
    [root@harbor ~]# curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
    [root@harbor ~]# chmod +x /usr/local/bin/docker-compose
    [root@harbor ~]# docker-compose -version
    docker-compose version 1.21.2, build a133471
    
    # 3、安装Harbor(下载地址:https://github.com/goharbor/harbor/releases)
    [root@harbor ~]# tar -xf harbor-offline-installer-v1.9.2.tgz -C /opt/
    [root@harbor ~]# vim /opt/harbor/harbor.yml 
    hostname: 10.0.0.101	#修改主机名及端口
    http:
      port: 85
    [root@harbor ~]# cd /opt/harbor/
    [root@harbor harbor]# ./prepare
    [root@harbor harbor]# ./install.sh
    
    # 4、启动harbor
    [root@harbor harbor]# docker-compose up -d #启动
    [root@harbor harbor]# docker-compose stop #停止
    [root@harbor harbor]# docker-compose restart #重新启动
    
    # 5、访问harbor:http://10.0.0.101:85/  (默认账户admin/Harbor12345)
    

    image-20210323101641760

    3.2.3、Harbor创建用户和项目

    1)创建项目

    Harbor的项目分为公开和私有的:

    • 公开项目:所有用户都可以访问,通常存放公共的镜像,默认有一个library公开项目。
    • 私有项目:只有授权用户才可以访问,通常存放项目本身的镜像。

    我们可以为微服务项目创建一个新的项目:

    image-20210323102148261

    image-20210323102220868

    2)创建用户

    image-20210323102413728

    image-20210323102448586

    3)给私有项目分配用户

    进入dianchou项目->成员

    image-20210323102628436

    image-20210323102654386

    image-20210323102731579

    相关角色说明

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

    4)以新用户登录Harbor

    image-20210323103226497

    3.2.4、测试:镜像上传Harbor

    # 1、给镜像打标签
    [root@jenkins ~]# docker tag eureka:v1 10.0.0.101:85/dianchou/eureka:v1
    [root@jenkins ~]# docker images
    REPOSITORY                      TAG            IMAGE ID       CREATED          SIZE
    10.0.0.101:85/dianchou/eureka   v1             18faab929e00   42 minutes ago   150MB
    eureka                          v1             18faab929e00   42 minutes ago   150MB
    openjdk                         8-jdk-alpine   a3562aa0b991   22 months ago    105MB
    
    # 2、推送镜像
    [root@jenkins ~]# docker push 10.0.0.101:85/dianchou/eureka:v1
    The push refers to repository [10.0.0.101:85/dianchou/eureka]
    Get https://10.0.0.101:85/v2/: http: server gave HTTP response to HTTPS client	# 报错(Docker没有把Harbor加入信任列表中)
    
    # 3、把Harbor地址加入到Docker信任列表(json格式,不要缺少逗号)
    [root@jenkins ~]# vim /etc/docker/daemon.json
    {
      "registry-mirrors": ["https://t09ww3n9.mirror.aliyuncs.com"],
      "insecure-registries": ["10.0.0.101:85"]
    }
    [root@jenkins ~]# systemctl restart docker
    
    # 4、登录harbor并推送镜像
    [root@jenkins ~]# docker login -u dianchou -p Dianchou123 10.0.0.101:85
    WARNING! Using --password via the CLI is insecure. Use --password-stdin.
    WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
    Configure a credential helper to remove this warning. See
    https://docs.docker.com/engine/reference/commandline/login/#credentials-store
    Login Succeeded
    [root@jenkins ~]# docker push 10.0.0.101:85/dianchou/eureka:v1
    The push refers to repository [10.0.0.101:85/dianchou/eureka]
    82a5c8c35672: Pushed 
    ceaf9e1ebef5: Pushed 
    9b9b7f3d56a0: Pushed 
    f1b5933fe4b5: Pushed 
    v1: digest: sha256:1f8c45ff25ec12790dc1cc350aa9d862930ae362dde381dd8d16ca6d082bc83e size: 1159
    
    # 5、web界面查看
    

    image-20210323104123108

    3.2.5、测试:从Harbor下载镜像

    需求:从生产服务器测试拉取镜像

    # 1、安装docker(参考之前的步骤)
    
    # 2、修改docker配置
    [root@tomcat ~]# vim /etc/docker/daemon.json
    {
      "registry-mirrors": ["https://t09ww3n9.mirror.aliyuncs.com"],
      "insecure-registries": ["10.0.0.101:85"]
    }
    [root@tomcat ~]# systemctl restart docker
    
    # 3、登录harbor
    [root@tomcat ~]# docker login -u dianchou -p Dianchou123 10.0.0.101:85
    WARNING! Using --password via the CLI is insecure. Use --password-stdin.
    WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
    Configure a credential helper to remove this warning. See
    https://docs.docker.com/engine/reference/commandline/login/#credentials-store
    
    Login Succeeded
    
    # 4、拉取镜像
    [root@tomcat ~]# docker pull 10.0.0.101:85/dianchou/eureka:v1
    v1: Pulling from dianchou/eureka
    e7c96db7181b: Pull complete 
    f910a506b6cb: Pull complete 
    c2274a1a0e27: Pull complete 
    93d0144a4f8b: Pull complete 
    Digest: sha256:1f8c45ff25ec12790dc1cc350aa9d862930ae362dde381dd8d16ca6d082bc83e
    Status: Downloaded newer image for 10.0.0.101:85/dianchou/eureka:v1
    10.0.0.101:85/dianchou/eureka:v1
    [root@tomcat ~]# docker images
    REPOSITORY                      TAG       IMAGE ID       CREATED          SIZE
    10.0.0.101:85/dianchou/eureka   v1        18faab929e00   55 minutes ago   150MB
    

    四、后台微服务部署

    4.1、项目代码上传Gitlab

    image-20210323113225782

    4.2、创建Jenkins Pipeline项目

    1)参数化构建:根据分支拉取代码

    image-20210323114755750

    2)流水线配置

    image-20210323113910619

    4.3、Jenkins拉取项目源码

    1)项目根目录创建Jenkinsfile文件

    //gitlab的凭证
    def git_auth = "cf17ff40-5824-4b2d-bdd5-784560255001"
    //gitlab仓库地址
    def git_url = "git@10.0.0.101:dianchou_group/tensqure_back.git"
    
    node {
        stage('拉取代码') {
            checkout([$class: 'GitSCM', branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
        }
    }
    
    

    2)构建测试拉取代码

    image-20210323115428062

    image-20210323115524892

    4.4、提交SonarQube代码审查

    1)添加Choice Parameter构建参数

    image-20210323140612918

    2)每个项目的根目录下添加sonar-project.properties,注意修改sonar.projectKeysonar.projectName

    # must be unique in a given SonarQube instance
    sonar.projectKey=tensquare_eureka_server
    # this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1.
    sonar.projectName=tensquare_eureka_server
    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=1.8
    sonar.java.target=1.8
    #sonar.java.libraries=**/target/classes/**
    
    # Encoding of the source code. Default is default system encoding
    sonar.sourceEncoding=UTF-8
    

    3)修改Jenkinsfile

    //gitlab的凭证
    def git_auth = "cf17ff40-5824-4b2d-bdd5-784560255001"
    //gitlab仓库地址
    def git_url = "git@10.0.0.101:dianchou_group/tensqure_back.git"
    
    node {
        stage('拉取代码') {
            checkout([$class: 'GitSCM', branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
        }
    
        stage('代码审查') {
            //定义当前Jenkins的SonarQubeScanner工具
            def scannerHome = tool 'sonarqube-scanner'
            //引用当前JenkinsSonarQube环境
            withSonarQubeEnv('sonarqube') {
                 sh """
                         cd ${project_name}
                         ${scannerHome}/bin/sonar-scanner
                 """
            }
        }
    }
    

    4)构建测试

    image-20210323140738612

    image-20210323140808116

    image-20210323141238161

    4.5、使用Dockerfile编译、生成镜像

    1)在每个微服务项目的pom.xml加入dockerfifile-maven-plugin插件(tensquare_common模块无需添加)

        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
                <plugin>
                    <groupId>com.spotify</groupId>
                    <artifactId>dockerfile-maven-plugin</artifactId>
                    <version>1.3.6</version>
                    <configuration>
                        <repository>${project.artifactId}</repository>
                        <buildArgs>
                            <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
                        </buildArgs>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    

    2)在每个微服务项目根目录下建立Dockerfile文件,注意修改端口

    #FROM java:8
    FROM openjdk:8-jdk-alpine
    ARG JAR_FILE
    COPY ${JAR_FILE} app.jar
    EXPOSE 10086
    ENTRYPOINT ["java","-jar","/app.jar"]
    

    3)修改Jenkinsfile构建脚本

    //gitlab的凭证
    def git_auth = "cf17ff40-5824-4b2d-bdd5-784560255001"
    //gitlab仓库地址
    def git_url = "git@10.0.0.101:dianchou_group/tensqure_back.git"
    
    node {
        stage('拉取代码') {
            checkout([$class: 'GitSCM', branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
        }
    
        stage('代码审查') {
            //定义当前Jenkins的SonarQubeScanner工具
            def scannerHome = tool 'sonarqube-scanner'
            //引用当前JenkinsSonarQube环境
            withSonarQubeEnv('sonarqube') {
                 sh """
                         cd ${project_name}
                         ${scannerHome}/bin/sonar-scanner
                 """
            }
        }
    
        stage('编译,安装公共子工程') {
            sh "mvn -f tensquare_common clean install"
        }
    
        stage('编译,打包微服务工程,上传镜像') {
            sh "mvn -f ${project_name} clean package dockerfile:build"
        }
    }
    
    

    问题一:如果出现找不到父工程依赖,需要手动把父工程的依赖上传到仓库中

    image-20210323152636186

    image-20210323144031578

    问题二:找不到插件

    image-20210323152718562

    # 修改maven的配置文件,添加如下配置
    [root@jenkins ~]# vim /opt/maven/conf/settings.xml
      <pluginGroups>
         <pluginGroup>com.spotify</pluginGroup>
      </pluginGroups>
    

    4.6、镜像上传Harbor仓库

    1)Jenkins中生成Harbor凭证

    image-20210323164211630

    2)生成凭证脚本代码

    image-20210323164512881

    3)修改Jenkinfile

    //gitlab的凭证
    def git_auth = "cf17ff40-5824-4b2d-bdd5-784560255001"
    //gitlab仓库地址
    def git_url = "git@10.0.0.101:dianchou_group/tensqure_back.git"
    //镜像的版本号
    def tag = "latest"
    //Harbor的url地址
    def harbor_url = "10.0.0.101:85"
    //镜像库项目名称
    def harbor_project = "dianchou"
    //Harbor的登录凭证ID
    def harbor_auth = "86beb97d-7de6-4dc2-ab10-bc199d9eda97"
    
    node {
        stage('拉取代码') {
            checkout([$class: 'GitSCM', branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
        }
    
        stage('代码审查') {
            //定义当前Jenkins的SonarQubeScanner工具
            def scannerHome = tool 'sonarqube-scanner'
            //引用当前JenkinsSonarQube环境
            withSonarQubeEnv('sonarqube') {
                 sh """
                         cd ${project_name}
                         ${scannerHome}/bin/sonar-scanner
                 """
            }
        }
    
        stage('编译,安装公共子工程') {
            sh "mvn -f tensquare_common clean install"
        }
    
        stage('编译,打包微服务工程,上传镜像') {
            sh "mvn -f ${project_name} clean package dockerfile:build"
            //定义镜像名称
            def imageName = "${project_name}:${tag}"
            //给镜像打标签
            sh "docker tag ${imageName} ${harbor_url}/${harbor_project}/${imageName}"
            //登录harbor并上传镜像
            withCredentials([usernamePassword(credentialsId:  "${harbor_auth}", passwordVariable: 'password', usernameVariable: 'username')]) {
                //登录
                sh "docker login -u ${username} -p ${password} ${harbor_url}"
                //上传镜像
                sh "docker push ${harbor_url}/${harbor_project}/${imageName}"
                sh "echo 上传镜像成功"
            }
            //删除本地镜像
            sh "docker rmi -f ${imageName}"
            sh "docker rmi -f ${harbor_url}/${harbor_project}/${imageName}"
        }
    }
    

    4)构建测试

    image-20210323170436735

    4.7、生产服务器拉取镜像并发布

    image-20210326151227766

    1)安装Publish Over SSH插件

    image-20210323170922318

    2)配置远程部署服务器

    拷贝公钥至远程服务器

    [root@jenkins ~]# ssh-copy-id 10.0.0.103
    

    系统配置->添加远程服务器

    image-20210323172747174

    3)生成远程调用模板代码

    image-20210323173026931

    # 生成的代码片段如下
    sshPublisher(publishers: [sshPublisherDesc(configName: 'master_server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
    

    4)添加一个port参数

    image-20210323173213655

    5)修改jenkinsfile文件

    //gitlab的凭证
    def git_auth = "cf17ff40-5824-4b2d-bdd5-784560255001"
    //gitlab仓库地址
    def git_url = "git@10.0.0.101:dianchou_group/tensqure_back.git"
    //镜像的版本号
    def tag = "latest"
    //Harbor的url地址
    def harbor_url = "10.0.0.101:85"
    //镜像库项目名称
    def harbor_project = "dianchou"
    //Harbor的登录凭证ID
    def harbor_auth = "86beb97d-7de6-4dc2-ab10-bc199d9eda97"
    
    node {
        stage('拉取代码') {
            checkout([$class: 'GitSCM', branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
        }
    
        stage('代码审查') {
            //定义当前Jenkins的SonarQubeScanner工具
            def scannerHome = tool 'sonarqube-scanner'
            //引用当前JenkinsSonarQube环境
            withSonarQubeEnv('sonarqube') {
                 sh """
                         cd ${project_name}
                         ${scannerHome}/bin/sonar-scanner
                 """
            }
        }
    
        stage('编译,安装公共子工程') {
            sh "mvn -f tensquare_common clean install"
        }
    
        stage('编译,打包微服务工程,上传镜像') {
            sh "mvn -f ${project_name} clean package dockerfile:build"
            //定义镜像名称
            def imageName = "${project_name}:${tag}"
            //给镜像打标签
            sh "docker tag ${imageName} ${harbor_url}/${harbor_project}/${imageName}"
            //登录harbor并上传镜像
            withCredentials([usernamePassword(credentialsId:  "${harbor_auth}", passwordVariable: 'password', usernameVariable: 'username')]) {
                //登录
                sh "docker login -u ${username} -p ${password} ${harbor_url}"
                //上传镜像
                sh "docker push ${harbor_url}/${harbor_project}/${imageName}"
                sh "echo 上传镜像成功"
            }
            //删除本地镜像
            sh "docker rmi -f ${imageName}"
            sh "docker rmi -f ${harbor_url}/${harbor_project}/${imageName}"
        }
    
        stage('部署应用') {
            sshPublisher(publishers: [sshPublisherDesc(configName: 'master_server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "/opt/jenkins_shell/deploy.sh $harbor_url $harbor_project $project_name $tag $port", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
        }
    }
    
    

    6)部署服务器上编写deploy.sh脚本

    [root@tomcat ~]# mkdir /opt/jenkins_shell
    [root@tomcat ~]# cd /opt/jenkins_shell
    [root@tomcat jenkins_shell]# cat 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 eric -p Eric123456 $harbor_url
    
    # 下载镜像
    docker pull $imageName
    
    # 启动容器
    docker run -di -p $port:$port $imageName
    
    echo "容器启动成功"
    [root@tomcat jenkins_shell]# chmod +x deploy.sh
    

    7)部署eureka测试

    image-20210323173922194

    8)导入数据库脚本文件并修改数据库连接信息并推送至gitlab

    image-20210323174625831

    mysql> show databases;
    +---------------------+
    | Database            |
    +---------------------+
    | information_schema  |
    | mysql               |
    | performance_schema  |
    | sonar               |
    | sys                 |
    | tensquare_gathering |
    | tensquare_user      |
    +---------------------+
    7 rows in set (0.00 sec)
    

    修改服务配置:

    image-20210323175105388

    9)其他服务打包测试

    image-20210323175747285

    10)postman测试

    获取token

    image-20210323175932037

    image-20210323180050961

    五、前端web部署

    5.1、部署流程图解

    image-20210326151403639

    5.2、部署步骤

    5.2.1、上传项目源码至gitlab

    git init
    git add *
    git commit -m "这是上传第一次项目"
    git remote add origin git@10.0.0.101:dianchou_group/tensquare_font.git
    git push -u origin master
    

    image-20210323183358867

    5.2.2、安装nginx并配置

    [root@tomcat ~]# rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
    [root@tomcat ~]# yum install -y nginx
    [root@tomcat ~]# systemctl start nginx.service
    [root@tomcat ~]# systemctl enable nginx.service
    
    # 配置nginx
    [root@tomcat ~]# cd /etc/nginx/conf.d/
    [root@tomcat conf.d]# vim tensquare_font.conf
    server {
        listen       9090;
        server_name  _;
    
        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
        }
    
    }
    [root@tomcat conf.d]# nginx -t
    [root@tomcat conf.d]# nginx -s reload
    

    image-20210323181013863

    5.2.3、安装NodeJs插件

    image-20210323181128264

    5.2.4、Jenkins配置NodeJs环境

    Manage Jenkins->Global Tool Confifiguration

    image-20210323191548305

    5.2.5、创建流水线项目并配置

    image-20210323191750931

    image-20210323191910510

    5.2.6、编写Jenkinsfile

    //gitlab的凭证 
    def git_auth = "cf17ff40-5824-4b2d-bdd5-784560255001" 
    def git_url = "git@10.0.0.101:dianchou_group/tensquare_font.git"
    
    node { 
        stage('拉取代码') {
             checkout([$class: 'GitSCM', branches: [[name: '*/${branch}']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]]) 
        }
        stage('打包,部署网站') { 
            //使用NodeJS的npm进行打包 
            nodejs('NodeJs12'){ 
                sh '''
                	npm install 
                	npm run build 
                '''
            }
            //=====以下为远程调用进行项目部署======== 
            sshPublisher(publishers: [sshPublisherDesc(configName: 'master_server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '/usr/share/nginx/html', remoteDirectorySDF: false, removePrefix: 'dist', sourceFiles: 'dist/**')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)]) 
        } 
    }
    

    5.2.7、修改前端连接后台网关地址

    image-20210323193437627

    构建完成后,访问:http://10.0.0.103:9090/ 进行测试。

    作者:Lawrence

    -------------------------------------------

    个性签名:独学而无友,则孤陋而寡闻。做一个灵魂有趣的人!

    扫描上面二维码关注我
    如果你真心觉得文章写得不错,而且对你有所帮助,那就不妨帮忙“推荐"一下,您的“推荐”和”打赏“将是我最大的写作动力!
    本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接.
  • 相关阅读:
    如何改变常用编辑器(eclipse)的字号大小
    IOConsole Updater error
    RNAfold的使用方法
    单因素方差分析(oneway ANOVA)
    Perl内部保留变量(系统变量)
    Perl 中的正则表达式
    Perl Eclipse 格式化代码
    卸载Oracle 9i
    Ubuntu的菜鸟常用的基础命令
    linux as4u2 下安装openssh
  • 原文地址:https://www.cnblogs.com/hujinzhong/p/14571041.html
Copyright © 2011-2022 走看看