Jenkins+Docker+SpringCloud微服务持续集成

Jenkins+Docker+SpringCloud微服务持续集成

  • Jenkins+Docker+SpringCloud持续集成流程说明
    • SpringCloud微服务源码概述
      • 本地运行微服务
      • 本地部署微服务
    • Docker安装和Dockerfile制作微服务镜像
    • Harbor镜像仓库安装及使用
      • 在Harbor创建用户和项目
      • 上传镜像到Harbor
      • 从Harbor下载镜像
  • 微服务持续集成
    • 项目代码上传到Gitlab
    • 从Gitlab拉取项目源码
    • 提交到SonarQube代码审查
    • 微服务打包构建
    • 使用Dockerfile编译生成镜像
    • 上传到Harbor镜像仓库
    • 拉取镜像和发布应用
    • 配置远程部署服务器
      • 编写远程部署脚本
      • 编写Jenkins流水线脚本
    • 部署和测试所有微服务
    • 部署前端静态web网站

Jenkins+Docker+SpringCloud持续集成流程说明

在这里插入图片描述

  1. 开发人员每天把代码提交到Gitlab代码仓库
  2. Jenkins从Gitlab中拉取项目源码,编译并打成Jar包,然后构建成Docker镜像,将镜像上传到Harbor私有仓库
  3. Jenkins发送SSH远程命令,让生产部署服务器到Harbor私有仓库拉取镜像到本地,然后创建容器
  4. 最后,用户可以访问到容器

服务器列表

服务器名称IP地址安装软件硬件配置系统
代码托管服务器192.168.100.240Gitlab-12.9.92核4GCentOS Linux release 7.5.1804
持续集成服务器192.168.100.241Jenkins 2.401.2,JDK 11,JDK 1.8,Maven 3.8.8,Git 1.8.3.1,Docker 20.10.24-ce2核4GCentOS Linux release 7.5.1804
代码审查服务器192.168.100.242mysql 5.7.43,sonarqube 6.7.71核2GCentOS Linux release 7.5.1804
Harbor仓库服务器192.168.100.251Docker 20.10.24-ce,Harbor 1.9.21核2GCentOS Linux release 7.5.1804
生产部署服务器192.168.100.252Docker 20.10.24-ce1核2GCentOS Linux release 7.5.1804

SpringCloud微服务源码概述

项目架构:前后端分离
后端技术栈:SpringBoot+SpringCloud+SpringDataJpa(Spring全家桶)
微服务项目结构:
在这里插入图片描述

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

数据库结构:

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

微服务配置分析:

  1. tensquare_eureka
  2. tensquare_zuul
  3. tensquare_admin_service
  4. tensquare_gathering

本地运行微服务

本地运行微服务,按顺序逐一启动

运行eureka服务器
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
通过浏览器进入localhost:10086
在这里插入图片描述
开启zuul网关
在这里插入图片描述
在这里插入图片描述
开启权限中心
在这里插入图片描述
在这里插入图片描述
开启微服务
在这里插入图片描述
在这里插入图片描述
刷新Eureka页面业务都成功部署
在这里插入图片描述

本地部署微服务

SpringBoot微服务项目打包,必须导入该插件
在pom.xml里添加
在这里插入图片描述

# 在Pom.xml添加<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>

在这里插入图片描述
项目打包
在这里插入图片描述
在这里插入图片描述
打包后在target下产生jar包
在这里插入图片描述
本地运行微服务的jar包

java -jar xxx.jar

查看效果
在这里插入图片描述
在这里插入图片描述

Docker安装和Dockerfile制作微服务镜像

Docker安装

# 卸载旧版本
sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine
# 删除docker的所有镜像和容器
rm -rf /var/lib/docker# 安装基本的依赖包
sudo yum install yum-utils device-mapper-persistent-data lvm2 -y# 设置镜像仓库 Docker yum源
sudo yum-config-manager \--add-repo \http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo# 更新yum软件包索引
sudo yum makecache fast# 列出需要安装的版本列表
yum list docker-ce --showduplicates | sort -r# 安装docker-ce-20.10
yum install docker-ce-20.10.* docker-ce-cli-20.10.* containerd -ymkdir /etc/docker -p
cat > /etc/docker/daemon.json <<EOF
{"registry-mirrors": ["https://k68iw3ol.mirror.aliyuncs.com"]
}
EOF# 开启内核转发,后续报错排查后回来整理的笔记,重要!!!
vim /etc/sysctl.conf
net.ipv4.ip_forward = 1# 重装使配置生效
sysctl -p /etc/sysctl.confsystemctl daemon-reload && systemctl enable --now docker

部分问题总结

安装docker后无法启动的问题排查
之前所有的安装设置daemon文件为daemon.json格式,但在今天设置后发生报错,并且为之后docker添加harbor地址信任后重启docker埋下伏笔,一直找不到原因,无数次修改json文件,问题的最终在于,参考文章:CentOS7 启动docker.service失败,但又无法连接harbor私有仓库。

cat > /etc/docker/daemon.json <<EOF
{"registry-mirrors": ["https://k68iw3ol.mirror.aliyuncs.com","https://docker.mirrors.ustc.edu.cn","http://hub-mirror.c.163.com"],"exec-opts":["native.cgroupdriver=systemd"]
}
EOF

在这里插入图片描述
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设置容器的挂载卷

利用Dockerfile制作一个Eureka注册中心的镜像

# 将eureka的jar包上传至服务器
mkdir /root/eureka
mv tensquare_eureka_server-1.0-SNAPSHOT.jar /root/eureka/cd /root/eureka/
vim DockerfileFROM openjdk:8-jdk-alpine
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
EXPOSE 10086
ENTRYPOINT ["java","-jar","/app.jar"]docker build --build-arg JAR_FILE=tensquare_eureka_server-1.0-SNAPSHOT.jar -t eureka:v1 .# 查看镜像是否创建成功
[root@jenkins eureka]# docker image ls
REPOSITORY   TAG            IMAGE ID       CREATED         SIZE
eureka       v1             0147238f31a1   5 seconds ago   150MB
openjdk      8-jdk-alpine   a3562aa0b991   4 years ago     105MB# 创建容器验证镜像是否成功
docker run -id --name=eureka -p 10086:10086 eureka:v1# 查看日志
docker logs -f 容器id

构建镜像
在这里插入图片描述
浏览器访问
在这里插入图片描述

Harbor镜像仓库安装及使用

Harbor简介

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

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

Harbor安装

Harbor需要安装在192.168.100.251
参考文章:Harbor prepare脚本分析

# 安装docker
# 参考之前的安装过程# 安装docker-compose
sudo curl -L "https://kgithub.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-composechmod +x /usr/local/bin/docker-compose
docker-compose version# 安装harbor
wget https://ghproxy.com/https://github.com/goharbor/harbor/releases/download/v1.9.2/harbor-offline-installer-v1.9.2.tgzmkdir /opt/harbor
tar xf harbor-offline-installer-v1.9.2.tgz -C /opt# 修改Harbor的配置
vim harbor.yml5 hostname: 192.168.100.251
10   port: 85
27 harbor_admin_password: Harbor12345  # 也可更改harbor默认密码# 产生配置脚本
./prepare
# 安装Harbor
./install.sh# 启动Harbor
docker-compose up -d    # 启动
docker-compose stop     # 停止
docker-compose restart  # 重新启动# 完成安装后,通过192.168.100.251:85进行浏览器访问

在这里插入图片描述
配置Harbor开机随系统启动,服务器重启后默认Harbor无法正常启动,可以使用systemd管理Harbor启停
参考文章:harbor安装并配置https

# 先停止已经启动的harbor
docker-compose -f docker-compose.yml downcat > /usr/lib/systemd/system/harbor.service << 'EOF'
[Unit]
Description=Harbor
After=docker.service systemd-networkd.service systemd-resolved.service
Requires=docker.service
Documentation=https://github.com/goharbor/harbor[Service]
Type=simple
Restart=on-failure
RestartSec=5
Environment=Harbor_Path=/opt/harbor
ExecStart=/usr/local/bin/docker-compose -f ${Harbor_Path}/docker-compose.yml up
ExecStop=/usr/local/bin/docker-compose -f ${Harbor_Path}/docker-compose.yml down[Install]
WantedBy=multi-user.target
EOFsystemctl daemon-reload && systemctl enable harbor --now

在这里插入图片描述

在Harbor创建用户和项目

创建项目

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

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

我们可以为微服务项目创建一个新的项目:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
创建用户
在这里插入图片描述
在这里插入图片描述
给私有项目分配用户
进入tensquare项目->成员
在这里插入图片描述
在这里插入图片描述

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

上传镜像到Harbor

# 把Harbor地址加入到Docker信任列表
vim /etc/docker/daemon.json
{"registry-mirrors": ["https://k68iw3ol.mirror.aliyuncs.com"],"insecure-registries": ["192.168.100.251:85"]
}systemctl daemon-reload && systemctl restart docker# 登录Harbor
docker login -u haibo -p LIUhaibo123 192.168.100.251:85# 给镜像打上标签
[root@jenkins eureka]# docker images
REPOSITORY   TAG            IMAGE ID       CREATED          SIZE
eureka       v1             0147238f31a1   36 minutes ago   150MB
openjdk      8-jdk-alpine   a3562aa0b991   4 years ago      105MBdocker tag eureka:v1 192.168.100.251:85/tensquare/eureka:v1[root@jenkins eureka]# docker images
REPOSITORY                            TAG            IMAGE ID       CREATED          SIZE
192.168.100.251:85/tensquare/eureka   v1             0147238f31a1   37 minutes ago   150MB
eureka                                v1             0147238f31a1   37 minutes ago   150MB
openjdk                               8-jdk-alpine   a3562aa0b991   4 years ago      105MB# 推送镜像
docker push 192.168.100.251:85/tensquare/eureka:v1

此时Harbor仓库有了上传的镜像
在这里插入图片描述

从Harbor下载镜像

需求:在192.168.100.252服务器(生产部署服务器)完成从192.168.100.251(Harbor镜像仓库)下载镜像

# 安装Docker,并启动Docker(已完成)# 修改Docker配置添加对Harbor镜像仓库的信任
vim /etc/docker/daemon.json
{"registry-mirrors": ["https://k68iw3ol.mirror.aliyuncs.com"],"insecure-registries": ["192.168.100.251:85"]
}systemctl daemon-reload && systemctl restart docker# 先登录,再从Harbor下载镜像
docker login -u haibo -p LIUhaibo123 192.168.100.251:85
docker pull 192.168.100.251:85/tensquare/eureka:v1docker images

在这里插入图片描述

微服务持续集成

项目代码上传到Gitlab

参考之前的步骤,上传后台微服务和前端web网站代码。

上传后端代码

创建tensquare项目组
在这里插入图片描述
将张三加入项目组,并赋予owner权限
在这里插入图片描述
创建项目
在这里插入图片描述
在这里插入图片描述
此时tensquare组里就有新建的两个项目
在这里插入图片描述
上传代码,通过IDEA操作

首先上传后端微服务代码
启用版本控制集成
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
新建一个仓库地址
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
提交代码到仓库
在这里插入图片描述
在这里插入图片描述
项目成功提交
在这里插入图片描述
上传前端代码

通过Tortoisegit上传
Git小乌龟的安装及使用

在代码目录下右键创建本地仓库
在这里插入图片描述
在这里插入图片描述
提交代码到本地仓库,右键提交–>master
在这里插入图片描述
在这里插入图片描述
管理远程地址
在这里插入图片描述
在这里插入图片描述
使用用户zhangsan执行代码推送
在这里插入图片描述
在这里插入图片描述
前往Gitlab代码仓库查看
在这里插入图片描述
至此,所有代码上传完毕!

从Gitlab拉取项目源码

Jenkins创建后端流水线项目
在这里插入图片描述
添加参数化构建
在这里插入图片描述
添加字符参数
在这里插入图片描述
在这里插入图片描述
配置从版本控制里抓取pipeline脚本
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
使用流水线语法生成流水线脚本
在这里插入图片描述
在这里插入图片描述

// 定义变量以及引用变量,这样维护性好一点
// 引用凭证ID最好使用双引号 ""// git凭证ID
def git_auth = "a4d0066f-6c58-4ab0-b714-6a24b3f5bc90"
// git的URL地址
def git_url = "git@192.168.100.240:tensquare_group/tensquare_back.git"node {stage('拉取代码') {checkout scmGit(branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]])}
}

上传Jenkinsfile文件至仓库,以便Jenkins项目能够获取脚本文件执行项目构建
在这里插入图片描述
在这里插入图片描述
进入代码仓库查看
在这里插入图片描述
开始构建项目,默认使用master分支
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

提交到SonarQube代码审查

进入tensquare_back项目,添加两个参数
在参数化构建过程添加(Choice Parameter)
在这里插入图片描述
添加需要选择审查的项目名称
在这里插入图片描述
点击构建查看效果
在这里插入图片描述
项目的根目录下添加sonar-project.properties
首先在eureka_server根目录创建

# 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

然后再相应的目录里添加不同的sonar-project.properties,注意:修改sonar.projectKeysonar.projectName
修改Jenkinsfile

// git凭证ID
def git_auth = "a4d0066f-6c58-4ab0-b714-6a24b3f5bc90"
// git的URL地址
def git_url = "git@192.168.100.240:tensquare_group/tensquare_back.git"node {stage('拉取代码') {checkout scmGit(branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]])}stage('代码审查') {// 定义当前Jenkins的SonarQubeScanner工具的环境,位于全局工具配置的SonarQube Scanner 的name定义为'sonar-scanner'def scannerHome = tool 'sonar-scanner'// 引用当前JenkinsSonarQube的环境,系统配置的SonarQube servers定义的name以及代码审查服务器位置withSonarQubeEnv('sonarqube') {sh """cd ${project_name}${scannerHome}/bin/sonar-scanner"""}}
}

由于修改了很多文件,统一提交至仓库
在这里插入图片描述
构建项目并测试代码审查能否完成
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
sonarqube后台查看审查结果
在这里插入图片描述
将其他三个项目也做代码审查
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

微服务打包构建

编译构建之前需要对一个公共子工程编译安装

//Jenkinsfile文件添加步骤// git凭证ID
def git_auth = "a4d0066f-6c58-4ab0-b714-6a24b3f5bc90"
// git的URL地址
def git_url = "git@192.168.100.240:tensquare_group/tensquare_back.git"node {stage('拉取代码') {checkout scmGit(branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]])}stage('代码审查') {// 定义当前Jenkins的SonarQubeScanner工具的环境,位于全局工具配置的SonarQube Scanner 的name定义为'sonar-scanner'def scannerHome = tool 'sonar-scanner'// 引用当前JenkinsSonarQube的环境,系统配置的SonarQube servers定义的name以及代码审查服务器位置withSonarQubeEnv('sonarqube') {sh """cd ${project_name}${scannerHome}/bin/sonar-scanner"""}}stage('编译安装公共子工程') {sh "mvn -f tensquare_common clean install"}
}

Jenkinsfile文件上传至代码仓库,再尝试构建
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
构建失败
在这里插入图片描述
如果编译构建失败,进入IDEA
tensquare_parent父工程里面的spring-boot-maven插件移到需要项目打包的项目里去

tensquare_common子工程不需要这个插件
只需要将插件加入tensquare_eureka_servertensquare_admin_servicetensquare_gatheringtensquare_zuul

    <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build><!-- 在project里添加 -->
</project>

调整好之后,上传至Gitlab代码服务器
再次尝试对公共子工程进行打包,此时可以看到公共子工程安装到了本地maven仓库
在这里插入图片描述
在这里插入图片描述
继续编写Jenkinsfile,需要对其他微服务进行打包

// git凭证ID
def git_auth = "a4d0066f-6c58-4ab0-b714-6a24b3f5bc90"
// git的URL地址
def git_url = "git@192.168.100.240:tensquare_group/tensquare_back.git"node {stage('拉取代码') {checkout scmGit(branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]])}stage('代码审查') {// 定义当前Jenkins的SonarQubeScanner工具的环境,位于全局工具配置的SonarQube Scanner 的name定义为'sonar-scanner'def scannerHome = tool 'sonar-scanner'// 引用当前JenkinsSonarQube的环境,系统配置的SonarQube servers定义的name以及代码审查服务器位置withSonarQubeEnv('sonarqube') {sh """cd ${project_name}${scannerHome}/bin/sonar-scanner"""}}stage('编译安装公共子工程') {sh "mvn -f tensquare_common clean install"}stage('编译打包微服务工程') {// 项目参数传入的project_name 修改为变量sh "mvn -f ${project_name} clean package"}
}

首先对eureka服务器进行打包
在这里插入图片描述
在这里插入图片描述
来到Jenkins工作目录下查看一下
tensquare_eureka_server进行了打包并且target下有jar包
在这里插入图片描述
将其它三个微服务以同样方式打包

但打包tensquare_zuul报错
在这里插入图片描述
网关依赖父工程,但仓库里的父工程没有
因此需要按照父工程的目录结构将父工程pom.xml文件上传到Jenkins服务器的maven仓库,对应的maven仓库里去以便构建时网关服务找到父工程
那么这个动作需要手动完成

[root@jenkins ~]# cd repo/com/tensquare/
[root@jenkins tensquare]# ls
tensquare_common  tensquare_parentrz

在这里插入图片描述
再次进行构建
在这里插入图片描述
在这里插入图片描述
将剩下两个微服务打包
在这里插入图片描述

使用Dockerfile编译生成镜像

利用dockerfile-maven-plugin插件构建Docker镜像
在每个微服务项目的pom.xml加入dockerfile-maven-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>

在这里插入图片描述
在每个微服务项目根目录下建立Dockerfile文件
注意:每个项目公开的端口不一样
在这里插入图片描述

# 构建eureka服务器的dockerfile
FROM openjdk:8-jdk-alpine
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
EXPOSE 10086
ENTRYPOINT ["java","-jar","/app.jar"]

修改Jenkins流水线脚本,添加dockerfile:build触发插件执行

// git凭证ID
def git_auth = "a4d0066f-6c58-4ab0-b714-6a24b3f5bc90"
// git的URL地址
def git_url = "git@192.168.100.240:tensquare_group/tensquare_back.git"node {stage('拉取代码') {checkout scmGit(branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]])}stage('代码审查') {// 定义当前Jenkins的SonarQubeScanner工具的环境,位于全局工具配置的SonarQube Scanner 的name定义为'sonar-scanner'def scannerHome = tool 'sonar-scanner'// 引用当前JenkinsSonarQube的环境,系统配置的SonarQube servers定义的name以及代码审查服务器位置withSonarQubeEnv('sonarqube') {sh """cd ${project_name}${scannerHome}/bin/sonar-scanner"""}}stage('编译安装公共子工程') {sh "mvn -f tensquare_common clean install"}stage('编译打包微服务工程') {// 项目参数传入的project_name 修改为变量sh "mvn -f ${project_name} clean package dockerfile:build"}
}

commit代码,然后对eureka_server进行构建
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
查看本地镜像,创建成功!
在这里插入图片描述
其他的服务也是如此,依然需要插件和dockerfile

# 编写dockerfile,注意端口号的区分,实际没多大区别# 构建tensquare_zuul所需的dockerfile
FROM openjdk:8-jdk-alpine
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
EXPOSE 10020
ENTRYPOINT ["java","-jar","/app.jar"]# 构建tensquare_admin_service所需的dockerfile
FROM openjdk:8-jdk-alpine
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
EXPOSE 9001
ENTRYPOINT ["java","-jar","/app.jar"]# 构建tensquare_gathering所需的dockerfile
FROM openjdk:8-jdk-alpine
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
EXPOSE 9002
ENTRYPOINT ["java","-jar","/app.jar"]

上传代码后进行构建
在这里插入图片描述
在这里插入图片描述

上传到Harbor镜像仓库

修改Jenkinsfile构建脚本

添加对镜像打tag配置

// git凭证ID
def git_auth = "a4d0066f-6c58-4ab0-b714-6a24b3f5bc90"
// git的URL地址
def git_url = "git@192.168.100.240:tensquare_group/tensquare_back.git"
// 镜像的版本号
def tag = "latest"
// Harbor的url地址
def harbor_url = "192.168.100.251:85"
// 镜像库项目名称
def harbor_project = "tensquare"node {stage('拉取代码') {checkout scmGit(branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]])}stage('代码审查') {// 定义当前Jenkins的SonarQubeScanner工具的环境,位于全局工具配置的SonarQube Scanner 的name定义为'sonar-scanner'def scannerHome = tool 'sonar-scanner'// 引用当前JenkinsSonarQube的环境,系统配置的SonarQube servers定义的name以及代码审查服务器位置withSonarQubeEnv('sonarqube') {sh """cd ${project_name}${scannerHome}/bin/sonar-scanner"""}}stage('编译安装公共子工程') {sh "mvn -f tensquare_common clean install"}stage('编译打包微服务工程,上传镜像') {// 项目参数传入的project_name 修改为变量sh "mvn -f ${project_name} clean package dockerfile:build"// 定义镜像名称def imageName = "${project_name}:${tag}"// 对镜像打标签sh "docker tag ${imageName} ${harbor_url}/${harbor_project}/${imageName}"}
}

在这里插入图片描述
在这里插入图片描述
添加Harbor用户凭证
在这里插入图片描述
创建完成后再次进入凭证查看
在这里插入图片描述
将生成的id复制并保存
在这里插入图片描述

5785fbf3-a0f0-4234-8961-c866ca1e7046

进入流水线片段生成器
在这里插入图片描述
在这里插入图片描述
编写Jenkins流水线脚本,添加推送镜像至harbor仓库的配置

// git凭证ID
def git_auth = "a4d0066f-6c58-4ab0-b714-6a24b3f5bc90"
// git的URL地址
def git_url = "git@192.168.100.240:tensquare_group/tensquare_back.git"
// 镜像的版本号
def tag = "latest"
// Harbor的url地址
def harbor_url = "192.168.100.251:85"
// 镜像库项目名称
def harbor_project = "tensquare"
// Harbor的登录凭证ID
def harbor_auth = "5785fbf3-a0f0-4234-8961-c866ca1e7046"node {stage('拉取代码') {checkout scmGit(branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]])}stage('代码审查') {// 定义当前Jenkins的SonarQubeScanner工具的环境,位于全局工具配置的SonarQube Scanner 的name定义为'sonar-scanner'def scannerHome = tool 'sonar-scanner'// 引用当前JenkinsSonarQube的环境,系统配置的SonarQube servers定义的name以及代码审查服务器位置withSonarQubeEnv('sonarqube') {sh """cd ${project_name}${scannerHome}/bin/sonar-scanner"""}}stage('编译安装公共子工程') {sh "mvn -f tensquare_common clean install"}stage('编译打包微服务工程,上传镜像') {// 项目参数传入的project_name 修改为变量sh "mvn -f ${project_name} clean package dockerfile:build"// 定义镜像名称def imageName = "${project_name}:${tag}"// 对镜像打标签sh "docker tag ${imageName} ${harbor_url}/${harbor_project}/${imageName}"// 把镜像推送到Harbor,项目为私有级别,登录时涉及一个问题,登录harbor需要输入账号和密码,Jenkinsfile需要配置项目目录下,会暴露给所有开发人员,为了安全使用凭证方式withCredentials([usernamePassword(credentialsId: "${harbor_auth}", passwordVariable: 'password', usernameVariable: 'username')]) {// 登录到Harbor,引用如上定义的username和password,就是用户haibo的信息sh "docker login -u ${username} -p ${password} ${harbor_url}"// 镜像上传sh "docker push ${harbor_url}/${harbor_project}/${imageName}"sh "echo 镜像上传成功"}}
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

拉取镜像和发布应用

安装Publish Over SSH插件

安装以下插件,可以实现远程发送Shell命令
在这里插入图片描述
在这里插入图片描述

配置远程部署服务器

# 将Jenkins服务器的公钥拷贝到远程pro生产部署服务器 
ssh-copy-id 192.168.100.252

在这里插入图片描述
在Jenkins进入系统配置,找到Publish over SSH
在这里插入图片描述
Path to key文件指向持续集成服务器的私钥文件,写绝对路径
在这里插入图片描述
点击新增
新增Hostname设置远程生产环境部署项目的主机IP地址
在这里插入图片描述
在这里插入图片描述
修改Jenkinsfile构建脚本

生成远程调用模板代码
新版Jenkins需要安装完插件后重启生效
在这里插入图片描述
在这里插入图片描述
其他置空,生成流水线脚本,需要注意的是Exec command,这个是远程执行的命令
在这里插入图片描述

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)])

添加端口参数,作为外部可变参数进行设置

参数化构建过程–>字符参数
在这里插入图片描述
在这里插入图片描述

编写远程部署脚本

# 位于pro生产环境服务器上操作
mkdir /opt/jenkins_shell
vim /opt/jenkins_shell/deploy.sh#!/bin/sh
# 接收外部参数
harbor_url=$1
harbor_project_name=$2
project_name=$3
tag=$4
port=$5imageName=$harbor_url/$harbor_project_name/$project_name:$tagecho "$imageName"# 查询容器是否存在,存在则删除
containerId=`docker ps -a | grep -w ${project_name}:${tag}  | awk '{print $1}'`
if [ "$containerId" !=  "" ] ; then# 停掉容器docker stop $containerId# 删除容器docker rm $containerIdecho "成功删除容器"
fi# 查询镜像是否存在,存在则删除
imageId=`docker images | grep -w $project_name  | awk '{print $3}'`if [ "$imageId" !=  "" ] ; then# 删除镜像docker rmi -f $imageIdecho "成功删除镜像"
fi# 登录Harbor
docker login -u haibo -p LIUhaibo123 $harbor_url# 下载镜像
docker pull $imageName# 启动容器
docker run -di -p $port:$port $imageNameecho "容器启动成功"# 添加执行权限
chmod +x /opt/jenkins_shell/deploy.sh

编写Jenkins流水线脚本

添加远程部署配置

// git凭证ID
def git_auth = "a4d0066f-6c58-4ab0-b714-6a24b3f5bc90"
// git的URL地址
def git_url = "git@192.168.100.240:tensquare_group/tensquare_back.git"
// 镜像的版本号
def tag = "latest"
// Harbor的url地址
def harbor_url = "192.168.100.251:85"
// 镜像库项目名称
def harbor_project = "tensquare"
// Harbor的登录凭证ID
def harbor_auth = "5785fbf3-a0f0-4234-8961-c866ca1e7046"node {stage('拉取代码') {checkout scmGit(branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]])}stage('代码审查') {// 定义当前Jenkins的SonarQubeScanner工具的环境,位于全局工具配置的SonarQube Scanner 的name定义为'sonar-scanner'def scannerHome = tool 'sonar-scanner'// 引用当前JenkinsSonarQube的环境,系统配置的SonarQube servers定义的name以及代码审查服务器位置withSonarQubeEnv('sonarqube') {sh """cd ${project_name}${scannerHome}/bin/sonar-scanner"""}}stage('编译安装公共子工程') {sh "mvn -f tensquare_common clean install"}stage('编译打包微服务工程,上传镜像') {// 项目参数传入的project_name 修改为变量sh "mvn -f ${project_name} clean package dockerfile:build"// 定义镜像名称def imageName = "${project_name}:${tag}"// 对镜像打标签sh "docker tag ${imageName} ${harbor_url}/${harbor_project}/${imageName}"// 把镜像推送到Harbor,项目为私有级别,登录时涉及一个问题,登录harbor需要输入账号和密码,Jenkinsfile需要配置项目目录下,会暴露给所有开发人员,为了安全使用凭证方式withCredentials([usernamePassword(credentialsId: "${harbor_auth}", passwordVariable: 'password', usernameVariable: 'username')]) {// 登录到Harbor,引用如上定义的username和password,就是用户haibo的信息sh "docker login -u ${username} -p ${password} ${harbor_url}"// 镜像上传sh "docker push ${harbor_url}/${harbor_project}/${imageName}"sh "echo 镜像上传成功"}// 部署应用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)])}
}

提交Jenkinsfile文件后尝试对项目进行构建
在这里插入图片描述
远程登录服务器并执行部署脚本
在这里插入图片描述
在生产环境部署服务器上查看容器和镜像
在这里插入图片描述
在这里插入图片描述

部署和测试所有微服务

更改微服务设置

eureka配置
修改ip地址为部署的生产环境服务器地址
在这里插入图片描述
zuul网关配置
修改eureka的ip地址,使其部署后在eureka服务器注册服务
在这里插入图片描述
admin_service权限中心
需要修改数据库相关信息(选择sonarqube服务器上的mysql作为后端数据库,此数据库在sonarqube代码审查服务器上)
在这里插入图片描述

# mysql授权root用户远程登录
grant all privileges on *.* to 'root'@'%' identified by 'Hahaha123@#';# 重载数据库刷新用户权限
flush privileges;

使用SQLyog进行连接测试
在这里插入图片描述
gathering活动微服务
同样修改数据库和eurekaIP地址使其部署后可以注册服务
在这里插入图片描述
将所有更新的配置上传代码仓库
在这里插入图片描述
导入MySQL数据
依次导入用户表和活动表
在这里插入图片描述
在这里插入图片描述
更改了配置后重新部署微服务

需要注意的是端口的区别
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
查看容器运行状态
在这里插入图片描述
通过浏览器查看
在这里插入图片描述
此时所有微服务已经全部构建完毕!可以通过postman对微服务功能进行检测
由于程序连接数据库有部分问题,通过参考文章:https://blog.csdn.net/L_it123/article/details/106845391 修改部分代码

首先检查权限中心能否登录

http://192.168.100.252:10020/admin/admin/login

在这里插入图片描述

部署前端静态web网站

在这里插入图片描述
安装Nginx服务器

rpm -ivh nginx-1.20.0-1.el7.ngx.x86_64.rpm# 修改端口
vim /etc/nginx/conf.d/default.conf
server {listen       9090;server_name  localhost;#access_log  /var/log/nginx/host.access.log  main;location / {root   /usr/share/nginx/html;index  index.html index.htm;}# 启动nginx
systemctl enable nginx --now

在这里插入图片描述

# 持续集成服务器安装nodejs环境
curl --silent --location https://rpm.nodesource.com/setup_10.x | bash -
yum install nodejs -y
npm install -g cnpm --registry=https://registry.npm.taobao.org

在这里插入图片描述
创建前端流水线项目
在这里插入图片描述
添加分支参数
在这里插入图片描述
在这里插入图片描述

编写流水线脚本

//gitlab的凭证 
def git_auth = "a4d0066f-6c58-4ab0-b714-6a24b3f5bc90"node {stage('拉取代码') {checkout scmGit(branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: "${branch}", url: 'git@192.168.100.240:tensquare_group/tensquare_front.git']])}stage('打包前端静态代码') {// 使用NodeJS的npm进行打包// sh 'npm cache clean --force'// sh 'rm -rf node_modules && rm -rf package-lock.json'  sh 'npm install'    sh 'npm run build'    }stage('部署网站') {	//=====以下为远程调用进行项目部署========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)])}
}

git_auth 凭据需要去Jenkins找
在这里插入图片描述
在这里插入图片描述
构建成功
在这里插入图片描述
使用浏览器访问
在这里插入图片描述
在这里插入图片描述
查询到了数据库的信息,因此证明前端页面和后端连接成功
在这里插入图片描述
再次查看容器日志,可以看到有修改数据库内容,证明前后端连通成功

# 查看活动微服务容器日志
docker logs -f `docker ps| grep -i 'gathering'|awk '{print $1}'`

在这里插入图片描述
至此Jenkins+Docker+SpringCloud微服务持续集成就搭建完成!剩余还需要对其优化!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/83944.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络安全设备及部署

什么是等保定级&#xff1f; 之前了解了下等保定级&#xff0c;接下里做更加深入的探讨 文章目录 一、网路安全大事件1.1 震网病毒1.2 海康威视弱口令1.3 物联网Mirai病毒1.4 专网 黑天安 事件1.5 乌克兰停电1.6 委内瑞拉电网1.7 棱镜门事件1.8 熊猫烧香 二、法律法规解读三、安…

【AI】Python调用讯飞星火大模型接口,轻松实现文本生成

随着chatGPT的出现&#xff0c;通用大模型已经成为了研究的热点&#xff0c;由于众所周知的原因&#xff0c;亚太地区调用经常会被禁&#xff0c;在国内&#xff0c;讯飞星火大模型是一个非常优秀的中文预训练模型。本文将介绍如何使用Python调用讯飞星火大模型接口&#xff0c…

全球飞机电磁阀总体规模分析

电磁阀是一种液压管路的电磁装置&#xff0c;通过使用电流产生磁场&#xff0c;从而驱动螺线管&#xff0c;控制阀中流体的流动。电磁阀作为流体控制自动化系统的执行器之一&#xff0c;有着结构紧凑、尺寸小、重量轻、密封良好、维修简便和可靠性高、节能降耗的特点&#xff0…

SpringBoot 的事务及使用

一、事务的常识 1、事务四特性&#xff08;ACID&#xff09; A 原子性&#xff1a;事务是最小单元,不可再分隔的一个整体。C 一致性&#xff1a;事务中的方法要么同时成功,要么都不成功,要不都失败。I 隔离性&#xff1a;多个事务操作数据库中同一个记录或多个记录时,对事务进…

【高频面试题】多线程篇

文章目录 一、线程的基础知识1.线程与进程的区别2.并行和并发有什么区别&#xff1f;3.创建线程的方式有哪些&#xff1f;3.1.Runnable 和 Callable 有什么区别&#xff1f;3.2.run()和 start()有什么区别&#xff1f; 4.线程包括哪些状态&#xff0c;状态之间是如何变化的4.1.…

C++核心编程:C++中的引用

C中的引用 引用的基本语法 作用&#xff1a;给变量起别名 语法&#xff1a;数据类型 & 别名 原名 //比如给一个int变量a命名一个别名 b int &b a;b 20; cout<< a << endl;//a 20引用的注意事项 引用必须初始化 int &b;//错误的引用在初始化后&…

问道管理:沪指窄幅震荡跌0.18%,有色、汽车等板块走低

3日早盘&#xff0c;沪指盘中窄幅震动下探&#xff0c;创业板逆市上扬&#xff1b;两市半日成交不足5000亿元&#xff0c;北向资金净卖出超15亿元。 到午间收盘&#xff0c;沪指跌0.18%报3255.88点&#xff0c;深成指跌0.23%&#xff0c;创业板指涨0.2%&#xff1b;两市算计成交…

剑指 Offer 37. 序列化二叉树

文章目录 题目描述简化题目思路分析 题目描述 请实现两个函数&#xff0c;分别用来序列化和反序列化二叉树。 你需要设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑&#xff0c;你只需要保证一个二叉树可以被序列化为一个字符串并且将…

Spring AOP(AOP概念,组成成分,实现,原理)

目录 1. 什么是Spring AOP&#xff1f; 2. 为什么要用AOP&#xff1f; 3. AOP该怎么学习&#xff1f; 3.1 AOP的组成 &#xff08;1&#xff09;切面&#xff08;Aspect&#xff09; &#xff08;2&#xff09;连接点&#xff08;join point&#xff09; &#xff08;3&a…

SpringMVC概述、SpringMVC的工作流程、创建SpringMVC的项目

&#x1f40c;个人主页&#xff1a; &#x1f40c; 叶落闲庭 &#x1f4a8;我的专栏&#xff1a;&#x1f4a8; c语言 数据结构 javaweb 石可破也&#xff0c;而不可夺坚&#xff1b;丹可磨也&#xff0c;而不可夺赤。 Spring MVC入门 一、Spring MVC概述二、入门案例2.1导入Sp…

【go语言学习笔记】04 Go 语言工程管理

文章目录 一、质量保证1. 单元测试1.1 定义1.2 Go 语言的单元测试1.3 单元测试覆盖率 2. 基准测试2.1 定义2.2 Go 语言的基准测试2.3 计时方法2.4 内存统计2.5 并发基准测试2.6 基准测试实战 3. 特别注意 二、性能优化1. 代码规范检查1.1 定义1.2 golangci-lint1.2.1 安装1.2.2…

【C++】STL——stack和queue的模拟实现、空间适配器、deque的介绍、增删查改函数的简单实现

文章目录 1.deque的简单介绍2.模拟实现stack3.模拟实现queue 1.deque的简单介绍 deque的介绍文档 deque(双端队列)&#xff1a;是一种双开口的"连续"空间的数据结构&#xff0c;双开口的含义是&#xff1a;可以在头尾两端进行插入和删除操作&#xff0c;且时间复杂度…

好的测试数据管理,到底要怎么做?

你的组织是否实施了测试数据管理&#xff1f;如果你的组织处理关键或敏感的业务数据&#xff0c;测试数据管理肯定会让组织受益。与测试数据相关的问题占所有软件缺陷的 15%&#xff0c;这一事实强调了测试数据的重要性。本文将准确讨论测试数据经理职责、测试数据经理需要什么…

Unity Shader:闪烁

还是一样的分为UI闪烁和物体闪烁&#xff0c;其中具体可分为&#xff1a;UI闪烁、物体闪烁与半透明闪烁 1&#xff0c;UI闪烁 对于UI 还是一样的&#xff0c;改写UI本身的shader&#xff1a; Shader "UI/YydUIShanShder" {Properties{[PerRendererData] _MainTex(…

UML类图

UML类图 类与类之间的关系 类与类之间的关系 依赖 一个类的对象,作为另一个类的局部变量, 虚线加箭头表示继承 实线三角实现 虚线三角关联 一个类的对象,作为一个类的字段 实线箭头 a. 组合 实心菱形实线箭头 b. 聚合 空心菱形实线箭头

vue3 - 使用reactive定义响应式数据进行列表赋值时,视图没有更新的解决方案

文章目录 1&#xff0c;问题2&#xff0c;原因3&#xff0c;解决方案一、再封装一层数据&#xff0c;即定义属性名&#xff0c;在后期赋值的时候&#xff0c;对此属性进行直接赋值三、使用数组的splice来直接更改原数组三、使用 ref 来定义数据 1&#xff0c;问题 在Vue 3.0 中…

快速入门:【c# 之 Winform开发】

C#基础 面向对象(OOP) c语言是面向过程。 c是面向过程面向对象。 c#是纯粹的面向对象: 核心思想是以人的思维习惯来分析和解决问题。万物皆对象。 面向对象开发步骤: 分析对象 特征行为关系(对象关系/类关系) 写代码: 特征–>成员变量 方法–>成员方法 实例化–具体对…

gitblit-使用

1.登入GitBlit服务器 默认用户和密码: admin/admin 2.创建一个新的版本库 点击图中的“版本库”&#xff0c;然后点击图中“创建版本库” 填写名称和描述&#xff0c;注意名称最后一定要加 .git选择限制查看、克隆和推送勾选“加入README”和“加入.gitignore文件”在图中的1处…

【C++】多态的底层原理(虚函数表)

文章目录 前言一、虚函数表二、派生类中虚函数表1.原理2.例子&#xff1a; 三、虚函数的存放位置四 、单继承中的虚函数表五、多继承中的虚函数表六、问答题 前言 一、虚函数表 通过观察测试我们发现b对象是8bytes&#xff0c;除了_b成员&#xff0c;还多一个__vfptr放在对象的…

FFmpeg安装和使用

sudo apt install ffmpeg sudo apt-get install libavfilter-devcmakelist模板 CMakeLists.txt cmake_minimum_required(VERSION 3.16) project(ffmpeg_demo)# 设置ffmpeg依赖库及头文件所在目录&#xff0c;并存进指定变量 set(ffmpeg_libs_DIR /usr/lib/x86_64-linux-gnu) …