微服务CI/CD实践-GitOps完整设计与实现
单应用与环境
多应用与环境
CI持续集成
首先,准备一个代码库:
https://github.com/DevOpsCICDCourse/microservicescicd/blob/main/microservice-demo-service-master.zip
我们来梳理一下CI流水线的步骤:
由于此次实现的代码仓库类型为单一存储库,即一个存储库存放多个服务模块代码,每个子目录为一个服务模块。 首先,我们的持续集成流水线需要能够正确获取,当前的commit是哪个服务的代码。 确定好服务,然后下载该服务的代码,进行编译打包、单元测试、代码扫描和构建镜像等步骤。
如何获取commit的服务信息?这里我们使用GitLab WebHook功能和Jenkins 的job 构建触发器对接来实现。
工作流程是:当我在Gitlab提交了代码,会通过GitLab webhook 触发Jenkins Scheduler 作业, 会将此次提交代码所产生的hook data数据信息以POST的方式传给Jenkins Job。此时Jenkins job可以编写使用Generic Hook插件获取此次POST请求传输过来的请求体Body信息。是一段JSON数据, 该job运行后编写Pipeline 解析JSON中的数据拿到所变更的服务模块信息。最后触发对应服务的CI作业进行构建。
CI-Scheduler 作业
此作业只需要开启webhook, 配置触发token(唯一性)。生成hookurl:http://jenkins.idevops.site/generic-webhook-trigger/invoke?token=microservicecicd-scheduler-CI
Jenkinsfile pipeline { agent any stages{ stage("GetData"){ steps{ script { echo "${webHookData}" data = readJSON text: "${webHookData}" println(data) env.branchName = data.ref - "refs/heads/" env.commitId = data.checkout_sha env.projectId = data.project_id commits = data["commits"] println("${env.branchName}") println("${env.commitID}") println("${env.projectId}") //env.moduleName = "service01" changeServices = [] for(commit in commits) { println(commit.id) //added for (add in commit.added) { s = add.split("/") as List if (s.size() > 1){ if (changeServices.indexOf(s[0]) == -1){ changeServices.add(s[0]) &nbs微服p; } } } //modified for (m in commit.modified) { s = m.split("/") as List // println s // println s.size() // println s[0] if (s.size() > 1){ // println changeServices.indexOf(s[0]) if (changeServices.indexOf(s[0]) == -1){ changeServices.add(s[0]) } } } //removed for (r in commit.removed) { s = r.split("/") as List  务C; println s if (s.size() > 1){ if (changeServices.indexOf(s[0]) == -1){ changeServices.add(s[0]) } } } } println(changeServices) //currentBuild.description = " Trigger by ${eventType} ${changeServices} } } } stage('DefineService') { steps { script{ println(changeServices) //服务构建顺序控制 services = ['service02', 'service01'] for (service in services){ if (changeServices.indexOf(service) != -1){ jobName = 'microservicecicd-'+service+'-service-CI' build job: jobName, wait: false, parameters: [string(name: 'branchName', value: "${env.branchName}" ), &I/nbsp; string(name: 'commitId', value: "${env.commitId}" ), string(name: 'projectId', value: "${env.projectId}" )] } } } } } } } GitLab 配置WebHook
开启webhook,配置hookurl:http://jenkins.idevops.site/generic-webhook-trigger/invoke?token=microservicecicd-scheduler-CI
CI流水线-CI作业
每个微服务创建一个CI作业,具有三个字符串参数:分支名称、commitID、项目ID。
Jenkinsfile String branchName = "${env.branchName}" String moduleName = "${JOB_NAME}".split("/")[1].split("-")[1] String srcUrl = "http://gitlab.idevops.site/microservicecicd/microservicecicd-demo-service.git" String commitId = "${env.commitId}" String projectId = "${env.projectId}" pipeline { agent { node { label "build" } } stages { stage('GetCode') { steps { script { checkout([$class: 'GitSCM', branches: [[name: "${branchName}"]], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'SparseCheckoutPaths', &nbsCDp; sparseCheckoutPaths: [[path: "${moduleName}"],[path: 'Dockerfile']]]], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'gitlab-admin-user', url: "${srcUrl}"]]]) } } } stage("Build&Test"){ steps{ script{ echo "Build..........." sh """ cd ${moduleName} mvn clean package """ } } post { always { junit "${moduleName}/target/surefire-reports/*.xml" } } } stage("SonarScan"){ steps{ script{ def sonarDate = sh returnStdout: true, script: 'date +%Y%m%d%H%M%S' &n实践bsp; sonarDate = sonarDate - " " withCredentials([string(credentialsId: 'sonar-admin-user', variable: 'sonartoken'), string(credentialsId: 'gitlab-user-token', variable: 'gitlabtoken')]) { // some block sh """ cd ${moduleName} sonar-scanner -Dsonar.projectKey=${JOB_NAME} -Dsonar.projectName=${JOB_NAME} -Dsonar.projectVersion=${sonarDate} -Dsonar.ws.timeout=30 -Dsonar.projectDescription="xxxxxxx" -Dsonar.links.homepage=http://www.baidu.com -Dsonar.sources=src -Dsonar.sourceEncoding=UTF-8 -Dsonar.java.binaries=target/classes -Dsonar.java.test.binaries=target/test-classes -Dsonar.java.surefire.report=target/surefire-reports -Dsonar.host.url="http://sonar.idevops.site" &nb-Gsp; -Dsonar.login=${sonartoken} -Dsonar.gitlab.commit_sha=${commitId} -Dsonar.gitlab.ref_name=${branchName} -Dsonar.gitlab.project_id=${projectId} -Dsonar.dynamicAnalysis=reuseReports -Dsonar.gitlab.failure_notification_mode=commit-status -Dsonar.gitlab.url=http://gitlab.idevops.site -Dsonar.gitlab.user_token=${gitlabtoken} -Dsonar.gitlab.api_version=v4 """ } } } } stage("BuildImage"){ steps{ script{ withCredentials([usernamePassword(credentialsId: 'aliyun-registry-admin', passwordVariable: 'password', usernameVariable: 'username')]) { env.nowDate = sh returnStdout: true, script: 'date +%Y%m%d%H%M%S' env.nowDate = env.nowDate - " " env.releaseVersion = "${env.branchName}" &nitbsp; env.imageTag = "${releaseVersion}-${nowDate}-${commitId}" env.dockerImage = "registry.cn-beijing.aliyuncs.com/microservicecicd/microservicecicd-${moduleName}-service:${env.imageTag}" env.jarName = "${moduleName}-${branchName}-${commitId}" sh """ docker login -u ${username} -p ${password} registry.cn-beijing.aliyuncs.com cd ${moduleName} && docker build -t ${dockerImage} -f ../Dockerfile --build-arg SERVICE_NAME=${jarName} . sleep 1 docker push ${dockerImage} sleep 1 docker rmi ${dockerImage} """ } } } } } } GitOps-CI扩展部分
在原始CI作业的步骤基础上,增加了一个更新环境的步骤。GitOps实践会将当前的基础环境部署文件存放到一个Git仓库中。我们的CI作业在完成镜像上传后,同时更新环境部署文件中的镜像标签信息。(所以我们需要先获取该环境文件并更新上传)
stage("PushFile"){ // when { // expression { "${env.branchName}".contains("RELEASE-") } // } steps{ &nbsOpp; script{ if ("${env.branchName}".contains("RELEASE-")){ println("branchName = branchName") env.branchName = "master" } else { env.branchName = "feature" } for (i = 0; i < 3; i++) { //下载版本库文件 response = GetRepoFile(40,"${moduleName}%2fvalues.yaml", "${env.branchName}") //println(response) //替换文件中内容 yamlData = readYaml text: """${response}""" println(yamlData.image.version) println(yamlData.image.commit) yamlData.image.version = "${releaseVersion}-${env.nowDate}" yamlData.image.commit = "${commitId}" println(yamlData.toString()) sh "rm -fr test.yaml" writeYaml charset: 'UTF-8', data: yamlData, file: 'test.yaml' newYaml = sh returnStdout: true, script: 'cat test.yaml' println(newYams完l) //更新gitlab文件内容 base64Content = newYaml.bytes.encodeBase64().toString() // 会有并行问题,同时更新报错 try { UpdateRepoFile(40,"${moduleName}%2fvalues.yaml",base64Content, "${env.branchName}") break; } catch(e){ sh "sleep 2" continue; } } } } } //封装HTTP请求 def HttpReq(reqType,reqUrl,reqBody){ def gitServer = "http://gitlab.idevops.site/api/v4" withCredentials([string(credentialsId: 'gitlab-token', variable: 'gitlabToken')]) { result = httpRequest customHeaders: [[maskValue: true, name: 'PRIVATE-TOKEN', value: "${gitlabToken}"]], httpMode: reqType, contentType: "APPLICATION_JSON", consoleLogResponseBody: true, ignoreSslErrors: true, requestBody: reqBody, url: "${gitServer}/${reqUrl}" //quiet: true } return result } //获取文件内容 def GetRepoFile(projectId,filePath,branchName){ apiUrl = "projects/${projectId}/repository/files/${filePath}/raw?ref=${整设;branchName}" response = HttpReq('GET',apiUrl,'') return response.content } //更新文件内容 def UpdateRepoFile(projectId,filePath,fileContent, branchName){ apiUrl = "projects/${projectId}/repository/files/${filePath}" reqBody = """{"branch": "${branchName}","encoding":"base64", "content": "${fileContent}", "commit_message": "update a new file"}""" response = HttpReq('PUT',apiUrl,reqBody) println(response) }
images
GitOps-CD部分
CD-Scheduler作业
此作业其实也是接收GitLab的webhook请求, 与CI-scheduler作业类似。不同的是这个CD-scheduler作业是用来接收环境仓库的代码变更。开启webhook, 配置触发token。生成hookurl:http://jenkins.idevops.site/generic-webhook-trigger/invoke?token=microservicecicd-scheduler-CD
Jenkinsfile pipeline { agent any stages { stage('GetCommitService') { steps { script{ echo 'Hello World' echo "${WebHookData}" // Git Info webhookdata = readJSON text: """${WebHookData}""" eventType = webhookdata["object_kind"] commits = webhookdata["commits"] branchName = webhookdata["ref"] - "refs/heads/" projectID = webhookdata["project_id"] commitID = webhookdata["checkout_sha"] changeServices = [] for(commit in commits) { println(commit.id) &nbs计与p; //added for (add in commit.added) { s = add.split("/") as List if (s.size() > 1){ if (changeServices.indexOf(s[0]) == -1){ changeServices.add(s[0]) } } } //modified for (m in commit.modified) { s = m.split("/") as List // println s // println s.size() // println s[0] if (s.size() > 1){ // println changeServices.indexOf(s[0]) if (changeServices.indexOf(s[0]) == -1){ &nb实现sp; changeServices.add(s[0]) } } } //removed for (r in commit.removed) { s = r.split("/") as List println s if (s.size() > 1){ if (changeServices.indexOf(s[0]) == -1){ changeServices.add(s[0]) } } } } println(changeServices) currentBuild.description = " Trigger by ${eventType} ${changeServices} " } } } stage('DefineService') { steps {  微服; script{ println(changeServices) //服务构建顺序控制 services = ['service02', 'service01'] for (service in services){ if (changeServices.indexOf(service) != -1){ jobName = 'microservicecicd-'+service+'-service-CD' build job: jobName, wait: false, parameters: [string(name: 'branchName', value: "${branchName}" )] } } } } } } } 环境库配置webhook
开启webhook,配置hookurl:http://jenkins.idevops.site/generic-webhook-trigger/invoke?token=microservicecicd-scheduler-CD
CD流水线-CD作业
Jenkinsfile String serviceName ="${JOB_NAME}".split("-")[1] String nameSpace = "${JOB_NAME}".split("-")[0].split("/")[-1] //pipeline pipeline{ agent { node { label "k8s"}} stages{ stage("GetCode"){ steps{ script{ println("${branchName}") println("${env.branchName}".contains("RELEASE-")) println "获取代码" checkout([$class: 'GitSCM', branches: [[name: "${env.branchName}"]], &nb务Csp; doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'SparseCheckoutPaths', sparseCheckoutPaths: [[path: "${serviceName}"]]]], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'gitlab-admin-user', url: "http://gitlab.idevops.site/microservicecicd/microservicecicd-env.git"]]]) } } } stage("HelmDeploy"){ steps{ script{ sh """ kubectl create ns "${nameSpace}-uat" || echo false helm install "${serviceName}" --namespace "${nameSpace}-uat" ./"${serviceName}" || helm upgrade "${serviceName}" --namespace "${nameSpace}-uat" ./"${serviceName}" helm list --namespace "${nameSpace}-uat" helm history "${serviceName}" --namespace "${nameSpace}-uat" """ } } } } }
(责任编辑:行业新闻)
-
云安全日报220519:思科安全设备和威胁防御软件发现权限提升漏洞,需要尽快升级
Cisco ASA是思科其中的一套防火墙和网络安全平台,主要用于工业交换机,路由器等安全设备。Cisco FTD是思科其中的一个威胁防御安全软件,主要用于工业防火墙设备。 5月17日,思科公司发布了安...[详细]
-
云梦级4月18日云梦级消息,抖音 4 月 17 日公告称,近期,平台监测发现,有黑产团伙通过展示豪华酒店设施、发布隐晦暗语等方式,规避平台监管,将目标用户导流至站外实施涉赌行为。对此,平台第一时间对违...[详细]
-
标签: 爱诗科技 PixVerse 拍我AI 多模态视频大模型
云梦级7月14日云梦级消息,爱诗科技今日宣布完成整体 C 轮融资,本轮累计融资 29.8 亿元人民币。 其中,C+ 轮由阿里巴巴领投,Lollapalooza Capital(王慧文家办)、常春藤资本...[详细]
-
微软2021财年第三财季营收417亿美元 商业云业务营收177亿美元
4月28日消息,据国外媒体报道,当地时间周二,微软公布了截至2021年3月31日的2021财年第三财季财报。财报显示,该公司第三财季的总营收为417亿美元,同比增长19%。 该季度,包括Azure、W...[详细]
-
对于任何将工作负载和应用程序迁移到云的组织而言,最重要的考虑因素之一就是确保其所基于的云计算基础设施是安全的。 而对于许多组织而言,满足某些合规标准的需求不仅是遵守行业最佳实践的问题,而且在特定情况下...[详细]
-
快科技3月1日消息,国家安全部官方发文,提醒企业对于数据托管切莫“托而不管”,并特别提到了境外黑客攻击某电商平台数据库的案例。 如今,不少企业选择将数据存储在数据托管平台,降本增效,省心省力,但这也潜...[详细]
-
人工智能作为引领新一轮科技革命和产业变革的战略性技术,俨然已经成为世界主要国家推动科技跨越式发展、实现产业优化升级、赢得全球竞争主动权的重要战略抓手。 近年来,越来越多国家出台政策扶持人工智能产业发展...[详细]
-
影禾医脉联合北京天坛医院发布全球首个全疾病覆盖颅脑CT辅助报告大模型
近日,首都医科大学附属北京天坛医院与影禾医脉联合发布了“小君医生2.0”,标志着全球首个全疾病覆盖的颅脑CT辅助报告生成大模型正式问世。 该模型以天坛医院海量高质量颅脑CT影像与报告数据为核心,深度集...[详细]
-
NLP领域索引神器,3000+代码库,一键查找论文、GitHub库
说到搜索,学术搜索也是一门学问。 擅于运用搜索可以帮助你快速寻找想要的学术资料,起到事半功倍的效果。比如我们常用到的论文及对应源码的神器 Papers With Code,就收录了很多 SOTA 论文...[详细]
-
三星AI机器人“Luna”亮相:这款像点唱机的居家助手真的实用吗?
三星电子首席设计官毛罗·波奇尼近期展示了名为“Luna”的AI机器人设计概念。这款设备拥有圆形的显示屏和可旋转的头部,外形酷似三星此前发布的“AI OLED调色盘”。 尽管Luna的设计极具现代感,但...[详细]
- https://www.kuaikanmanhua.com/sou/谷歌留痕技术教程-教程要点与实践【tg:seogoogle987】,No2
- https://www.nctsn.org/search?cat=191&query=谷歌留痕技术教程-教程要点与实践【tg:seogoogle987】,kZK
- https://www.remit.co.jp/vi/?s=谷歌留痕技术教程-教程要点与实践【tg:seogoogle987】,ORO
- https://www.sdcard.org/ja/?s=谷歌留痕技术教程-教程要点与实践【tg:seogoogle987】,8kD
- https://www.paxnet.co.kr/search/jongmok?kwd=谷歌留痕技术教程-教程要点与实践【tg:seogoogle987】LW0
- https://search.danawa.com/dsearch.php?query=谷歌留痕技术教程-教程要点与实践【tg:seogoogle987】DAD
- https://www.teamlab.art/zh-hans/?submit=谷歌留痕技术教程-教程要点与实践【tg:seogoogle987】,T2A
- https://www.urmc.rochester.edu/news/search?q=谷歌留痕技术教程-教程要点与实践【tg:seogoogle987】,Ejw
- https://www.shopping.com/search.html?keyword=谷歌留痕技术教程-教程要点与实践【tg:seogoogle987】,7CW
- https://www.qidulp.com/search?query=谷歌留痕技术教程-教程要点与实践【tg:seogoogle987】,DJd

印度推出 ChatGPT 电商支付新体验,购物更智能!
标签: 长鑫科技 DRAM 朱一明 科创板
标签: B站 陈睿 UP主 AI内容
Nord Security联合创始人新创企业Nexos.ai完成3500万美元A轮融资:专注企业AI安全中间层
高管邮件揭露Facebook与苹果的新仇旧怨 可追溯到乔布斯时代
