文章目录
- 一、Jenkins+Docker+SpringCloud 持续集成流程说明
- 二、利用 Jenkins 打包微服务项目
- 1. 生成公共子工程 pom 文件
- 1.1 修改 Jenkinsfile
- 1.2 修改各个 pom.xml
- 2. 开始编译打包所有微服务项目
- 2.1 修改 Jenkinsfile 并提交
- 2.2 打包微服务项目
- ① 构建 eureka 服务
- ② 构建 zuul 服务
- ③ 构建权限中心服务
- ④ 构建活动微服务
- 三、利用 dockerfile-maven-plugin 插件构建 Docker 镜像
- 1. 在每个微服务项目的 pom.xml 加入 dockerfile-maven-plugin 插件
- 2. 在每个微服务项目根目录下建立 Dockerfile 文件
- 3. 修改 Jenkinsfile 构建脚本
- 4. 构建微服务镜像
- 5. 上传到 harbor 仓库
- 5.1 修改 Jenkinsfile
- 5.2 构建 eureka 测试打标签结果
- 5.3 使用凭证管理 Harbor 私服账户和密码
- 5.4 修改 Jenkinsfile
- 5.5 构建查看镜像是否上传 harbor
- 四、拉取镜像和发布应用
- 1. 安装 Publish Over SSH 插件
- 2. 配置远程部署服务器
- 3. 修改 Jenkinsfile
- 4. 添加端口新参数
- 5. 编写部署脚本 deploy.sh
- 6. 构建测试
- 五、构建运行所有微服务
- 1. 修改 mysql 和 eureka 地址
- 2. mysql 创建库并导入表
- 3. 逐个构建启动模块
- 4. 使用 postman 测试
- 六、部署前端静态 web 网站
- 1. 安装 Nginx 服务器
- 2. Jenkins 安装 NodeJS 插件
- 3. Jenkins 配置 Nginx 服务器
- 4. Jenkins 创建前端流水线项目
- 5. 修改前端代码文件并用小乌龟提交
- 6. 开始构建
一、Jenkins+Docker+SpringCloud 持续集成流程说明
大致流程说明:
- 开发人员每天把代码提交到 Gitlab 代码仓库。
- Jenkins 从 Gitlab 中拉取项目源码,编译并打成 jar 包,然后构建成 Docker 镜像,将镜像上传到 Harbor 私有仓库。
- Jenkins 发送 SSH 远程命令,让生产部署服务器到 Harbor 私有仓库拉取镜像到本地,然后创建容器。
- 最后,用户可以访问到容器。
服务器名称 | IP 地址 | 安装的软件 |
代码托管服务器 | 192.168.10.20 | Gitlab |
持续集成服务器 | 192.168.10.30 | Jenkins,Maven,Git,JDK,Sonarqube,Docker20.10.12-ce |
Docker 仓库服务器 | 192.168.10.40 | JDK,Tomcat,Docker20.10.12-ce,Harbor1.9.2 |
生产部署服务器 | 192.168.10.50 | Docker20.10.12-ce |
二、利用 Jenkins 打包微服务项目
1. 生成公共子工程 pom 文件
1.1 修改 Jenkinsfile
//git 的凭证
def git_auth="0b127895-eb97-4f8f-b471-1277e5549b54"
//git 的 URL
def git_url="git@192.168.10.20:test-group/tensquare_back.git"
node {
stage('pull code') {
//切换成变量,字符串符号使用双引号
checkout([$class: 'GitSCM', branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
}
stage('check code') {
//定义SonarQubeScanner工具
def scannerHome = tool 'sonar-scanner'
//引用SonarQube系统环境
withSonarQubeEnv('sonarqube') {
sh """
cd ${project_name}
${scannerHome}/bin/sonar-scanner
"""
}
}
//添加公共子工程
stage('make install public sub project') {
sh "mvn -f tensquare_common clean install"
}
}
1.2 修改各个 pom.xml
把 parent 父工程 pom.xml 中的 maven 插件代码移至除了 tensquare_common 以外每个子工程 pom.xml 中
修改 tensquare_parent 的 pom.xml
大框和小框中间是多余的部分,删掉或注释。
<plugin>
<!--提供打包(将应用打包成可执行的jar包)-->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
tensquare_common 中 pom 配置
不需要动。
其他微服务 pom 中的配置部分
应该已经有了,没有就添加。
提交整个代码
jenkinsfile 构建
查看 tensquare_common-1.0-SNAPSHOT.pom
[root@c7-2 ~]#ll /root/repo/com/tensquare/tensquare_common/1.0-SNAPSHOT/tensquare_common-1.0-SNAPSHOT.pom
-rw-r--r-- 1 root root 725 Feb 25 16:07 /root/repo/com/tensquare/tensquare_common/1.0-SNAPSHOT/tensquare_common-1.0-SNAPSHOT.pom
2. 开始编译打包所有微服务项目
2.1 修改 Jenkinsfile 并提交
//git 的凭证
def git_auth="0b127895-eb97-4f8f-b471-1277e5549b54"
//git 的 URL
def git_url="git@192.168.10.20:test-group/tensquare_back.git"
node {
stage('pull code') {
//切换成变量,字符串符号使用双引号
checkout([$class: 'GitSCM', branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
}
stage('check code') {
//定义SonarQubeScanner工具
def scannerHome = tool 'sonar-scanner'
//引用SonarQube系统环境
withSonarQubeEnv('sonarqube') {
sh """
cd ${project_name}
${scannerHome}/bin/sonar-scanner
"""
}
}
//添加公共子工程
stage('make install public sub project') {
sh "mvn -f tensquare_common clean install"
}
//打包微服务项目
stage('make package') {
sh "mvn -f ${project_name} clean package"
}
}
提交
2.2 打包微服务项目
① 构建 eureka 服务
查看
[root@c7-2 /var/lib/jenkins/workspace/tensquare_back/tensquare_eureka_server/target]#ls
classes generated-sources maven-archiver maven-status tensquare_eureka_server-1.0-SNAPSHOT.jar tensquare_eureka_server-1.0-SNAPSHOT.jar.original
[root@c7-2 /var/lib/jenkins/workspace/tensquare_back/tensquare_eureka_server/target]#pwd
/var/lib/jenkins/workspace/tensquare_back/tensquare_eureka_server/target
② 构建 zuul 服务
Jenkins 服务器中并没有 tensquare_parent 工程,而 zuul 需要依赖这个工程。解决方法:传递父工程进 Jenkins 仓库。
wget http://49.232.8.65/tensquare/tensquare_parent.zip
开始构建
[root@c7-2 ~]#ll /var/lib/jenkins/workspace/tensquare_back/tensquare_zuul/target/tensquare_zuul-1.0-SNAPSHOT.jar
-rw-r--r-- 1 root root 42564311 Feb 28 16:05 /var/lib/jenkins/workspace/tensquare_back/tensquare_zuul/target/tensquare_zuul-1.0-SNAPSHOT.jar
③ 构建权限中心服务
[root@c7-2 ~]#ll /var/lib/jenkins/workspace/tensquare_back/tensquare_admin_service/target/tensquare_admin_service-1.0-SNAPSHOT.jar
-rw-r--r-- 1 root root 53272061 Feb 28 16:12 /var/lib/jenkins/workspace/tensquare_back/tensquare_admin_service/target/tensquare_admin_service-1.0-SNAPSHOT.jar
④ 构建活动微服务
[root@c7-2 ~]#ll /var/lib/jenkins/workspace/tensquare_back/tensquare_gathering/target/tensquare_gathering-1.0-SNAPSHOT.jar
-rw-r--r-- 1 root root 51666837 Feb 28 16:14 /var/lib/jenkins/workspace/tensquare_back/tensquare_gathering/target/tensquare_gathering-1.0-SNAPSHOT.jar
这里不演示启动微服务 jar 包
三、利用 dockerfile-maven-plugin 插件构建 Docker 镜像
1. 在每个微服务项目的 pom.xml 加入 dockerfile-maven-plugin 插件
除了 common 模块,4 个模块要贴。
<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>
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 构建脚本
//git 的凭证
def git_auth="0b127895-eb97-4f8f-b471-1277e5549b54"
//git 的 URL
def git_url="git@192.168.10.20:test-group/tensquare_back.git"
node {
stage('pull code') {
//切换成变量,字符串符号使用双引号
checkout([$class: 'GitSCM', branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
}
stage('check code') {
//定义SonarQubeScanner工具
def scannerHome = tool 'sonar-scanner'
//引用SonarQube系统环境
withSonarQubeEnv('sonarqube') {
sh """
cd ${project_name}
${scannerHome}/bin/sonar-scanner
"""
}
}
//添加公共子工程
stage('make install public sub project') {
sh "mvn -f tensquare_common clean install"
}
//打包微服务,制作镜像
stage('make package') {
sh "mvn -f ${project_name} clean package dockerfile:build"
}
}
提交 jenkinsfile
4. 构建微服务镜像
构建 eureka 服务
其他三个服务类似。
查看四个镜像
5. 上传到 harbor 仓库
5.1 修改 Jenkinsfile
添加打标签步骤,用于上传镜像到 harbor 仓库。
//git 的凭证
def git_auth="0b127895-eb97-4f8f-b471-1277e5549b54"
//git 的 URL
def git_url="git@192.168.10.20:test-group/tensquare_back.git"
//镜像标签
def tag="latest"
//harbor的url地址
def harbor_url="192.168.10.40:85"
//镜像仓库名
def harbor_name="tensquare"
node {
stage('pull code') {
//切换成变量,字符串符号使用双引号
checkout([$class: 'GitSCM', branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
}
stage('check code') {
//定义SonarQubeScanner工具
def scannerHome = tool 'sonar-scanner'
//引用SonarQube系统环境
withSonarQubeEnv('sonarqube') {
sh """
cd ${project_name}
${scannerHome}/bin/sonar-scanner
"""
}
}
//添加公共子工程
stage('make install public sub project') {
sh "mvn -f tensquare_common clean install"
}
//打包微服务,制作镜像
stage('make package') {
sh "mvn -f ${project_name} clean package dockerfile:build"
//定义镜像名称
def imageName="${project_name}:${tag}"
//对镜像打标签
sh "docker tag ${imageName} ${harbor_url}/${harbor_name}/${imageName}"
}
}
提交 jenkinsfile
5.2 构建 eureka 测试打标签结果
查看镜像
其他三个模块类似。
5.3 使用凭证管理 Harbor 私服账户和密码
先在凭证建立 Harbor 的凭证,再生成凭证脚本代码
9269e103-c017-4555-bdf0-d9d8b56bc889
5.4 修改 Jenkinsfile
使用流水线代码生成器生成脚本代码
//git 的凭证
def git_auth="0b127895-eb97-4f8f-b471-1277e5549b54"
//git 的 URL
def git_url="git@192.168.10.20:test-group/tensquare_back.git"
//镜像标签
def tag="latest"
//harbor的url地址
def harbor_url="192.168.10.40:85"
//镜像仓库名
def harbor_name="tensquare"
//harbor的凭证
def harbor_auth="9269e103-c017-4555-bdf0-d9d8b56bc889"
node {
stage('pull code') {
//切换成变量,字符串符号使用双引号
checkout([$class: 'GitSCM', branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
}
stage('check code') {
//定义SonarQubeScanner工具
def scannerHome = tool 'sonar-scanner'
//引用SonarQube系统环境
withSonarQubeEnv('sonarqube') {
sh """
cd ${project_name}
${scannerHome}/bin/sonar-scanner
"""
}
}
stage('make install public sub project') {
sh "mvn -f tensquare_common clean install"
}
//打包微服务,制作镜像
stage('make package') {
sh "mvn -f ${project_name} clean package dockerfile:build"
//定义镜像名称
def imageName="${project_name}:${tag}"
//对镜像打标签
sh "docker tag ${imageName} ${harbor_url}/${harbor_name}/${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_name}/${imageName}"
sh "echo 镜像上传成功"
}
}
}
提交 Jenkinsfile
5.5 构建查看镜像是否上传 harbor
四个模块都构建一遍
四、拉取镜像和发布应用
1. 安装 Publish Over SSH 插件
需要重启 jenkins
2. 配置远程部署服务器
拷贝公钥从 Jenkins 服务器拷贝到生产服务器
ssh-copy-id 192.168.10.50
系统配置 -》添加远程服务器
3. 修改 Jenkinsfile
构建脚本生成远程调用模板代码
白色部分是需要修改的部分
Jenkinsfile
//git 的凭证
def git_auth="0b127895-eb97-4f8f-b471-1277e5549b54"
//git 的 URL
def git_url="git@192.168.10.20:test-group/tensquare_back.git"
//镜像标签
def tag="latest"
//harbor的url地址
def harbor_url="192.168.10.40:85"
//镜像仓库名
def harbor_name="tensquare"
//harbor的凭证
def harbor_auth="9269e103-c017-4555-bdf0-d9d8b56bc889"
node {
stage('pull code') {
//切换成变量,字符串符号使用双引号
checkout([$class: 'GitSCM', branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
}
stage('check code') {
//定义SonarQubeScanner工具
def scannerHome = tool 'sonar-scanner'
//引用SonarQube系统环境
withSonarQubeEnv('sonarqube') {
sh """
cd ${project_name}
${scannerHome}/bin/sonar-scanner
"""
}
}
stage('make install public sub project') {
sh "mvn -f tensquare_common clean install"
}
//打包微服务,制作镜像
stage('make package') {
sh "mvn -f ${project_name} clean package dockerfile:build"
//定义镜像名称
def imageName="${project_name}:${tag}"
//对镜像打标签
sh "docker tag ${imageName} ${harbor_url}/${harbor_name}/${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_name}/${imageName}"
sh "echo 镜像上传成功"
//部署应用
sshPublisher(publishers: [sshPublisherDesc(configName: 'master_server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "/opt/jenkins_shell/deploy.sh ${harbor_url} ${harbor_name} ${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
4. 添加端口新参数
项目配置里面
5. 编写部署脚本 deploy.sh
192.168.10.50
注意修改用户密码 tom/Zc120604
#!/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 tom -p Zc120604 $harbor_url
# 下载镜像
docker pull $imageName
# 启动容器
docker run -di -p $port:$port $imageName
echo "容器启动成功"
[root@c7-4 ~]#mkdir /opt/jenkins_shell
[root@c7-4 ~]#cd /opt/jenkins_shell
[root@c7-4 /opt/jenkins_shell]#vim deploy.sh
[root@c7-4 /opt/jenkins_shell]#ls
deploy.sh
[root@c7-4 /opt/jenkins_shell]#chmod +x deploy.sh
[root@c7-4 /opt/jenkins_shell]#ll
总用量 4
-rwxr-xr-x 1 root root 879 3月 1 14:39 deploy.sh
6. 构建测试
在生产服务器上查看镜像
在生产服务器上查看容器是否运行
浏览器访问
五、构建运行所有微服务
1. 修改 mysql 和 eureka 地址
IDEA 里模块修改配置文件
要连接数据库和 eureka 的都要改
提交整个代码到 gitlab
2. mysql 创建库并导入表
参考:
PS:mysql 需要授权远程登录。
grant all privileges on *.* to 'root'@'%' identified by '123456' with grant option;
flush privileges;
3. 逐个构建启动模块
- eureka:10086
- zuul:10020
- admin:9001
- gathering:9002(业务模块与前端对接)
可以看到服务已经注册上去。
4. 使用 postman 测试
token 是 post 测试获取的信息。
get 请求和 post 请求分别测试一遍
六、部署前端静态 web 网站
1. 安装 Nginx 服务器
192.168.10.50
yum -y install epel-release
yum -y install nginx
修改 nginx 的端口,默认 80,改为 9090
vi /etc/nginx/nginx.conf
#-----------------------------
server {
listen 9090;
listen [::]:9090;
server_name _;
root /usr/share/nginx/html;
启动 Nginx
systemctl enable nginx && systemctl start nginx
2. Jenkins 安装 NodeJS 插件
3. Jenkins 配置 Nginx 服务器
Manage Jenkins -> Global Tool Configuration
我们选 12.13.1 版本,太新的可能有问题。
4. Jenkins 创建前端流水线项目
或者使用脚本的方式(强烈推荐)
//harbor的凭证
def git_auth="0b127895-eb97-4f8f-b471-1277e5549b54"
node {
stage('pull code') {
//切换成变量,字符串符号使用双引号
checkout([$class: 'GitSCM', branches: [[name: "*/${branch}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: 'git@192.168.10.20:test-group/tensquare_front.git']]])
}
stage('make package,deploy') {
//使用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. 修改前端代码文件并用小乌龟提交
中间可能要登录 gitlab
root/12345678
6. 开始构建
生产服务器验证查看 /usr/share/nginx/html 根目录
访问前端页面
http://192.168.10.50:9090/