Jenkins+Docker+SpringCloud微服务持续集成
- Jenkins+Docker+SpringCloud持续集成流程说明
- SpringCloud微服务源码概述
- 本地部署
- SpringCloud微服务部署
- 使用Dockerfile制作微服务镜像
- Harbor镜像仓库安装及使用
- Harbor安装
- 在Harbor创建用户和项目
- 把镜像上传到Harbor
- 从Harbor下载镜像
- 微服务持续集成
- 项目代码上传到Gitlab
- 从Gitlab拉取项目源码
- 提交到SonarQube代码审查
- 将微服务打包成jar包
- 使用Dockerfile编译、生成镜像
- 上传到Harbor镜像仓库
- 报错
- 拉取镜像和发布应用
- 配置远程部署服务器
- 编写远程脚本文件
- 编写Jenkinsfile
- 更改微服务设置,准备好测试数据
- 部署前端静态web网站
Jenkins+Docker+SpringCloud持续集成流程说明
- 开发人员每天把代码提交到Gitlab代码仓库
- Jenkins从Gitlab中拉取项目源码,编译并打成jar包,然后构建成Docker镜像,将镜像上传到Harbor私有仓库
- Jenkins发送SSH远程命令,让生产部署服务器到Harbor私有仓库拉取镜像到本地,然后创建容器
- 最后,用户可以访问到容器
SpringCloud微服务源码概述
- 项目架构:前后端分离
- 后端技术栈:SpringBoot+SpringCloud+SpringDataJpa
- 微服务项目结构:
- tensquare_parent:父工程,存放基础配置
- tensquare_common:通用工程,存放工具类
- tensquare_eureka_server:SpringCloud的Eureka注册中心
- tensquare_zuul:SpringCloud的网关服务
- tensquare_admin_service:基础权限认证中心,负责用户认证(使用JWT认证)
- tensquare_gathering:一个简单的业务模块,活动微服务相关逻辑
- 数据库结构:
- tensquare_user:用户认证数据库,存放用户账户数据。对应tensquare_admin_service微服务
- tensquare_gathering:活动微服务数据库。对应tensquare_gathering微服务
- 微服务配置分析:
- tensquare_eureka
- tensquare_zuul
- tensquare_admin_service
- tensquare_gathering
本地部署
逐一启动微服务
- 运行eureka服务器
- 通过浏览器进入localhost:10086
- 开启网关zuul
- 开启权限中心
- 开启微服务
- 都成功启动
SpringCloud微服务部署
首先需要导入插件
在pom.xml里添加
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
- SpringBoot微服务项目打包
- 生成的jar包在target下面
- 本地运行微服务的jar包
java -jar xxx.jar
- 我们可以使用cmd运行一下
使用Dockerfile制作微服务镜像
安装docker
安装需要的安装包
yum install -y yum-utils
设置镜像仓库
我们用阿里云
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
更新yum软件包索引
yum makecache fast
安装docker docker-ce 社区
yum -y install docker-ce docker-ce-cli containerd.io
启动docker
systemctl start docker
查看版本
docker version
将eureka的jar包上传至服务器
mkdir /root/eureka
mv tensquare_eureka_server-1.0-SNAPSHOT.jar /root/eureka/
cd /root/eureka/
vim Dockerfile
FROM 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 images
REPOSITORY TAG IMAGE ID CREATED SIZE
eureka v1 255f6b6c7c53 4 seconds ago 150MB
openjdk 8-jdk-alpine a3562aa0b991 2 years ago 105MB
验证镜像是否成功
docker run -di -p 10086:10086 eureka:v1
查看日志
docker logs -f 容器id
浏览器访问
Harbor镜像仓库安装及使用
- Harbor(港口,港湾)是一个用于存储和分发Docker镜像的企业级Registry服务器。
- 除了Harbor这个私有镜像仓库之外,还有Docker官方提供的Registry。相对Registry,Harbor具有很多优势:
- 提供分层传输机制,优化网络传输
Docker镜像是是分层的,而如果每次传输都使用全量文件(所以用FTP的方式并不适合),显然不经济。必须提供识别分层传输的机制,以层的UUID为标识,确定传输的对象。 - 提供WEB界面,优化用户体验
只用镜像的名字来进行上传下载显然很不方便,需要有一个用户界面可以支持登陆、搜索功能,包括区分公有、私有镜像。 - 支持水平扩展集群
当有用户对镜像的上传下载操作集中在某服务器,需要对相应的访问压力作分解。 - 良好的安全机制
企业中的开发团队有很多不同的职位,对于不同的职位人员,分配不同的权限,具有更好的安全性。
Harbor安装
我们在harbor服务器上进行安装
安装docker和compose
安装需要的安装包
yum install -y yum-utils
设置镜像仓库
我们用阿里云
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
安装docker
yum install docker-ce docker-ce-cli containerd.io
systemctl enable docker --now
下载安装compose
curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-$(uname -s)-$(uname -m) > /usr/local/bin/docker-compose
授权
chmod +x /usr/local/bin/docker-compose
查看版本
docker-compose version
安装harbor
下载地址
下载完毕之后上传至服务器
tar xf harbor-offline-installer-v1.9.2.tgz -C /usr/local
cd /usr/local/harbor
修改harbor.yml 文件里面的hostname 改成本机地址
vim harbor.yml
hostname: 192.168.188.103
端口改成85 就不会与80冲突
port: 85
拉取镜像命令
./prepare
安装
./install.sh
当完成安装后,即可通过本机地址进行浏览器的访问
账户名为admin,密码默认为Harbor12345
在Harbor创建用户和项目
创建项目
Harbor的项目分为公开和私有的:
- 公开项目:所有用户都可以访问,通常存放公共的镜像,默认有一个library公开项目。
- 私有项目:只有授权用户才可以访问,通常存放项目本身的镜像。
我们可以为微服务项目创建一个新的项目
创建用户
密码Xiaotian123给私有项目分配用户
把镜像上传到Harbor
- 给镜像打上标签
[root@jenkins eureka]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
eureka v1 255f6b6c7c53 32 minutes ago 150MB
openjdk 8-jdk-alpine a3562aa0b991 2 years ago 105MB
docker tag eureka:v1 192.168.188.103:85/tensquare/eureka:v1
[root@jenkins eureka]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.188.103:85/tensquare/eureka v1 255f6b6c7c53 33 minutes ago 150MB
eureka v1 255f6b6c7c53 33 minutes ago 150MB
openjdk 8-jdk-alpine a3562aa0b991 2 years ago 105MB
- 把Harbor地址加入到Docker信任列表
vi /etc/docker/daemon.json
{
"registry-mirrors": ["https://zydiol88.mirror.aliyuncs.com"],
"insecure-registries": ["192.168.188.103:85"]
}
重启docker
- 登录Harbor
docker login 192.168.188.103:85 -u maomao -p Xiaotian123
- 推送镜像
docker push 192.168.188.103:85/tensquare/eureka:v1
仓库里面有了上传的镜像
从Harbor下载镜像
在192.168.188.102服务器下载镜像
vi /etc/docker/daemon.json
{
"registry-mirrors": ["https://zydiol88.mirror.aliyuncs.com"],
"insecure-registries": ["192.168.188.103:85"]
}
systemctl daemon-reload
systemctl restart docker
先登录,再从Harbor下载镜像
[root@tomcat ~]# docker login 192.168.188.103:85 -u maomao -p Xiaotian123
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
拉取镜像
docker pull 192.168.188.103:85/tensquare/eureka:v1
docker images
微服务持续集成
项目代码上传到Gitlab
上传后台微服务和前端web网站代码
首先去gitlab上面创建项目
我们在这个组里就有新建的两个项目
上传代码,通过IDEA操作Add添加到本地缓冲区
将代码提交到本地代码仓库
新建一个仓库地址
推送代码至仓库
项目已经成功提交
前端代码我们通过Git小乌龟来上传
安装地址在代码目录 右键 选择在这创建版本库
右键 选择commit
选择推送 将代码推送远程仓库
设置仓库地址
填写仓库用户和密码
到此为止 代码都已经上传至仓库
从Gitlab拉取项目源码
我们进入jenkins构建后端流水线项目
添加参数
选择SCM 脚本上传至仓库
配置git地址 通过ssh拉取
打开IDEA 在工程根目录下面创建一个Jenkinsfile打开流水线语法
帮助我们生成脚本
我们可以定义变量
//git凭证ID
def git_auth = "41580d48-d4c3-4116-9a71-4d4d777c5753"
// git的url地址
def git_url = "git@192.168.188.97:maomao_group/tensquare_back.git"
node {
stage('拉取代码') {
checkout([$class: 'GitSCM', branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
}
}
上传Jenkinsfile文件
开始构建项目
注意 脚本里面一定要注意格式和语法,自己因为冒号的原因,错了三次才改正过来
提交到SonarQube代码审查
在tensquare_back项目里,添加两个参数
这个参数选择选项参数(Choice Parameter)
添加需要选择审查的名字
这时候构建就可以选择需要审查的代码
接下来配置sonarkube文件在eureka_server根目录创建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
zull
# must be unique in a given SonarQube instance
sonar.projectKey=tensquare_zuul
# this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1.
sonar.projectName=tensquare_zuul
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
admin_service
# must be unique in a given SonarQube instance
sonar.projectKey=tensquare_admin_service
# this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1.
sonar.projectName=tensquare_admin_service
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
gathering
# must be unique in a given SonarQube instance
sonar.projectKey=tensquare_gathering
# this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1.
sonar.projectName=tensquare_gathering
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
修改Jenkinsfile脚本
//git凭证ID
def git_auth = "41580d48-d4c3-4116-9a71-4d4d777c5753"
// git的url地址
def git_url = "git@192.168.188.97:maomao_group/tensquare_back.git"
node {
stage('拉取代码') {
checkout([$class: 'GitSCM', branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
}
stage('代码审查') {
//定义了当前Jenkins的SonarQubeScanner工具环境 在全局工具配置里查看
def scannerHome = tool 'sonar-scanner'
//引用当前JenkinsSonarQube环境 在系统配置里查看
withSonarQubeEnv('sonarqube') {
sh """
cd ${project_name}
${scannerHome}/bin/sonar-scanner
"""
}
}
}
push代码至仓库 然后构建项目
查看控制台输出开始审查代码
构建成功
来到sonarkube后台查看审查结果
然后我们把剩下三个代码也进行审查
没有问题
将微服务打包成jar包
第一步 需要对一个公共的子工程进程编译,安装
在Jenkinsfile里添加一个步骤
//git凭证ID
def git_auth = "41580d48-d4c3-4116-9a71-4d4d777c5753"
// git的url地址
def git_url = "git@192.168.188.97:maomao_group/tensquare_back.git"
node {
stage('拉取代码') {
checkout([$class: 'GitSCM', branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
}
stage('代码审查') {
//定义了当前Jenkins的SonarQubeScanner工具环境 在全局工具配置里查看
def scannerHome = tool 'sonar-scanner'
//引用当前JenkinsSonarQube环境 在系统配置里查看
withSonarQubeEnv('sonarqube') {
sh """
cd ${project_name}
${scannerHome}/bin/sonar-scanner
"""
}
}
stage('编译,安装公共子工程') {
sh "mvn -f tensquare_common clean install"
}
}
将脚本上传至git仓库,再尝试进行一次构建
进行打包
构建成功
如果失败的话,进入IDEA
将tensquare_parent父工程里面的 spring-boot-maven
插件移走 移到需要项目打包的项目里去
tensquare_common子工程不需要这个插件
只需要将插件加入tensquare_eureka_server、tensquare_admin_service、tensquare_gathering、tensquare_zuul
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
调整好之后,继续编写Jenkinsfile,需要打包其他微服务了
//git凭证ID
def git_auth = "41580d48-d4c3-4116-9a71-4d4d777c5753"
// git的url地址
def git_url = "git@192.168.188.97:maomao_group/tensquare_back.git"
node {
stage('拉取代码') {
checkout([$class: 'GitSCM', branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
}
stage('代码审查') {
//定义了当前Jenkins的SonarQubeScanner工具环境 在全局工具配置里查看
def scannerHome = tool 'sonar-scanner'
//引用当前JenkinsSonarQube环境 在系统配置里查看
withSonarQubeEnv('sonarqube') {
sh """
cd ${project_name}
${scannerHome}/bin/sonar-scanner
"""
}
}
stage('编译,安装公共子工程') {
sh "mvn -f tensquare_common clean install"
}
// 这里project_name就是参数 选择对谁打包
stage('编译,安装公共子工程') {
sh "mvn -f ${project_name} clean package"
}
}
对eureka服务进行打包
通过目录也可以看见 tensquare_admin_service没有进行打包
tensquare_eureka_server进行了打包 target下有jar包
接下来将其它三个微服务以同样方式打包
但是在打包tensquare_zuul
报错了
因为网关依赖父工程,但是仓库里的父工程没有
因此我们需要手动将父工程pom.xml文件传到Jenkins服务器里
再次重新构建
这次找到父工程的pom文件之后 打包成功
然后将剩下两个微服务打包构建
除了第二次打包网关失败 其余都成功了
使用Dockerfile编译、生成镜像
利用dockerfile-maven-plugin
插件构建Docker镜像
在每个微服务项目的pom.xml加入dockerfile-maven-plugin插件
我们可以在之前spring-boot-maven-plugin
插件下面添加dockerfile-maven-plugin
插件
<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>
在每个微服务里创建一个Dockerfile文件
#FROM java:8
FROM openjdk:8-jdk-alpine
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
EXPOSE 10086
ENTRYPOINT ["java","-jar","/app.jar"]
修改Jenkinsfile 添加dockerfile:build
命令
//git凭证ID
def git_auth = "41580d48-d4c3-4116-9a71-4d4d777c5753"
// git的url地址
def git_url = "git@192.168.188.97:maomao_group/tensquare_back.git"
node {
stage('拉取代码') {
checkout([$class: 'GitSCM', branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
}
stage('代码审查') {
//定义了当前Jenkins的SonarQubeScanner工具环境 在全局工具配置里查看
def scannerHome = tool 'sonar-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"
}
}
然后对eureka_server进行构建
进行镜像的制作
执行Dockerfile里写的步骤
最后成功
查看镜像,已经创建成功
接下来把其他微服务也构建成镜像,需要写Dockerfile和添加插件
tensquare_zuul
#FROM java:8
FROM openjdk:8-jdk-alpine
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
EXPOSE 10020
ENTRYPOINT ["java","-jar","/app.jar"]
tensquare_admin_service
#FROM java:8
FROM openjdk:8-jdk-alpine
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
EXPOSE 9001
ENTRYPOINT ["java","-jar","/app.jar"]
tensquare_gathering
#FROM java:8
FROM openjdk:8-jdk-alpine
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
EXPOSE 9002
ENTRYPOINT ["java","-jar","/app.jar"]
上传代码之后进行构建
四个微服务的镜像都构建成功
上传到Harbor镜像仓库
修改Jenkinsfile构建脚本
//git凭证ID
def git_auth = "41580d48-d4c3-4116-9a71-4d4d777c5753"
// git的url地址
def git_url = "git@192.168.188.97:maomao_group/tensquare_back.git"
// 镜像的版本号
def tag = "latest"
// Harbor的url地址
def harbor_url = "192.168.188.103:85"
// 镜像库项目名称
def harbor_project = "tensquare"
node {
stage('拉取代码') {
checkout([$class: 'GitSCM', branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
}
stage('代码审查') {
//定义了当前Jenkins的SonarQubeScanner工具环境 在全局工具配置里查看
def scannerHome = tool 'sonar-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用户凭据
再次进去查看 将生成的id复制
4135b3f5-a3eb-436e-a6ef-fe096098bb4f进入流水线语法
将流水线生成的语法稍作改变
增加变量
// git凭证ID
def git_auth = "41580d48-d4c3-4116-9a71-4d4d777c5753"
// git的url地址
def git_url = "git@192.168.188.97:maomao_group/tensquare_back.git"
// 镜像的版本号
def tag = "latest"
// Harbor的url地址
def harbor_url = "192.168.188.103:85"
// 镜像库项目名称
def harbor_project = "tensquare"
// Harbor的登录凭据ID
def harbor_auth = "4135b3f5-a3eb-436e-a6ef-fe096098bb4f"
node {
stage('拉取代码') {
checkout([$class: 'GitSCM', branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
}
stage('代码审查') {
//定义了当前Jenkins的SonarQubeScanner工具环境 在全局工具配置里查看
def scannerHome = tool 'sonar-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')]) {
// 登录到Harbor
sh "docker login -u ${username} -p ${password} ${harbor_url}"
// 镜像上传
sh "docker push ${harbor_url}/${harbor_project}/${imageName}"
sh "echo 镜像上传成功了"
}
}
}
上传镜像成功
报错
这一步有两个小细节错了 害得我弄了一个多小时才找出来,气得要死
这里显示我docker tag 命令参数多了
后面仔细检测发现这里多了一个空格
各种排查,仍然有空格,后面在任务配置里找到选项参数
发现这里面的选项前面打了空格,导致脚本读取参数也包含了空格第二个错误是因为把username写成了usrname
拉取镜像和发布应用
安装Publish Over SSH
插件 可以实现远程发送Shell命令
配置远程部署服务器
将jenkins服务器的公钥拷贝到远程tomcat服务器
ssh-copy-id 192.168.188.107
在jenkins进入系统配置,找到Publish over SSH
Path to key 填私钥存放的位置 /root/.ssh/id_rsa
下面点击新增
Hostname 填 远程部署项目的主机ip
接下来要写Jenkinsfile脚本,首先去流水线语法
找到这个 可以帮我们产生一些远程连接的脚本
ssh server 选择我们之前传公钥的服务器
其他现在都留空,点击生成流水线脚本
这段就是复制下来的脚本
sshPublisher(publishers: [sshPublisherDesc(configName: 'tomcat_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)])
- execCommand就是在远程服务器上执行的命令,我们让它执行一个shell脚本,shell脚本就可以帮助我们完成部署
- 因为我们微服务的端口是不相同的,所以还要在流水线任务里面添加新的端口参数
编写远程脚本文件
进入tomcat服务器
[root@tomcat ~]# mkdir /opt/jenkins_shell
[root@tomcat ~]# cd /opt/jenkins_shell/
[root@tomcat jenkins_shell]# vim deploy.sh
#! /bin/bash
#接收外部参数
harbor_url=$1
harbor_project=$2
project_name=$3
tag=$4
port=$5
imageName=$harbor_url/$harbor_project/$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 maomao -p Xiaotian123 $harbor_url
# 下载镜像
docker pull $imageName
# 启动容器
docker run -di -p $port:$port $imageName
echo "容器启动成功"
然后给脚本加上执行权限
chmod +x deploy.sh
编写Jenkinsfile
// git凭证ID
def git_auth = "41580d48-d4c3-4116-9a71-4d4d777c5753"
// git的url地址
def git_url = "git@192.168.188.105:maomao_group/tensquare_back.git"
// 镜像的版本号
def tag = "latest"
// Harbor的url地址
def harbor_url = "192.168.188.106:85"
// 镜像库项目名称
def harbor_project = "tensquare"
// Harbor的登录凭据ID
def harbor_auth = "c0e6642d-bab9-4978-be45-955e5130fae2"
node {
stage('拉取代码') {
checkout([$class: 'GitSCM', branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
}
stage('代码审查') {
//定义了当前Jenkins的SonarQubeScanner工具环境 在全局工具配置里查看
def scannerHome = tool 'sonar-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')]) {
// 登录到Harbor
sh "docker login -u ${username} -p ${password} ${harbor_url}"
// 镜像上传
sh "docker push ${harbor_url}/${harbor_project}/${imageName}"
sh "echo 镜像上传成功啦"
}
// 部署项目
sshPublisher(publishers: [sshPublisherDesc(configName: 'tomcat_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)])
}
}
上传代码之后构建项目
开始远程登录服务器执行脚本
在部署服务器上查看镜像和容器
更改微服务设置,准备好测试数据
- eureka配置
修改ip地址为我们部署的服务器地址 - zuul网关
也是修改eruka的ip地址 - admin_service权限中心
这里需要修改数据库相关信息(我们选择sonarqube服务器上的mysql作为后端数据库,此数据库在jenkins服务器上) - 因此我们需要去mysql里面进行授权
授权root账户能够在所以客户端登录
grant all privileges on *.* to 'root'@'%' identified by '123';
刷新权限
flush privileges;
利用Navicat 测试
修改配置
- gathering
也是修改数据库和ip
最后将所有更新的配置上传代码仓库
然后导入mysql数据
最后把剩下的三个微服务也构建成容器
这里需要注意的是要改变端口
查看容器
通过浏览器查看
部署前端静态web网站
在tomcat服务器上进行
yum install -y epel-release
yum -y install nginx
修改nginx的端口,默认80,改为9090
vim /etc/nginx/nginx.conf
server {
listen 9090 default_server;
listen [::]:9090 default_server;
server_name _;
root /usr/share/nginx/html;
启动nginx
systemctl enable nginx --now
安装NodeJS插件
Jenkins在全局工具配置里配置Nginx服务器找到NodeJS 选择一个版本 保存
创建前端流水线项目
首先添加分支参数
编写流水线脚本
//gitlab的凭证
def git_auth = "41580d48-d4c3-4116-9a71-4d4d777c5753"
node { stage('拉取代码') {
checkout([$class: 'GitSCM', branches: [[name: '*/${branch}']],
doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [],
userRemoteConfigs: [[credentialsId: "${git_auth}", url:
'git@192.168.188.105:maomao_group/tensquare_front.git']]])
}
stage('打包,部署网站') {
//使用NodeJS的npm进行打包
nodejs('nodejs12'){
sh '''
npm install
npm run build
'''
}
//=====以下为远程调用进行项目部署========
sshPublisher(publishers: [sshPublisherDesc(configName: 'tomcat_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 凭据id需要去jenkins里面找
构建成功
通过浏览器登录ip+9090端口
登录
查询到了数据库的信息,因此证明前端页面和后端连接成功
至此我们的Jenkins+Docker+SpringCloud微服务持续集成就搭建完成了,剩下的就是对其的优化了