对微服务打包,制作镜像,上传镜像到,创建容器发布,及对接数据库(后端)
对微服务打包,制作镜像,上传镜像到,创建容器发布
一:使用Dockerfile 编译,生成镜像
构建common工具
common公共子工程是所有微服务使用的工具,所以先打包common子工程
修改Jenkinsfile文件,添加编译,打包,镜像制作的步骤
复制//定义git凭证
def git_url="git@192.168.23.201:my_group/tensquare_back.git"
//定义git的url
def git_auth="fc529390-8711-4c3a-894e-fd77845bf5e4"
node {
stage('pull code'){
checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
}
stage('check code'){
//定义SonarQubeScanner工具,要和Jenkins的全局工具配置里的一致
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"
}
}
父工程的pom.xml 配置
复制<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>tensquare_parent</artifactId>
<groupId>com.tensquare</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>tensquare_eureka_server</artifactId>
<dependencies>
<!-- eureka服务器 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
</project>
eureka的pom配置。(除了common工具,其他项目的pom文件也修改)
复制<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>tensquare_parent</artifactId>
<groupId>com.tensquare</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>tensquare_eureka_server</artifactId>
<dependencies>
<!-- eureka服务器 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
</project>
直接提交整个项目,然后在Jenkins里构建。构建时,会下载maven组件,需要一定时间。
公共子工程安装到了设置的仓库目录下
/root/repo/com/tensquare/tensquare_common/1.0-SNAPSHOT/tensquare_common-1.0-SNAPSHOT.jar
若果不移除父项目里pom 文件设置的maven 设置,则会报错如下。 这是因为common会使用父目录的pom设置,而common并不是一个微服务,其只是一个工具
复制RROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project tensquare_common: Compilation failure -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
编译打包所有微服务
修改Dockerfile,并提交。然后在Jenkins 编译打包所有微服务项目
复制//定义git凭证
def git_url="git@192.168.23.201:my_group/tensquare_back.git"
//定义git的url
def git_auth="fc529390-8711-4c3a-894e-fd77845bf5e4"
node {
stage('pull code'){
checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
}
stage('check code'){
//定义SonarQubeScanner工具,要和Jenkins的全局工具配置里的一致
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"
}
}
构建完eureka 后,构建zuul 出错。因为没有把父工程放入到仓库目录中
zull 报错如下
复制[ERROR] Failed to execute goal on project tensquare_zuul: Could not resolve dependencies for project com.tensquare:tensquare_zuul:jar:1.0-SNAPSHOT: Failed to collect dependencies at com.tensquare:tensquare_common:jar:1.0-SNAPSHOT: Failed to read artifact descriptor for com.tensquare:tensquare_common:jar:1.0-SNAPSHOT: Could not find artifact com.tensquare:tensquare_parent:pom:1.0-SNAPSHOT -> [Help 1]
将父工程放入到Jenkins服务器的/root/repo/com/tensquare目录下
链接:https://pan.baidu.com/s/1jNVAfbbBzA9SJ7lrQN09Ag?pwd=kq74
提取码:kq74
再次构建zuul 及之后的微服务
在Jenkins的/var/lib/jenkins/workspace/tensquare_back目录下,有构建服务成功后,生成的各个微服务目录
在各个微服务目录下的 target 目录下,有服务的 jar 包
所有微服务项目打包成功
生成镜像
在 每个微服务 项目的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文件
注意修改发布端口
复制#FROM java:8
FROM openjdk:8-jdk-alpine
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
EXPOSE 10086
ENTRYPOINT ["java","-jar","/app.jar"]
修改Jenkinsfile构建脚本,并上传
复制//定义git凭证
def git_url="git@192.168.23.201:my_group/tensquare_back.git"
//定义git的url
def git_auth="fc529390-8711-4c3a-894e-fd77845bf5e4"
node {
stage('pull code'){
checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
}
stage('check code'){
//定义SonarQubeScanner工具,要和Jenkins的全局工具配置里的一致
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"
}
}
在Jenkins对四个微服务进行重新构建,制作镜像.
在Jenkins服务器上,查看镜像
如果构建报错如下,
复制[ERROR] No plugin found for prefix 'dockerfile' in the current project and in the plugin groups [org.apache.maven.plugins, org.codehaus.mojo] available from the repositories [local (/root/repo), alimaven (http://maven.aliyun.com/nexus/content/groups/public/)] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
需要在安装maven的Jenkins服务上,配置maven的settings文件,然后Jenkins重新构建
复制<pluginGroups>
<pluginGroup>com.spotify</pluginGroup> <!--添加此行-->
</pluginGroups>
二:镜像上传到Harbor镜像仓库
给镜像打标签
修改Jenkinsfile构建脚本
复制//定义git凭证
def git_url="git@192.168.23.201:my_group/tensquare_back.git"
//定义git的url
def git_auth="fc529390-8711-4c3a-894e-fd77845bf5e4"
//镜像标签
def tag="latest"
//harbor的url地址
def harbor_url="192.168.23.204:85"
//镜像仓库名
def harbor_name="tensquare"
node {
stage('pull code'){
checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
}
stage('check code'){
//定义SonarQubeScanner工具,要和Jenkins的全局工具配置里的一致
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}"
}
}
构建eureka,测试打标签效果
配置Harbor私服账户密码,上传镜像到harbor
使用凭证管理Harbor私服账户和密码
先在凭证建立Harbor凭证,再生成凭证脚本代码
点击生成的凭证--->Update--->复制ID栏
使用流水线语法生成代码
sample Step:withCredentials:Bind credentials to variables--->
Bindings--->Add--->Username and password (separated)--->
用户名变量:username 密码变量 password 凭证选择harbor凭证
修改Jenkinsfile文件,并上传
复制//定义git凭证
def git_url="git@192.168.23.201:my_group/tensquare_back.git"
//定义git的url
def git_auth="fc529390-8711-4c3a-894e-fd77845bf5e4"
//镜像标签
def tag="latest"
//harbor的url地址
def harbor_url="192.168.23.204:85"
//镜像仓库名
def harbor_name="tensquare"
//harbor凭证
def harbor_auth="2fce7f44-a3d6-4545-994b-39635e300a27"
node {
stage('pull code'){
checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
}
stage('check code'){
//定义SonarQubeScanner工具,要和Jenkins的全局工具配置里的一致
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 镜像上传成功"
}
}
}
再次构建,查看镜像是否上传到了指定的harbor仓库
三: 拉取镜像和发布应用
安装插件
安装插件 Publish Over SSH,可以实现远程发送Shell命令(如果没有这个插件,可能是版本需要升级或重启)
配置远程部署服务器
将公钥从Jenkins服务器拷贝到生成服务器
复制 ssh-copy-id 192.168.23.205
系统配置---->Publish over SSH--->Add
修改Jenkinsfile构建脚本,生成远程调用模板
显示用片段生成器,选择sshPublisher:Send build artifacts over SSH
修改Jenkinsfile文件,并提交
复制//定义git凭证
def git_url="git@192.168.23.201:my_group/tensquare_back.git"
//定义git的url
def git_auth="fc529390-8711-4c3a-894e-fd77845bf5e4"
//镜像标签
def tag="latest"
//harbor的url地址
def harbor_url="192.168.23.204:85"
//镜像仓库名
def harbor_name="tensquare"
//harbor凭证
def harbor_auth="2fce7f44-a3d6-4545-994b-39635e300a27"
node {
stage('pull code'){
checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
}
stage('check code'){
//定义SonarQubeScanner工具,要和Jenkins的全局工具配置里的一致
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)])
}
}
为项目添加端口变化
项目配置界面--->Add Parameter---->String Parameter
部署脚本deploy.sh
再生产服务器上,创建目录,放入脚本
复制mkdir /opt/jenkins_shell
cd /opt/jenkins_shell/
脚本内容如下,要修改harbor的用户名和密码为自己的账号
复制! /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,这里的用户名 和 密码修改为自己harbor 的账号
docker login -u tom -p Abcd1234 $harbor_url
# 下载镜像
docker pull $imageName
# 启动容器
docker run -di -p $port:$port $imageName
echo "容器启动成功"
给脚本添加执行权限
复制chmod +x deploy.sh
在Jenkins服务器上的mysql 数据库,创建库,导入表
将两个sql 文件上传到Jenkins数据库
登录数据库,创建数据库tensquare_gathering ,tensquare_user
复制mysql -uroot -pabc123
create database tensquare_gathering;
create database tensquare_user;
grant all privileges on *.* to 'root'@'%' identified by 'abc123' with grant option;
flush privileges;
导入表
复制 use tensquare_user;
source /root/tensquare_user.sql
use tensquare_gathering;
source /root/tensquare_gathering.sql
idea 里修改每个微服务的application.yml文件,并提交
eureka
复制# 单机版
server:
port: 10086
#基本服务器信息
spring:
application:
name: eureka-server #服务ID
#enreka服务器配置
eureka:
client:
fetch-registry: false #单机版关闭enreka相互注册
register-with-eureka: false
service-url:
defaultZone: http://192.168.23.205:${server.port}/eureka #暴露eureka服务访问地址
server:
enable-self-preservation: false #关闭自我保护
zuul
复制server:
port: 10020 # 端口
# 基本服务信息
spring:
application:
name: tensquare-zuul # 服务ID
# Eureka配置
eureka:
client:
service-url:
defaultZone: http://192.168.23.205:10086/eureka # Eureka访问地址
instance:
prefer-ip-address: true
# 修改ribbon的超时时间
ribbon:
ConnectTimeout: 1500 # 连接超时时间,默认500ms
ReadTimeout: 3000 # 请求超时时间,默认1000ms
# 修改hystrix的熔断超时时间
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMillisecond: 2000 # 熔断超时时长,默认1000ms
# 网关路由配置
zuul:
routes:
admin:
path: /admin/**
serviceId: tensquare-admin-service
gathering:
path: /gathering/**
serviceId: tensquare-gathering
# jwt参数
jwt:
config:
key: itcast
ttl: 1800000
admin_service
复制server:
port: 9001
spring:
application:
name: tensquare-admin-service #指定服务名
datasource:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://192.168.23.202:3306/tensquare_user?characterEncoding=UTF8
username: root
password: abc123
jpa:
database: mysql
show-sql: true
#Eureka配置
eureka:
client:
service-url:
defaultZone: http://192.168.23.205:10086/eureka
instance:
lease-renewal-interval-in-seconds: 5 # 每隔5秒发送一次心跳
lease-expiration-duration-in-seconds: 10 # 10秒不发送就过期
prefer-ip-address: true
# jwt参数
jwt:
config:
key: itcast
ttl: 1800000
gathering
复制server:
port: 9002
spring:
application:
name: tensquare-gathering #指定服务名
datasource:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://192.168.23.202:3306/tensquare_gathering?characterEncoding=UTF8
username: root
password: abc123
jpa:
database: mysql
show-sql: true
#Eureka客户端配置
eureka:
client:
service-url:
defaultZone: http://192.168.23.205:10086/eureka
instance:
lease-renewal-interval-in-seconds: 5 # 每隔5秒发送一次心跳
lease-expiration-duration-in-seconds: 10 # 10秒不发送就过期
prefer-ip-address: true
构建项目
Jenkins里,构建微服务。eureka:10086; zuul:10020; admin_service:9001; gathering:9002
构建完毕后,在生产服务器上,可以到四个微服务的镜像,以及容器,并且可以访问eureka服务
访问生产服务器的10086端口,可以看到,其他三个微服务都已经在eureka上注册
如果eureka微服务只能本地访问,而其他服务器无法访问,可能是因为ip转发没有打开
复制vim /etc/sysctl.conf
------
#在文件末尾添加
net.ipv4.ip_forward=1
-------
#载入配置,重启网卡
sysctl -p
systemctl restart network
windows里使用postman测试
先使用post方式,连接生产服务器的10020,获取到token后,复制
在使用get方式,访问生产服务器的10020
在headers配置里,key:token ,value:复制的token令牌
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现