wordpress调用文章标题/班级优化大师网页版
Jenkins+Docker+SpringCloud微服务持续集成
- Jenkins+Docker+SpringCloud持续集成流程说明
- SpringCloud微服务源码概述
- 本地运行微服务
- 本地部署微服务
- Docker安装和Dockerfile制作微服务镜像
- Harbor镜像仓库安装及使用
- 在Harbor创建用户和项目
- 上传镜像到Harbor
- 从Harbor下载镜像
- 微服务持续集成
- 项目代码上传到Gitlab
- 从Gitlab拉取项目源码
- 提交到SonarQube代码审查
- 微服务打包构建
- 使用Dockerfile编译生成镜像
- 上传到Harbor镜像仓库
- 拉取镜像和发布应用
- 配置远程部署服务器
- 编写远程部署脚本
- 编写Jenkins流水线脚本
- 部署和测试所有微服务
- 部署前端静态web网站
Jenkins+Docker+SpringCloud持续集成流程说明
- 开发人员每天把代码提交到Gitlab代码仓库
- Jenkins从Gitlab中拉取项目源码,编译并打成Jar包,然后构建成Docker镜像,将镜像上传到Harbor私有仓库
- Jenkins发送SSH远程命令,让生产部署服务器到Harbor私有仓库拉取镜像到本地,然后创建容器
- 最后,用户可以访问到容器
服务器列表
服务器名称 | IP地址 | 安装软件 | 硬件配置 | 系统 |
---|---|---|---|---|
代码托管服务器 | 192.168.100.240 | Gitlab-12.9.9 | 2核4G | CentOS Linux release 7.5.1804 |
持续集成服务器 | 192.168.100.241 | Jenkins 2.401.2,JDK 11,JDK 1.8,Maven 3.8.8,Git 1.8.3.1,Docker 20.10.24-ce | 2核4G | CentOS Linux release 7.5.1804 |
代码审查服务器 | 192.168.100.242 | mysql 5.7.43,sonarqube 6.7.7 | 1核2G | CentOS Linux release 7.5.1804 |
Harbor仓库服务器 | 192.168.100.251 | Docker 20.10.24-ce,Harbor 1.9.2 | 1核2G | CentOS Linux release 7.5.1804 |
生产部署服务器 | 192.168.100.252 | Docker 20.10.24-ce | 1核2G | CentOS Linux release 7.5.1804 |
SpringCloud微服务源码概述
项目架构:前后端分离
后端技术栈:SpringBoot+SpringCloud+SpringDataJpa(Spring全家桶)
微服务项目结构:
- 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网关
开启权限中心
开启微服务
刷新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具有很多优势:
- 提供分层传输机制,优化网络传输 Docker镜像是是分层的,而如果每次传输都使用全量文件(所以用FTP的方式并不适合),显然不经济。必须提供识别分层传输的机制,以层的UUID为标识,确定传输的对象。
- 提供WEB界面,优化用户体验 只用镜像的名字来进行上传下载显然很不方便,需要有一个用户界面可以支持登陆、搜索功能,包括区分公有、私有镜像。
- 支持水平扩展集群 当有用户对镜像的上传下载操作集中在某服务器,需要对相应的访问压力作分解。
- 良好的安全机制,企业中的开发团队有很多不同的职位,对于不同的职位人员,分配不同的权限,具有更好的安全性。
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的项目分为公开和私有的:
- 公开项目:所有用户都可以访问,通常存放公共的镜像,默认有一个library公开项目。
- 私有项目:只有授权用户才可以访问,通常存放项目本身的镜像。
我们可以为微服务项目创建一个新的项目:
创建用户
给私有项目分配用户
进入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.projectKey
和sonar.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_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><!-- 在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微服务持续集成就搭建完成!剩余还需要对其优化!
相关文章:

Jenkins+Docker+SpringCloud微服务持续集成
JenkinsDockerSpringCloud微服务持续集成 JenkinsDockerSpringCloud持续集成流程说明SpringCloud微服务源码概述本地运行微服务本地部署微服务 Docker安装和Dockerfile制作微服务镜像Harbor镜像仓库安装及使用在Harbor创建用户和项目上传镜像到Harbor从Harbor下载镜像 微服务持…...

系统架构设计师-系统可靠性分析与设计
目录 一、可靠性相关基本概念 二、可靠性指标 1、串联系统与并联系统可靠性指标计算 2、混合系统 三、可靠性设计 1、影响软件可靠性的主要因素: 2、增加可靠性的解决方案 2.1 避错技术 2.2 降低复杂度设计 2.3 检错技术 2.4 容错技术 3、双机容错 一、可靠性相关…...

Linux(CentOS7)搭建达梦数据库
参考官方文档 本文记录一下达梦数据库的安装步骤,在安装的过程中出现了一些问题,进行了处理。 文章目录 安装前准备数据库安装命令行安装图形化安装 配置实例注册服务启动、停止数据库达梦数据库卸载 安装前准备 用户在安装 DM 数据库之前需要检查或修…...

[杂谈]-国产MCU竞争力浅析
[杂谈]-国产MCU竞争力浅析 文章目录 [杂谈]-国产MCU竞争力浅析1、研发方面2、技术方面3、市场方面4、应用方面5、生态方面6、总结 微控制器(MCU)是一种集成了微处理器、存储器、输入/输出接口和其他外设的单片电路,广泛应用于各种电子产品和系…...

4.1、Flink任务怎样读取集合中的数据
1、API说明 非并行数据源: def fromElements[T: TypeInformation](data: T*): DataStream[T] def fromCollection[T: TypeInformation](data: Seq[T]): DataStream[T] def fromCollection[T: TypeInformation] (data: Iterator[T]): Data…...

JD商品详情页面+关键词搜索商品列表API接口数据,详情页面数据返回值说明
作为一个工作助手,我无法直接为您提供实时的京东商品详情。您可以通过访问京东官方网站或使用API接口来查看商品的详细信息。每个商品的详情页面通常会包括以下内容: 1. 商品标题:商品的名称和简要描述。 2. 价格信息:包括原价、…...

Electron v26.0.0-beta.11 发布,跨平台桌面应用开发工具
Electron是一款跨平台桌面应用开发工具,它基于Web技术,使用HTML、CSS和JavaScript来构建应用程序。它能够让开发者使用熟悉的Web开发技术来创建强大的桌面应用,并且可以运行在Windows、macOS和Linux等多个操作系统上。 一、Electron的特点 跨平台:Electron可以将Web技术转…...

提高办案效率:公检系统引入自动校对技术
引入自动校对技术到公检系统中可以有效提高办案效率。自动校对技术结合公检系统的特点,可以在以下方面提高办案效率: 1.节省时间:自动校对技术可以快速检测和修正法律文书中的语法、拼写和标点符号等错误。与手动校对相比,自动校对…...

iptables 清空
清空 iptables中所有策略。 -Z: 重置计数器 -F:删除所有规则(flush) -X:删除所有自定义的链 规则清理和重建如下: iptables -Z iptables -t nat -F iptables -t nat -X iptables -t nat -P PREROUTING A…...

网络安全(黑客)零基础入门
导语 什么是 Web 安全?我又该如何入门学习它呢?学习过程中又应注意哪些问题呢?... 或许你的心中有着这样的疑问、不过别着急,本文会为你一一解答这些问题。 正文 定义 Web 安全,顾名思义便是由保障 Web 应用能够持续…...
Al Go: 蒙特卡洛树搜索(MCTS)简介
目录 1. 前言 1.1 Minimax 1.2 剪枝 1.3 蒙特卡洛树搜索 1.4 为什么随机走子会可行呢? 2. vanilla Monte Carlo tree search 3. UCT-based trade-off between exploitation and exploration 4. MCTS基本算法流程 5. Efficiency Through Expert Policies 6…...

Client-go操作Deployment
在工作中需要对kubernetes进行自定义资源的开发,操作K8s的资源肯定是必不可少的。K8s原生语言是用Go编写的,所以在CRD中使用client-go来操作资源。本次介绍一下使用client-go来操作Deployment。 1. 创建main函数 func main() {homePath : homedir.Home…...

设计模式——单例模式(懒汉和饿汉)
单例模式 一、概念 单例模式是一种对象创建型模式,使用单例模式,可以保证为一个类只生成唯一的实例对象。也就是说,在整个程序空间中,该类只存在一个实例对象。一个类只能有一个实例在生活中是很常见的,比如打印机程…...

详解——Vue3递归函数功能
在 Vue 3 中,递归函数是一种在组件中调用自身的技术。递归函数在解决树状数据结构、无限级分类、嵌套组件等情况下非常有用。以下是一个示例,展示如何在 Vue 3 中实现递归函数的功能、代码和原理: 1. 创建递归组件: 首先&#x…...

【VSCode】查看二进制文件
1.安装插件Hex Editor 2.打开二进制文件 3.执行Hex Editor命令...

C#设计模式之观察者模式
题目:假设你正在开发一个简单的新闻发布系统,该系统允许用户订阅不同的新闻频道,并在有新闻发布时向订阅者发送通知。使用观察者模式设计和实现该系统。观察者模式的相关概念和定义: 观察者模式是一种行为设计模式,它定…...

小红书攻略:爆款引流,如何在激烈竞争中脱颖而出?
小红书(RED)作为国内最具影响力的社交电商平台之一,是很多品牌运营者的首选之一。然而,在小红书的激烈竞争中,如何快速引流、吸引关注,成为了品牌运营者面临的挑战。本篇文章一秒推小编将为您介绍小红书运营…...

Ubuntu中的安装卸载及删除方法
说明:由于图形化界面方法(如Add/Remove... 和Synaptic Package Manageer)比较简单,所以这里主要总结在终端通过命令行方式进行的软件包安装、卸载和删除的方法。 一、Ubuntu中软件安装方法 1、APT方式 (1࿰…...

获取历史dokcer镜像项目,并上传gitlab,再打包镜像管理
今天遇到一个问题: 发现一个部署在Jenkins的脚本用的docker镜像是:test_project:v20191108,即这个项目是19年的一个版本,由于代码不断更新,用现在的最新代码运行该脚本,可能不能运行了,必须用19…...

【Go语言】Golang保姆级入门教程 Go初学者chapter3
Go语言 第三章 运算符 下划线“_”本身在Go中一个特殊的标识符,成为空标识符。可以代表任何其他的标识符,但是他对应的值就会被忽略 仅仅被作为站维度使用, 不能作为标识符使用 因为Go语言中没有private public 所以标记变量首字母大写代表其…...

网络防御(4)
一、结合以下问题对当天内容进行总结 1. 什么是IDS? 2. IDS和防火墙有什么不同? 3. IDS工作原理? 4. IDS的主要检测方法有哪些详细说明? 5. IDS的部署方式有哪些? 6. IDS的签名是什么意思?签名过滤器有什么…...

conda错误处理:ResolvePackageNotFound
当运行conda env create -f environment.yaml时出现"ResolvePackageNotFound"错误,这可能是由于环境配置文件中指定的依赖项无法找到或不可用。 错误消息中列出的依赖项包括pip20.3、python3.8.5和cudatoolkit11.3。 尝试以下解决方案: 更新…...

linux初学者小命令
linux初学者小命令 一.在正式学习linux命令之前需要先认识一下linux环境中命令是如何被执行的shell是一个属于linux内核的软件,在系统启动后加载进RAM(内存)内,每个用户通过终端登录系统后,就会运行。负责不间断的接收用户的输入,…...

宝尊电商短期前景堪忧,宝尊国际能否取得成功还有待验证
来源:猛兽财经 作者:猛兽财经 核心业务面临短期逆风 在2023年第一季度财报中,宝尊电商(BZUN)表示其电商业务(简称BEC)主要包括:品牌的门店运营、客户服务以及物流和供应链管理、IT和数字营销等增值服务”。…...

百川智能发布首个530亿参数闭源大模型,今年追上GPT-3.5
4月官宣创业,6月15日发布第一款7B开源模型,7月11日发布第二款13B、130亿参数开源模型。 平均保持2个月一个版本发布速度,8月8日,百川智能发布了创业以来的首个530亿参数闭源大模型——Baichuan-53B(以下简称“53B”&a…...

Redis的常用数据结构
StringListhashsetzset 1.字符串类型是Redis最基础的数据结构 使用场景: 缓存功能 Redis 作为缓存层,MySQL作为存储层,绝大部分请求的数据都是从Redis中获取。由于Redis具有支撑高并发的特性,所以缓存通常能起到加速读写和降低后端压力的作…...

深入JVM - JIT分层编译技术与日志详解
深入JVM - JIT分层编译技术与日志详解 文章目录 深入JVM - JIT分层编译技术与日志详解1. 背景简介2. JIT 编译器2.1. 客户端版本的编译器: C12.2. 服务端版本的编译器: C22.3. Graal JIT 编译器 3. 分层编译技术(Tiered Compilation)3.1. 汇聚两种编译器的优点3.2. 精准优化(Ac…...

临时文档2
java 中 IO 流分为几种? 按照流的流向分,可以分为输入流和输出流;按照操作单元划分,可以划分为字节流和字符流;按照流的角色划分为节点流和处理流。 Java Io流共涉及40多个类,这些类看上去很杂乱,但实际…...

[深度学习入门]PyTorch深度学习[数组变形、批量处理、通用函数、广播机制]
目录 一、前言二、数组变形2.1 更改数组的形状2.1.1 reshape2.1.2 resize2.1.3 T(转置)2.1.4 ravel2.1.5 flatten2.1.6 squeeze2.1.7 transpose 2.2 合并数组2.2.1 append2.1.2 concatenate2.1.3 stack 三、批量处理四、通用函数4.1 math 与 numpy 函数的性能比较4.2 循环与向量…...

男孩向妈妈发脾气爸爸言传身教
近日,广东的一个家庭中发生了一件引人深思的事情。 一个男孩因为游戏没有通关,向妈妈发脾气,结果被爸爸发现并带到一边教育。 爸爸对孩子说:“她凭什么要承受你给的负能量,凭什么你心情不好就可以对着她发脾气…...