Jenkins file一行代码部署.NET程序到K8S

Jenkins file一行代码部署.NET程序

2cb0066fa2d19cea8928620a9ac25fc0.png


什么是Jenkins共享库

随着微服务的增多,每个项目的都需要pipline文件,这样的话Pipeline代码冗余度高,并且pipeline的功能越来越复杂。

jenkins可以使用Shared Lib,将一些公共的pipeline抽象做成模块代码,在各种项目pipeline之间复用,以减少冗余。

共享库目录结构

共享库根目录
|-- vars|-- test1.groovy
|-- src|-- test2.groovy
|-- resources

vars: 依赖于Jenkins运行环境的Groovy脚本。其中的Groovy脚本被称之为全局变量
src: 标准的Java源码目录结构,其中的Groovy脚本被称为类库(Library class)。
resources: 目录允许从外部库中使用 libraryResource 步骤来加载有关的非 Groovy 文件。

引用共享库的方式

#!/usr/bin/env groovy// 引用默认配置的共享库
@Library('demo-shared-library') _// 引用指定分支、tag的共享库代码
@Library('demo-shared-library@1.0') _// 引用多个指定分支tag的共享库
@Library('demo-shared-library@$Branch/Tag','demo-shared-library-test@$Branch/Tag') _@Library('utils') import org.foo.Utilities@Library('utils') import static org.foo.Utilities.*

vars下的全局变量

/vars下的全局变量必须以全小写或驼峰(camelCased)
/vars/*.groovy若实现call()方法,直接引用时默认执行其中的方法

实现一行代码部署.NET程序到K8S

安装Jenkins Master

# master
docker run --name jenkins-blueocean -u root --privileged -d -p 8080:8080 -p 50000:50000 -v D:/architecture/jenkins/data:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock jenkinsci/blueocean # 访问:http://ip:8080/
# jenkins密码,查看容器日志: 7285ced325a24483bfdaab227415fdac
# 安装推荐插件

安装Jenkins Agent

Manage Jenkins -> Manage Nodes and Clouds -> New Node

  • Name: agent2/agent3

  • Labels: agentnode

  • Launch method: Launch agent by connecting it to the master

Build Agent Docker Image

# slave
# Dockerfile
FROM jenkins/inbound-agent:latest
USER rootRUN apt-get update
RUN apt-get -y install ca-certificates curl gnupg lsb-release
RUN curl -fsSL https://get.docker.com -o get-docker.sh
RUN sh get-docker.shRUN curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
RUN install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
RUN kubectl version --clientENV JMETER_VERSION=5.4.1
ENV JMETER_HOME=/jmeter/apache-jmeter-${JMETER_VERSION}
ENV JMETER_PATH=${JMETER_HOME}/bin:${PATH}
ENV PATH=${JMETER_HOME}/bin:${PATH}RUN mkdir /jmeter
COPY apache-jmeter-${JMETER_VERSION}.tgz /jmeter
RUN cd /jmeter && tar xvf apache-jmeter-${JMETER_VERSION}.tgz #其中tgz文件请去官网下载
RUN sed -i 's/#jmeter.save.saveservice.output_format=csv/jmeter.save.saveservice.output_format=xml/g'  /jmeter/apache-jmeter-5.4.1/bin/jmeter.propertiesdocker build -t chesterjenkinsagent .
docker tag chesterjenkinsagent:latest 192.168.43.95/jenkins/chesterjenkinsagent:v1
docker login --username=admin --password=123456  192.168.43.95
docker push 192.168.43.95/jenkins/chesterjenkinsagent:v1

运行Agent,其中的密钥通过jenkins的agent信息获取

5f885bf578559f0936c89f21a3a19356.png

# agent4
docker run  -v /var/run/docker.sock:/var/run/docker.sock --name agent4  -d --init 192.168.43.95/jenkins/chesterjenkinsagent:v1 -url http://192.168.43.94:8080   1e84c896dbffc0c325587eedb6301ab0ae66d3f4b49c4628dbb05714e382d7a2 agent4

新增K8S凭据

  • 将k8s集群的配置文件导出 ~/.kube/config

  •  Mange Jenkins -> Manage Credentials -> Add Credentials -> Secret File

  • 选择导出的kubeconfig,设置id为kubeconfig

新增Harbor凭据

  • Mange Jenkins -> Manage Credentials -> Add Credentials -> Username with password

  • 输入Harbor的用户名密码

新增Gitee凭据

  • Mange Jenkins -> Manage Credentials -> Add Credentials -> Username with password

  • 输入Gitee的用户名密码

安装插件

Manage Jenkins -> Manage Plugins -> Search "Performance" -> install

管理共享库

Manage Jenkins -> Configure System -> Global Pipeline Libraries,其中的git地址是共享库的地址

1a84e82ff3dd196fc7942a5d282f1f98.png

共享库中新增以下代码

vars/run.groovy

#!/usr/bin/env groovydef call(String nameSpaceName, String serviceName, String servicePath, String servicePort, String nodePort, Map envInfo) {def devBranch = envInfo['dev']def prodBranch = envInfo['prod']pipeline {agent {label 'agentnode'}environment {DEV_MY_KUBECONFIG = credentials('kubeconfig')PROD_MY_KUBECONFIG = credentials('kubeconfig')HARBOR = credentials('harbor')}stages {stage('Dev - GitPull') {steps {deleteDir()gitCheckOut devBranch, env.GIT_URL}post {success {script {echo 'pull done'}}}}stage('Dev - DockerBuild') {steps {dockerImageBuild serviceName, "${servicePath}Dockerfile"}}stage('Dev - DockerTag') {steps {dockerTag serviceName, 'dev'}}stage('Dev - DockerLogin') {steps {dockerLogin 'dev'}}stage('Dev - DockerPush') {steps {dockerPush serviceName, 'dev'}}stage('Dev - GenerateHarborSecretYAML') {steps {harborSecret nameSpaceName, serviceName, 'dev'}}stage('Dev - GenerateK8SYAML') {steps {k8sGenerateYaml nameSpaceName, serviceName, servicePath, 'dev', servicePort, nodePort}}stage('Dev - DeployToK8S') {steps {k8sDeploy servicePath, 'dev'}}stage('Dev - CheckDeployStatus') {steps {k8sCheckDeployStatus nameSpaceName, serviceName, 'dev'}}stage('Dev - Jmeter Test') {steps {jmeterTest servicePath}}stage('DeployToProd?') {steps {input '部署生产?'}}stage('Prod - GitPull') {steps {gitCheckOut prodBranch, env.GIT_URL}}stage('Prod - DockerBuild') {steps {dockerImageBuild serviceName, "${servicePath}Dockerfile"}}stage('Prod - DockerTag') {steps {dockerTag serviceName, 'prod'}}stage('Prod - DockerLogin') {steps {dockerLogin 'prod'}}stage('Prod - DockerPush') {steps {dockerPush serviceName, 'prod'}}stage('Prod - GenerateHarborSecretYAML') {steps {harborSecret nameSpaceName, serviceName, 'prod'}}stage('Prod - GenerateK8SYAML') {steps {k8sGenerateYaml nameSpaceName, serviceName, servicePath, 'prod', servicePort, nodePort}}stage('Prod - DeployToK8S') {steps {k8sDeploy servicePath, 'prod'}}stage('Prod - CheckDeployStatus') {steps {k8sCheckDeployStatus nameSpaceName, serviceName, 'prod'}}}}
}

vars/dockerImageBuild.groovy

#!/usr/bin/env groovydef call(String serviceName, String dockerfilePath) {echo "serviceName:${serviceName} dockerfilePath:${dockerfilePath}"sh "docker build -t ${serviceName} -f  ${dockerfilePath} ."
}

vars/dockerLogin.groovy

#!/usr/bin/env groovydef call(String envName) {sh 'docker login --username=$HARBOR_USR --password=$HARBOR_PSW  192.168.43.95'
}

vars/dockerPush.groovy

#!/usr/bin/env groovydef call(String serviceName,String envName) {sh "docker push 192.168.43.95/dapr/${serviceName}:${envName}-${BUILD_NUMBER}"
}

vars/dockerTag.groovy

#!/usr/bin/env groovydef call(String serviceName, String envName) {sh "docker tag ${serviceName}:latest 192.168.43.95/dapr/${serviceName}:${envName}-${BUILD_NUMBER}"
}

vars/gitCheckOut.groovy

#!/usr/bin/env groovydef call(String branchName, String gitUrl) {echo "branchName:${branchName} gitUrl:${gitUrl}"checkout([$class: 'GitSCM', branches: [[name: branchName]], extensions: [], userRemoteConfigs: [[credentialsId: 'gitee', url: gitUrl]]])
}

vars/harborSecret.groovy

def call(String namespaceName, String serviceName, String envName) {dir('harborsecret') {checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: 'gitee', url: 'https://gitee.com/chesterdotchen/jenkins-demo-secrets.git']]])sh """sed -i 's/{{ServiceName}}/${serviceName}/g'  secrets.yaml"""sh """sed -i 's/{{NameSpaceName}}/${namespaceName}/g'  secrets.yaml"""if (envName == 'dev') {sh("kubectl --kubeconfig  ${DEV_MY_KUBECONFIG} apply -f secrets.yaml")}if (envName == 'prod') {sh("kubectl --kubeconfig  ${PROD_MY_KUBECONFIG} apply -f secrets.yaml")}}
}

vars/jmeterTest.groovy

#!/usr/bin/env groovydef call(String servicePath) {sh "jmeter -j jmeter.save.saveservice.output_format=xml -n -t ${servicePath}jmeter.jmx -l ${servicePath}jmeter.report.jtl"sh "cp ${servicePath}jmeter.report.jtl ${servicePath}jmeter.report.${BUILD_NUMBER}.jtl"perfReport errorFailedThreshold:5, sourceDataFiles:"${servicePath}jmeter.report.jtl"sh "cat ${servicePath}jmeter.report.${BUILD_NUMBER}.jtl"sh """#!/bin/shgrep '<failure>true</failure>' ${servicePath}jmeter.report.${BUILD_NUMBER}.jtlif [ \$? = 0 ]thenexit 1elseexit 0fi"""
}

vars/k8sCheckDeployStatus.groovy

#!/usr/bin/env groovydef call(String nameSpaceName, String serviceName, String envName) {if (envName == 'dev') {sh("""ATTEMPTS=0ROLLOUT_STATUS_CMD='kubectl --kubeconfig  ${DEV_MY_KUBECONFIG} rollout status deployment/${serviceName}  -n ${nameSpaceName}-ns'until \$ROLLOUT_STATUS_CMD || [ \$ATTEMPTS -eq 60 ]; do\$ROLLOUT_STATUS_CMDATTEMPTS=\$((attempts + 1))sleep 10done""")}if (envName == 'prod') {sh("""ATTEMPTS=0ROLLOUT_STATUS_CMD='kubectl --kubeconfig  ${PROD_MY_KUBECONFIG} rollout status deployment/${serviceName}  -n ${nameSpaceName}-ns'until \$ROLLOUT_STATUS_CMD || [ \$ATTEMPTS -eq 60 ]; do\$ROLLOUT_STATUS_CMDATTEMPTS=\$((attempts + 1))sleep 10done""")}
}

vars/k8sDeploy.groovy

#!/usr/bin/env groovydef call(String servicePath, String envName) {if (envName == 'dev') {sh("kubectl --kubeconfig  ${DEV_MY_KUBECONFIG} apply -f ${servicePath}deployment.yaml")}if (envName == 'prod') {sh("kubectl --kubeconfig  ${PROD_MY_KUBECONFIG} apply -f ${servicePath}deployment.yaml")}
}

vars/k8sGenerateYaml.groovy

#!/usr/bin/env groovydef call(String namespaceName, String serviceName, String servicePath, String envName, String servicePort, String nodePort) {sh """sed "s/{{tagversion}}/${envName}-${BUILD_NUMBER}/g"  ${servicePath}deployment.yaml.tpl > ${servicePath}deployment.yaml """sh """sed -i 's/{{ServiceName}}/${serviceName}/g'  ${servicePath}deployment.yaml"""sh """sed -i 's/{{ServicePort}}/${servicePort}/g'  ${servicePath}deployment.yaml"""sh """sed -i 's/{{NodePort}}/${nodePort}/g'  ${servicePath}deployment.yaml"""sh """sed -i 's/{{NameSpaceName}}/${namespaceName}/g'  ${servicePath}deployment.yaml"""
}

jenkins-demo-secrets中代码如下

apiVersion: v1
kind: Namespace
metadata:name: {{NameSpaceName}}-ns---
apiVersion: v1
kind: Secret
metadata:name: harbor-keynamespace: {{NameSpaceName}}-ns
type: kubernetes.io/dockerconfigjson
data:.dockerconfigjson: ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjQzLjk1IjogewoJCQkiYXV0aCI6ICJZV1J0YVc0Nk1USXpORFUyIgoJCX0sCgkJInJlZ2lzdHJ5LmNuLWJlaWppbmcuYWxpeXVuY3MuY29tIjogewoJCQkiYXV0aCI6ICI2Wm1JNUxpQTU0dXVPbU5vWlc1NWFYTm9hVEV5TXc9PSIKCQl9Cgl9Cn0=

dockerconfigjson可通过以下方式获取

docker login --username=admin --password=123456 192.168.43.95
cat ~/.docker/config.json | base64

Jenkinsfile中引用共享库

项目库中需要提前编写好Dockerfile,Jenkinsfile,deployment.yaml.tpl,jmeter.jmx

768dfb746e5bc344251525e49a68d125.png

Dockerfile

#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
EXPOSE 5001FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["FrontEnd/FrontEnd.csproj", "FrontEnd/"]
COPY ["Common/Common.csproj", "Common/"]
RUN dotnet restore "FrontEnd/FrontEnd.csproj"
COPY . .
WORKDIR "/src/FrontEnd"
RUN dotnet build "FrontEnd.csproj" -c Release -o /app/buildFROM build AS publish
RUN dotnet publish "FrontEnd.csproj" -c Release -o /app/publishFROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "FrontEnd.dll"]

Jenkinsfile

#!/usr/bin/env groovy@Library('share@master') _run 'daprtest', 'frontend', './FrontEnd/', '5001', '31111', ['dev':'*/master', 'prod':'*/master']

deployment.yaml.tpl

apiVersion: v1
kind: Namespace
metadata:name: {{NameSpaceName}}-ns---
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:name: statestorenamespace: {{NameSpaceName}}-ns
spec:type: state.redisversion: v1metadata:- name: redisHostvalue: 192.168.43.102:6379- name: redisPasswordvalue: "123456"- name: actorStateStorevalue: "true"---
apiVersion: apps/v1
kind: Deployment
metadata:name: {{ServiceName}}namespace: {{NameSpaceName}}-nslabels:app: {{ServiceName}}
spec:replicas: 1selector:matchLabels:app: {{ServiceName}}template:metadata:namespace: {{NameSpaceName}}-nslabels:app: {{ServiceName}}annotations:dapr.io/enabled: "true"dapr.io/app-id: "{{ServiceName}}"dapr.io/app-port: "{{ServicePort}}"spec:imagePullSecrets:- name: harbor-keycontainers:- name: {{ServiceName}}image: 192.168.43.95/dapr/{{ServiceName}}:{{tagversion}}ports:- containerPort: {{ServicePort}}imagePullPolicy: Always---
apiVersion: v1
kind: Service
metadata:namespace: {{NameSpaceName}}-nsname: {{ServiceName}}-svc
spec:type: NodePortselector:app: {{ServiceName}}ports:- port: {{ServicePort}}targetPort: {{ServicePort}}nodePort: {{NodePort}}

jmter.jmx则根据需要自行编写

56643c704cd3e75c80ed1af1181d0181.png

新建pipline

其中的URL指向自己项目的git地址

3bc05eb7b4cec34fe0cafd4a84b1d5c0.png

构建pipline

7a13d4635865880ac028c951c12291c3.png

至此,我们已经完成了Jenkinsfile中一行代码部署我们的项目,如果有新的service,在编写好Dockerfile,deployment.yaml.tpl(保持一致),jmeter.jmx的前提下,我们只需要Jenkinsfile中通过共享库引用run方法即可

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/295896.shtml

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

相关文章

Android之SharedPreferences详解

获取SharedPreferences的两种方式: 1 调用Context对象的getSharedPreferences()方法 2 调用Activity对象的getPreferences()方法 两种方式的区别: 调用Context对象的getSharedPreferences()方法获得的SharedPreferences对象可以被同一应用程序下的其他 组件共享. 调用Activity对…

吵架后女生和男生的夜晚!所有男生都这样吗?

1 猫&#xff1a;哪个瓜娃子开的灯&#xff1f;&#xff01;2 神回复在哪里3 舔舔舔舔舔&#xff0c;被发现了&#xff01;4 喵喵&#xff1a;你当我傻吗&#xff1f;5 今晚可不可以到你家吃饭6 吵架后女生的夜晚vs吵架后男生的夜晚太真实了7 打游戏时候 对方队友和我方…

MySQL大批量数据插入

公司有一个项目&#xff0c;需要频繁的插入数据到MySQL数据库中&#xff0c;设计目标要求能支持平均每秒插入1000条数据以上。目前功能已经实现&#xff0c;不过一做压力测试&#xff0c;发现数据库成为瓶颈&#xff0c;每秒仅能插入100多条数据&#xff0c;远远达不到设计目标…

项目背景介绍

Adventure 项目&#xff08;1&#xff09; 墨翟坐在办公室里&#xff0c;正和秘书 Alan 开会&#xff0c;讨论着一件让他和 Alan 都很烦心的事情。Adventure 在全球都有工厂&#xff0c;制造各种不同的产品。作为制造部门的负责人&#xff0c;墨翟需要每个月了解各个工厂的运行…

canvas-a13prototype.html

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>扩展方法</title> </head> <body><canvas id"canvas" style"margin:0 auto;border:1px #ddd solid">The…

不想升Win11?Win10新版马上到!

微软正式宣布 Windows 10 操作系统的下一个功能更新&#xff1a;Windows 10 版本 21H2。微软表示&#xff1a;虽然我们对下一代 Windows 11 感到兴奋&#xff0c;但也专注于支持 Windows 10 上超过 13 亿台活跃设备。当人们继续在混合和远程环境中工作、学习和娱乐时&#xff0…

Android之layout属性介绍

android:id 为控件指定相应的ID android:text 指定控件当中显示的文字&#xff0c;需要注意的是&#xff0c;这里尽量使用strings.xml文件当中的字符串 android:gravity 指定View组件的对齐方式&#xff0c;比如说居中&#xff0c;居右等位置 这里指的是控件中的文本位置并不是…

娱乐项目和女朋友哪个重要?

1 这招风卷残云我只演示一遍&#xff0c;看好了2 摄影师给男生拍照VS给女生拍照3 这个视力表是永远不会近视的4 娱乐项目和女朋友哪个重要&#xff1f;小伙子你飘了啊5 最怕空气突然安静6 “灵魂六问”7 原来是这样周末愉快↓ ↓ ↓

深度解析windows调试技术之一 [抓取user mode dump文件的几重境界]

抓取user mode dump文件的几重境界 导读记得去年对一些朋友说过要写一些调试技术相关的文章&#xff0c;但是后来出于种种原因吧&#xff0c;还是没写成。最近终于有些时间&#xff0c;希望可以把这些文章补上。对于软件开发而言&#xff0c;调试无疑是最重要的部分之一&#x…

The 'Microsoft.Jet.OLEDB.4.0' provider is not registered on the local machine.

64位系统上编译运行32位程序时如果要访问Access数据库会出现The Microsoft.Jet.OLEDB.4.0 provider is not registered on the local machine错误&#xff0c; 解决方法是&#xff1a;打开项目配置管理器&#xff08;Configuration Manager&#xff09;&#xff0c;将项目的运行…

html语言简单,简单的html语言计算器

《简单的html语言计算器》由会员分享&#xff0c;可在线阅读&#xff0c;更多相关《简单的html语言计算器(3页珍藏版)》请在人人文库网上搜索。1、简单的计算器源码如图&#xff1a;代码input.MyButton font-size:16px; background-color: #FF0; width:38px; height:28px;borde…

如何判断当前请求的是健康检查API

前言为了性能监控的目的&#xff0c;我们使用了Middleware记录所有请求的Log。实现代码如下&#xff1a;public class RequestLoggingMiddleware {...public async Task Invoke(HttpContext context){try{await _next(context);}finally{//Log}} }同时&#xff0c;我们在服务中…

Androidz之clickable

在android Button的xml文件属性中有这麽一个属性标签&#xff1a; [html] view plaincopyprint? android:clickable 该标签&#xff08;继承自View的xml属性&#xff09;的值必须是boolean值&#xff0c;即true、false。该标签目的是设置button是否可以被点击。 于是&#x…

这些高校竟因名字太“坑爹”被误会为三本?盘点九所实力强劲但被名字耽误的大学...

全世界只有3.14 % 的人关注了爆炸吧知识有这样一个段子&#xff1a;西北某地一学生&#xff0c;志存高远&#xff0c;矢志从医。首次高考考入泸州医学院&#xff0c;到校后发现不理想&#xff0c;果断返乡复读。一年后成功考入四川医科大学&#xff0c;到校后傻眼了&#xff0c…

VC编程实现IE风格的界面

使用过IE浏览器的朋友都知道IE界面上的扁平工具条、地址栏&#xff0c;扁平工具栏上的按钮正常状态下为扁平态&#xff0c;按钮上的图像为灰色&#xff0c;当鼠标放在按钮上时&#xff0c;按钮突 起&#xff08;这种状态称为手柄&#xff09;&#xff0c;并且其上的图像变得鲜艳…

【全】.net core平台单元/集成测试结果、覆盖率、圈复杂度到可视化HTML报告之路...

.net core 平台的测试框架有好几个可供选择&#xff0c;内置的MSTest框架、NUnit框架以及强大好用的xUnit框架&#xff0c;依托宇宙最强的编辑器Visual Studio&#xff0c;可以开展非常友好的测试以及快乐的展示测试的结果。如果仅限于此&#xff0c;那么这篇文章对你来说就是多…

广义积分1

这几天&#xff0c;突然下了比较大的雪。打算翻出一道积分习题做做。 $$\int_{-\infty}^{\infty}\frac{\cos x}{x^2a^2}\text{d}x$$ 其中$a>0$ 不知道这个积分是从什么问题中被提出来的(会不会是几百年前某些人研究某个东西得到的&#xff1f;)。打算用Residue formula来算,…

哪种HTML列表会自动编号,HTML列表的种类

HTML 支持有序、无序和定义列表无序列表无序列表是一个项目的列表&#xff0c;此列项目使用粗体圆点(典型的小黑圆圈)进行标记。无序列表始于 标签。每个列表项始于 。(推荐学习&#xff1a;HTML入门教程)CoffeeMilk浏览器显示如下&#xff1a;CoffeeMilk列表项内部可以使用段落…

Android之AsyncTask异步任务详解总结

Android 多线程----AsyncTask异步任务详解 【正文】 本文将讲解一下Android的多线程的知识&#xff0c;以及如何通过AsyncTask机制来实现线程之间的通信。 一、Android当中的多线程&#xff1a; 在Android当中&#xff0c;当一个应用程序的组件启动的时候&#xff0c;并且没有其…

docker源码_使用docker、Jenkins、gitlee、springboot、搭建个人博客网站 并实现CI/CD 外加机器人提醒...

看朱成碧思纷纷&#xff0c;憔悴支离为忆君。--- barcke前言:服务器用的是云服务器买的阿里的linux、jdk1.8、docker服务端使用的为阿里的docker镜像仓库、mysql使用5.7版本的、redis使用最新版即可、文件服务使用的阿里的oss.项目采用jib推送docker镜像.附录: git源码地址—-h…