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.hqwc.cn/news/60862.html

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

相关文章

网盘直链下载助手

一、插件介绍 1.介绍 这是一款免费开源获取网盘文件真实下载地址的油猴脚本&#xff0c;基于 PCSAPI&#xff0c;支持 Windows&#xff0c;Mac&#xff0c;Linux 等多平台&#xff0c;支持 IDM&#xff0c;XDown&#xff0c;Aria2 等多线程下载工具&#xff0c;支持 JSON-RPC…

linux_常用命令

一、日常使用命令/常用快捷键命令 开关机命令 1、shutdown –h now&#xff1a;立刻进行关机 2、shutdown –r now&#xff1a;现在重新启动计算机 3、reboot&#xff1a;现在重新启动计算机 4、su -&#xff1a;切换用户&#xff1b;passwd&#xff1a;修改用户密码 5、logou…

微服务——elasticsearch

初识ES——什么是elasticsearch elasticsearch的发展 初识ES——正向索引和倒排索引 初识ES——es与mysql的概念对比 类比到mysql中是表结构约束 概念对比 初始ES——安装es和kibana 1.部署单点es 1.1创建网络 要安装es容器和kibana容器并让他们之间相连&#xff0c;这里…

idea - 刷新 Git 分支数据 / 命令刷新 Git 分支数据

一、idea - 刷新 Git 分支数据 idea 找到 fetch 选项&#xff0c;重新获取分支数据 二、命令刷新 Git 分支数据 git fetch参考链接 1. 远程Gitlab新建的分支在IDEA里不显示

探讨C语言是否仍然满足现代编程需求

在过去的30年里&#xff0c;有人试图通过引入一门新的语言来取代C语言&#xff0c;其中一位被简称为BS的人也持有类似观点。尽管这门新语言在某些方面表现出色&#xff0c;但它并未能完全取代C语言&#xff0c;而是在特定领域发展出自己的优势。此后&#xff0c;又有一家公司决…

数据结构入门:队列

目录 文章目录 前言 1.队列 1.1 队列的概念及结构 1.2 队列的实现 1.2.1 队列的定义 1.2.2队列的初始化 1.2.3 入队 1.2.4 判空 1.2.5 出队 1.2.6 队头队尾数据 1.2.7 队列长度 1.2.8 队列销毁 总结 前言 队列&#xff0c;作为一种重要的数据结构&#xff0c;在计算机科学中扮演…

ffmpeg 4.4版本对MP4文件进行AES-CTR加密,和流式加密

对于ffmpeg的AES-CTR加密有两种方式&#xff0c;一个是普通的整个视频做加密&#xff0c;另一个是对视频做切片处理&#xff0c;然后进行加密。 一、对于普通的加密方式 直接使用下面的命令就行 ffmpeg -i animal.mp4 -vcodec copy -acodec copy -encryption_scheme cenc-aes…

力扣hot100刷题记录

二刷hot100&#xff0c;坚持每天打卡&#xff01;&#xff01;&#xff01;Today&#xff1a;2023-8-10 1. 两数之和 // 先求差&#xff0c;再查哈希表 public int[] twoSum(int[] nums, int target) {Map<Integer,Integer> map new HashMap<>();for(int i 0;i&…

【图像去噪的扩散滤波】基于线性扩散滤波、边缘增强线性和非线性各向异性滤波的图像去噪研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

JVM垃圾回收篇-垃圾回收器

JVM垃圾回收篇-垃圾回收器 串行垃圾回收器 Serial串行&#xff1a;为单线程环境设计且只使用一个线程进行垃圾回收&#xff0c;会暂停所有用户的线程&#xff0c;所以不适合服务器环境&#xff0c;适用于堆内存小&#xff0c;适合于个人电脑 开启串行垃圾回收 -XX:UseSeria…

计算机的构造和原理

本资料转载于B站up主芯片超人-花 仅用于学习和讨论&#xff0c;如有侵权请联系 计算机工作原理之3D动画揭秘&#xff1a;计算机内部如何工作_哔哩哔哩_bilibili 1.CPU的部分 1.1 CPU放大看 1.2 一个芯片中&#xff0c;有80亿至100亿晶体管 1.3 放大磁道 1.4 共享3级缓存 1.5 …

无涯教程-Perl - endservent函数

描述 此功能告诉系统您不再期望使用getservent从服务文件中读取条目。 语法 以下是此函数的简单语法- endservent返回值 此函数不返回任何值。 例 以下是显示其基本用法的示例代码- #!/usr/bin/perlwhile(($name, $aliases, $port_number,$protocol_name)getservent())…