关于cicd:项目开展CICD的实践探路-京东物流技术团队

本文介绍了作者对CICD的了解以及在我的项目中发展CICD的几种场景,总结了每种场景实际的要害节点、带来的收益,以及联合具体我的项目发展的理论利用。读者能够借鉴本文中形容的场景,或借鉴文中提到的实际形式,在我的项目中发展CICD,为我的项目在继续集成部署上做具体的撑持。 1 前言基于公司Bamboo、EOS,SonarQube平台,在我的项目中发展CICD继续集成与部署。介绍CICD发展的场景,我的项目中的理论利用,以及后续布局。 2 CICD根底概念CICD 是继续集成(Continuous Integration)和继续部署(Continuous Deployment)简称。指在研发过程中主动执行一系列脚本来升高开发引入 bug 的概率,在新代码从开发到部署的过程中,尽量减少人工的染指。 CICD 外围:继续集成、继续部署、继续交付。 CI:Continuous Integration,示意继续集成。 指在向近程仓库 push 代码后,在这次提交合并入主分支前进行一系列测试,构建等流程。 假如当初有个利用的代码存储在 仓库上,每天开发都会 push 很屡次提交,针对每次 push,你能够创立一系列脚本进行自动测试,升高往利用里引入谬误的概率。它能够利用在包含开发分支在内的多个分支上。 继续集成过程中很器重自动化测试验证后果,以保障所有的提交在合并主线之后的品质问题,对可能呈现的一些问题进行预警。 CD:Continuous Delivery,示意继续交付。 指在实现CI后可主动将已验证的代码公布到仓库。 继续交付的指标是领有一个可随时部署到生产环境的代码库。 CD:Continuous Deployment,示意继续部署。 指在继续集成的根底上更进一步,指将推送指仓库默认分支代码部署到特定环境。 通过自动化的构建、测试和部署循环来疾速交付高质量的产品。某种程度上代表了一个开发团队工程化的水平,任何批改通过了所有已有的工作流就会间接和客户见面,只有当一个批改在工作流中构建失败能力阻止它部署到产品线。 3 CICD的发展场景3.1 编译部署实现代码提交之后的主动编译-部署过程,取代j-one上构建-部署手动操作 内容: 代码提交后的主动构建、主动部署、构建部署后果告诉;收益: 去除Jone上代码构建实现后的手动部署操作中等待时间;3.2 单元测试发展基于Junit的单元测试 内容: 针对后端代码,基于Junit编写单元测试脚本,发展单测,获取单测报告、jacoco代码覆盖率报告;收益: 晋升测试覆盖率,进步代码品质;缩小bug,疾速定位bug;无限撑持重构;3.3 代码扫描实现基于SonarQube的代码品质检测 实现基于EOS的代码品质检测 内容: 实现基于SonarQube、或公司平台EOS的代码扫描检测;代码提交主动触发代码扫描,最终生成报告、后果告诉;扫描后果计入我的项目品质,记录跟踪问题,直至问题闭环解决。收益: 代码品质检测的伎俩丰盛;多层次的自动化测试,晋升代码品质;主动触发测试执行,缩减测试等待时间,提高效率,实现无人值守;3.4 自动化测试实现基于Python、EasyOne、DeepTest、Jmeter 的自动化测试。 内容: 实现基于SonarQube的代码品质检测;实现全链路各环节的自动化测试;代码提交主动触发测试执行、生成报告、报告告诉;收益: 多层次的自动化测试,晋升代码品质;主动触发测试执行,缩减测试等待时间,提高效率,实现无人值守;3.5 全链路测试摸索将上述单个场景进行组合造成全链路测试场景; 代码提交触发链路主动运行,以及报告生成、邮件发送。 4 我的项目实际联合公司外部平台在理论我的项目中发展CICD。 4.1 公司外部平台Bamboo Bamboo是京东自研的一套CI/CD流水线解决方案,笼罩软件开发的残缺生命周期。 EOS EOS是技术与数据中台自主研发的代码扫描零碎,通过扫描剖析代码,定位到工程中不标准的编码片段并给出批改倡议,能无效监督束缚开发人员对立编码习惯,缩小因编码不标准引起的低级谬误,进步代码可读性,进步团队合作效率。 4.2 我的项目理论利用1)编译-部署 ...

August 25, 2023 · 1 min · jiezi

关于cicd:开个脑洞带你写一个自己的极狐GitLab-CI-Runner

极狐GitLab Runner 是极狐GitLab CI/CD 执行的利器,可能帮忙实现 CI/CD Pipeline Job 的执行。 目前极狐GitLab Runner 是一个开源我的项目(https://jihulab.com/gitlab-cn...),以 Golang 编写。 极狐Gitlab 有个不错的个性,就是你能够应用本人的极狐Gitlab CI Runner。可是,如果你没有本人的CI Runner该怎么办呢?别放心,咱们能够本人写一个。[]~( ̄▽ ̄)~* 在这篇文章里,咱们会: 论述极狐GitLab Runner的外围工作;剖析Runner工作时和极狐GitLab的交互内容;设计和施行一个咱们本人的Runner;让咱们的Runner运行本人的CI工作;埋一个彩蛋!当然,如果你习惯间接看代码,欢送拜访极狐GitLab仓库。如果喜爱,欢送留个star。 Here we go! 明确外围工作打蛇打七寸,极狐GitLab Runner最外围的工作是这些: 从极狐GitLab拉取工作;获取工作后,筹备一个独立隔离可反复的环境;在环境中运行工作,上传运行日志;在工作实现/异样退出后上报执行后果(胜利/失败)。咱们DIY的Runner同样要实现这些工作。接下来咱们按程序捋一捋各个外围工作,同时察看Runner是怎么和极狐GitLab交互的。 为了行文扼要,下文的API申请和返回的内容有所精简。 一、 注册如果你用过自托管的极狐GitLab Runner,你应该相熟这个页面: 用户在这个页面获取注册token,而后通过gitlab-runner register命令把Runner实例注册到极狐GitLab。这个注册过程实质上是在调用接口POST /api/v4/runners,其body形如: { "description": "一段用户本人提供的形容", "info": { "architecture": "amd64", # runner的架构 "features": { # runner具备的个性,极狐GitLab可能会回绝不具备某些个性的runner注册 "trace_checksum": true, # 是否反对计算上传日志的checksum "trace_reset": true, "trace_size": true }, "name": "gitlab-runner", "platform": "linux", "revision": "f98d0f26", "version": "15.2.0~beta.60.gf98d0f26" }, "locked": true, "maintenance_note": "用户提供的保护备注", "paused": false, "run_untagged": true, "token": "my-registration-token" #极狐GitLab提供的注册token}如果注册token有效,极狐GitLab会返回403 Forbidden。在胜利注册时会返回: ...

December 29, 2022 · 4 min · jiezi

关于cicd:gitlabCICD共享runner基本配置

gitlab-CICD共享runner根本配置应用docker部署runner多个我的项目应用共享runner部署机器与runner不在同一台服务器上(应用ssh部署)部署runner部署镜像docker pull gitlab/gitlab-runner:latestdocker run -d --name gitlab-runner-shared \ --restart always \ -v /var/run/docker.sock:/var/run/docker.sock \ gitlab/gitlab-runner:latest注册runnerdocker exec -it gitlab-runner-shared gitlab-runner \ register -n \ --tag-list "gitlab-runner-shared" \ --description "形容" \ --url <公有gitlab地址> \ --registration-token <我的项目/共享token> \ --executor docker \ --docker-privileged \ --docker-image "alpine:latest" \ --docker-pull-policy "if-not-present" \ --docker-volumes "/var/run/docker.sock:/var/run/docker.sock"SSH相干配置在linux服务器应用ssh-keygen创立一个ssh key ssh-keygen -t rsa -P "" ~/.ssh/id_rsa推送到部署服务器上 ssh-copy-id -i ~/.ssh/id_rsa.pub <近程服务器ip>测试登录ssh <近程服务器登录名>@<近程服务器ip># 按提醒输出明码将私钥复制下来 cat ~/.ssh/id_rsa将私钥设置到Gitlab的变量中(例如:SSH_PRIVATE_KEY)近程部署(编写ci文件) image_build:stage: buildimage: alpine:latestbefore_script: - sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories # 设置国内镜像源 - 'which ssh-agent || ( apk update && apk add openssh-client )' # 装置ssh - eval $(ssh-agent -s) - echo "$SSH_PRIVATE_KEY" > deploy.key # 设置ssh私钥 - chmod 0600 deploy.key # 设置私钥权限 - ssh-add deploy.key # 增加到缓存中 - mkdir -p ~/.ssh - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config' # 第一次登录不须要询问script: - ssh <用户名>@<服务器ip> "ls && exit" # 近程执行语句应用docker打包image-build: stage: build image: docker:18.09.7 services: - docker:18.09.7-dind script: - docker build --no-cache -t <镜像>:<镜像tag> . # 生成镜像 - docker login -u <docker用户名> -p <docker明码> <docker库地址> # 登录云端 - docker push <镜像>:<镜像tag> # 镜像推送到云端 after_script: - docker rmi -f <镜像>:<镜像tag> # 已上传云端,清理本地镜像,缩小占用内存 retry: max: 2 when: always告诉(curl)build-job-failure: stage: build-notify when: on_failure # 失败时告诉 image: alpine:latest before_script: - sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories # 设置国内镜像源 - apk update && apk add curl # 装置curl script: - if [ "$CI_COMMIT_REF_NAME" == "dev" ]; then env_name="dev"; else env_name="prod"; fi - echo '{"content":"@'$GITLAB_USER_LOGIN' '${CI_COMMIT_TITLE}'\n'$CI_PROJECT_NAME' 构建'$env_name'环境 [ 失败 ]"}' > content.json # 防止提交文字中有空格导致报错,应用json的形式 - curl -X POST -H "Content-Type:application/json" -d @content.json "$NOTIFY_URL"残缺.gitlab-ci.ymldefault: tags: - gitlab-runner-shared variables: NOTIFY_URL: "告诉地址" IMAGE_REPOSITORIES: "docker地址" IMAGE_NAME: "docker镜像名" SSH_USERNAME: "SSH用户名" SSH_IP: "部署服务端IP"workflow: rules: - if: $CI_COMMIT_TITLE =~ /^[skip ci]/ when: never - when: alwaysstages: - build - deploy - notify# 应用docker构建镜像image-build: stage: build image: docker:18.09.7 services: - docker:18.09.7-dind script: - docker build --no-cache -t $IMAGE_NAME:$CI_COMMIT_REF_NAME . - docker login -u $IMAGE_REPOSITORY_USER -p $IMAGE_REPOSITORY_PASSWORD $IMAGE_REPOSITORIES - docker push $IMAGE_NAME:$CI_COMMIT_REF_NAME after_script: - docker rmi -f $IMAGE_NAME:$CI_COMMIT_REF_NAME retry: max: 2 when: always# 部署镜像image-deploy: stage: deploy image: alpine:latest rules: - if: $CI_COMMIT_REF_NAME == "dev" variables: PORT: "8180" - if: $CI_COMMIT_REF_NAME == "master" variables: PORT: "8181" before_script: - sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories - 'which ssh-agent || ( apk update && apk add openssh-client )' - eval $(ssh-agent -s) - echo "$SSH_PRIVATE_KEY" > deploy.key - chmod 0600 deploy.key - ssh-add deploy.key - mkdir -p ~/.ssh - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config' script: - ssh $SSH_USERNAME@$SSH_IP "docker rm -f frontend-$CI_COMMIT_REF_NAME && docker run -itd --restart=always --name frontend-$CI_COMMIT_REF_NAME -p $PORT:80 $IMAGE_NAME:$CI_COMMIT_REF_NAME && exit" retry: max: 2 when: alwayssuccess: stage: notify when: on_success image: alpine:latest before_script: - sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories - apk update && apk add curl script: - if [ "$CI_COMMIT_REF_NAME" == "dev" ]; then env_name="dev"; else env_name="prod"; fi - echo '{"content":"@'$GITLAB_USER_NAME'\n'$CI_PROJECT_NAME' 部署'$env_name'环境 [ 胜利 ]\n'${CI_COMMIT_TITLE}'"}' > content.json - curl -X POST -H "Content-Type:application/json" -d @content.json "$NOTIFY_URL" retry: max: 2 when: alwaysfailure: stage: notify when: on_failure image: alpine:latest before_script: - sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories - apk update && apk add curl script: - if [ "$CI_COMMIT_REF_NAME" == "dev" ]; then env_name="dev"; else env_name="prod"; fi - echo '{"content":"@'$GITLAB_USER_NAME'\n'$CI_PROJECT_NAME' 部署'$env_name'环境 [ 失败 ]\n'${CI_COMMIT_TITLE}'\n'$CI_PIPELINE_URL'"}' > content.json - curl -X POST -H "Content-Type:application/json" -d @content.json "$NOTIFY_URL" retry: max: 2 when: always参考文章:gitlab ssh ci文件 ...

July 6, 2022 · 3 min · jiezi

关于cicd:企业CICD规模化落地浅析

本次分享的题目是《企业CICD规模化落地》,因而咱们不会偏重解说CICD是什么以及怎么做CICD,而是你曾经晓得怎么“玩转”CICD了,要如何在一个比拟大的企业中规模化地落地。 本文整顿自阿里巴巴技术专家崔力强(怀虎)的分享《企业CICD规模化落地》。 研发流程与继续交付简析继续交付是随着互联网的迅猛发展逐步遍及的一种研发模式,它具备“疾速反馈”“品质内建”“自动化”“开发自运维”等特点。 这种研发模式次要蕴含如上图所示的四个环节,“分支治理”“测试验证”“制品治理”和“公布”。在业界有很多工具反对这些操作,在云效产品矩阵中也有对应的产品提供相应性能。 在一个中小型的研发团队(比方5-10人),无论你是应用商业软件还是开源的工具,通过一段时间的学习,你都能够把“继续交付”做起来。然而当须要规模化落地之后,就有更多的问题须要思考,如: 如何进步合作效率;新团队如何疾速接入;如何进行全局危险的管制;研发流程如何全局更新。继续交付在阿里巴巴的规模化接下来简略理解一下“继续交付”研发工具在阿里巴巴外部的演变历程。2009年,咱们开发了自动化公布工具;2013年,建设对立构建部署平台;到了2016年咱们曾经有了继续交付平台,外部称为“Aone”,该产品蕴含了从代码开发、构建、公布等性能,以一个一站式的研发平台,这个产品到当初也始终在演进;2017年时,咱们将“Aone”的外围性能凋谢进去,供宽广开发者应用,就是咱们的“阿里云·云效”。目前该产品在公测中,大家能够登录阿里云官网进行拜访、应用。 上面咱们介绍几个帮忙阿里巴巴实现继续交付规模化落地的研发实际。 要使继续交付规模化落地,很重要的一点是须要有一套工具对研发模式进行全自动反对。 “研发模式”是指你做事件的一种形式,在这里次要是指代码公布模式以及对应的分支应用形式,比方“骨干模式”,这也是继续交付比拟提倡的一种研发模式。然而“骨干模式”对研发人员的要求比拟高,并且也不能很好的体现出以后要进行公布的内容。作为一位研发负责人,你可能会抉择更灵便一些的研发模式,比方 “Aone Flow”或者 “Git Flow”等,这两种模式都须要肯定的自动化工具进行反对。 其中Aone Flow是在阿里巴巴外部支流的一种公布模式及分支治理形式,咱们这里简略介绍一下,感兴趣的同学能够在网上搜寻相干文章理解。Aone Flow应用三种分支类型:骨干分支、个性分支、公布分支。骨干分支上的代码跟线上版本的代码是统一的,当你要开发一个新的性能时,就会拉取一个个性分支作为开发分支,而后在这个分支上提交代码批改。当你须要公布的时候,须要先将不同的个性分支合并为开发分支再进行公布。公布到线上正式环境后,合并相应的公布分支到骨干,在骨干增加标签,同时删除该公布分支关联的个性分支。这个过程中波及到大量的“拉分支”“合分支”“打标签”“回滚版本”等等简单操作,这就须要有一系列自动化工具进行反对。在阿里巴巴外部咱们是通过Aone平台(即云效的外部版本)提供自动化反对的。 第二个实际是以利用为外围的一站式研发体验。“利用”是指一个服务或者微服务,能够间接对应一个代码库。以利用为核心,咱们又能够串联流水线、环境治理、构建配置、部署等工具链。能够让开发人员很好的了解和买通整个研发流程,同时也能够帮忙一个新团队疾速上手。 上图是咱们外部一个产品研发过程的截图,会有一个研发向导帮忙你提交各种信息、初始化代码库、源码主动生成、申请测试环境、进行线上公布等一系列操作。这种“以利用为外围的一站式体验”十分爽,能够帮忙研发团队节俭很多消耗在合作上的工夫,而且有了这套流程之后,只有依照向导的提醒去做就好了,很少出错。 接下来,咱们聊一下如何进行全局危险管控。 在部署正式环境之前,会有一个Checklist,进行平安审核、PE审核等等,咱们很多对外公布的利用都会通过这样的平安审核。在前DevOps时代(2016年以前),阿里巴巴外部还是有专门的运维团队的,咱们叫PE团队。在正式公布前,他们会去审核公布的工夫点、配置参数等。这就是全局危险管控,这些卡点会强制在一个流程中施行,不可能勾销。(当然当初曾经阿里巴巴外部曾经勾销了PE团队,这些卡点会通过自动化工具实现) 兼具灵活性与规范性的继续交付平台通过以上几个措施,就可能在阿里巴巴外部规模化的落地CICD,当新的研发团队退出时,也不必破费太多的工夫去了解这个事件,而是很快上手去操作。然而咱们这一套流程也遇到一些问题,这套流程面向Web端服务是能够很好去应答的,比方咱们只有一个版本的“天猫”“淘宝”,永远是面向最新版去交付的;然而随着阿里云业务的倒退,特地是呈现了混合云的业务,呈现了面向多Region和多版本交付的状况,咱们这套研发流程就有点顾此失彼了;因为咱们的研发理念是“以利用为核心”,当遇到一些跟利用无关的交付场景时这套研发流程也会显得不合时宜。 如何进步阿里巴巴继续交付平台的灵活性呢?咱们最早的研发架构如上图左侧所示,底层是研发平台,下面咱们做了很多“场景化”的研发组件,同时保留了肯定的扩展性,比方“自定义组件”,用户能够把本人的组件接入到咱们的流水线里来;也裸露了一部分API,次要只读接口,其余团队能够在这下面做一些他的场景化。 咱们认为这种研发架构的灵活性和扩大能力是有余的,(如上图右侧所示)起初咱们就把构建、编排、部署、制品这些能力独自拎进去,并凋谢对应的API,下层咱们再去编纂“场景化”,而且有可能这些“场景”都不是咱们开发的,而是应用这个产品的用户本人去开发,重点是咱们须要将这种扩大能力裸露进去。咱们还会有“自定义步骤”和“自定义组件”,这两个性能曾经在云效产品中提供。同时,咱们还会开发更多API、反对更多的源,也能够通过配置webhook在流水线的生命周期中(失败、胜利、暂停等)告诉第三方。 这样的研发架构就具备了肯定的灵活性和可扩展性,但对于企业来讲这是不够,还必须具备开箱即用的能力。 云效内置代码扫描、 平安扫描和各种自动化测试能力,并通过流水线模板串联起来 。如上图右侧所示,针对支流的开发语言Java、PHP、Node.js、Go、Python等提供从构建到部署公布的各种模板,能够帮忙你疾速开始。 模板化能力其实是推动CICD规模化落地的要害,云效不仅提供了数十种通用的模版来帮忙你疾速创立流水线,同时提供定制化能力,反对定制企业自有模版来治理企业继续集成和继续交付流程,将简单的流程通过可视化编排和后果展示,保障交付可见可控可度量。 总结:当你曾经对CICD有肯定理解,怎么样更好的在组织内规模化落地呢?第一,你须要抉择一款兼具灵活性和规范性的工具平台。第二,制订适宜本人企业的研发模式,并将其固化下来;第三,研发模式的变更能够利用到已有的团队;第四,通过适当的卡点来管制全局危险。 以上内容整顿自怀虎的视频分享《企业CICD规模化落地》,欢送大家退出云效开发者交换群(钉钉群号:34532418)观看视频回放,下载演讲PPT。 【对于云效】 云效,云原生时代一站式BizDevOps平台,反对公共云、专有云和混合云多种部署状态,通过云原生新技术和研发新模式,助力翻新守业和数字化转型企业疾速实现研发麻利和组织麻利,打造“双敏”组织,实现 10 倍效力晋升。 立刻体验

January 29, 2022 · 1 min · jiezi

关于cicd:分享实录降龙十八掌CICD持续集成持续部署-IDCF-DevOps案例研究

很快乐加入IDCF组织的第6期DevOps案例深度钻研,咱们小组的分享主题为《降龙十八掌—CI/CD继续集成继续部署》,以“企业CI/CD转型之路”为核心内容,较为残缺全面地梳理了CI/CD从征询到落地实际以及企业内一直优化的全生命周期的过程,和大家一起领略企业在复杂多变的环境之下如何胜利实现CI/CD转型。 一、飞龙在天1.1 CI/CD概览首先,咱们来回顾一下CI/CD的概念。 在工业实际中,工厂里的装配线以疾速、自动化、可反复的形式,从原材料生产出消费品。——自动化是现代化车间的一个重要规范,能够设想在将来会有更多先进的机器和工具去代替人工,人次要是负责保护和治理这些机器。 同样,在软件行业中,交付管道以疾速、自动化和可反复的形式从源代码生成公布版本。如何实现这项工作的总体设计称为“继续交付”(CD)。启动装配线的过程称为“继续集成”(CI)。确保品质的过程称为“继续测试”,将最终产品提供给用户的过程称为“继续部署”。——运维开发及DevOps践行者让这所有简略、顺畅、高效地运行。 1.1.1 继续集成 (CI)继续集成(CI)须要对开发人员每次的代码提交进行构建测试验证,确定每次提交的代码都是能够失常编译测试通过的。 继续集成为咱们的工作带来了很多便当, 它的长处包含: 尽早发现问题。由多个代码组合,因而,常常操作能够立刻晓得谬误何时何地呈现。轻松编写代码,以便与别人一起评论。代码评论可立刻取得反馈。其毛病是: 当我的项目变大时,很难集成。团队短少互动从而会产生一系列的代码问题。CI 不可避免地须要工具,这须要老本。传统 Source Integration vs Continuous Integration(继续集成) 传统集成:项目经理调配模块给开发人员, 每个模块的开发人员并行开发, 并行单元测试,一周到几个月,编写大量版本,如果两头有其余更新代码,则更新的代码也须要进行相应的批改。 这样一来,就可能呈现一些问题: 模块之间依赖关系简单,集成时发现大量的bug。测试人员期待测试工夫过长,造成资源节约。软件交付无奈保障。继续集成能够解决以上问题, 每个成员每天至多集成一次,每次都通过自动化的构建(编译、公布、自动化测试)来疾速验证,尽快发现错误。 1.1.2 继续交付(CD)继续交付(CD)是基于继续集成的根底上,将集成后的代码自动化地公布到各个环境中测试,确定能够公布的生产版本。能够借用制品库实现制品的治理,依据环境类型创立对应的制品库。一次构建,多处运行。 很多人会把继续交付误认为成继续部署,然而两者是两个不同档次的能力。 1.1.3 继续部署(CD)继续部署(CD)是继续交付的下一步,在继续交付的根底上,由开发人员或运维人员自助式地定期向生产环境部署稳固的构建版本。继续部署的指标是代码在任何时刻都是可部署的,并可主动进入到生产环境。 继续交付和继续部署的比照: 继续交付(Continuous Delivery)是指团队确保每个变更能够部署至生产环境,但兴许并不需要理论部署,这通常可能是出于业务方面的起因;继续部署(Continuous Deployment)是指每个变更能够主动部署到生产环境。只有胜利实现继续交付的前提下,能力进行继续部署。它基于一致性,齐全打消了人的干涉,所有已通过品质和测试的 Release 都立刻推送到操作环境。继续部署带来的益处是: 公布频率更快,因为不须要停下来期待公布。每一处提交都会主动触发公布流。在小批量公布的时候,危险升高了,发现问题能够很轻松地修复。客户每天都能够看到继续改良和晋升,而不是每个月或者每季度、每年。主动实时地部署上线,是最优的解决办法,但继续部署要求团队十分成熟,并且上线前需-要通过QA测试,所以实际上比拟难实现,挑战和危险都很大,个别的团队也很难承受。1.2 CI/CD的倒退历史当初,基本上每个IT公司都有本人的CI/CD零碎,有的公司甚至不止一套。从CI/CD倒退历史来说,大体经验了如下4个阶段: 人工公布阶段:CI/CD的操作都是由开发和运维人工染指的,通常是开发做CI生成可部署单元,运维将其部署到服务器上。人工形式是最间接、最无效、最易出错的形式。脚本公布阶段:咱们称之为“半自动化”阶段,人工公布过程的很多事件是重复性的,开发、运维人员深感其扰,于是开始寻求脚本帮忙,如shell、python脚本。脚本的退出极大缓解了开发运维的重复劳动,但脚本形式还须要很多人工操作,而且脚本的很多步骤会被人为跳过或篡改,造成公布的不标准、不胜利等问题。零碎公布阶段(自动化):当初大多数公司都在研发本人的CI/CD零碎,其目标就是标准公布流程,缩小人为失误,进步公布效率。系统对脚本最大的益处是暗藏细节,不可篡改。零碎公布阶段(智能化):大数据时代,一些优良的公司曾经开启智能化CI/CD零碎,通过引入数据分析、智能预测伎俩,进一步优化公布流程、进步公布效率。(内容原创:李帅DevOps DevOps技术说) 1.3 推动CI/CD的内外因素1.3.1 企业推动CI/CD的起因当今商业世界,须要比以往更快的翻新, 软件交付也须要更快更好。借助自动化,须要实现的手动工作较少,能够更频繁地公布较小的变更到生产环境,更快地交付产品,疾速取得最终用户反馈,帮忙企业更好、更高效地参加市场竞争。应用CI/CD,测试和部署过程是通明的。任何问题简直都能够立刻看到,并且能够疾速找到起因,从而缩小了之前在查明问题起因时无可奈何的猜想。谬误缩小。古代软件性能、我的项目和应用程序很简单,谬误也越来越简单。开发人员的手动工作更少,这意味着更少的人为谬误机会。运维部门会收到高质量的代码,QA须要解决的问题较少,客户服务也不会收到那么多宜人的客户投诉邮件或投诉电话。每个人的工作都失去改善。资源开释。如果将可反复和可预测的工作移交给自动化,则能够为开发人员腾出工夫来做他们喜爱的事件,在放弃原始业务束缚的同时,还能够实现更多工作。客户更称心。更快、更频繁的公布和更少的谬误使得开发人员与其余业务部门之间更加信赖,按时实现工作,取得牢靠的后果以及使最终用户更加称心。由此可见,CI/CD是双赢的。有了CI/CD和自动化,频繁的集成,可见性,手动操作造成的谬误等问题就打消了。因而,当初越来越多的企业正在向麻利方法论和自动化流程迈进。 1.3.2 案例 - NationwideNationwide(互惠保险,500强里排名第69的一家公司)的转型是从麻利开始的,从瀑布模型逐步转型到CI/CD,随后在多个团队实现全栈式麻利开发。 第一阶段:从3个麻利团队倒退到200个麻利团队 一年后麻利团队成熟了,开始规模化麻利。从3个团队开始,始终倒退到整个公司绝大多数开发团队都能做到成熟的麻利施行。这一过程花了五六年的工夫 ,因为公司规模大,问题也是很不错的,从品质、开发速率、零碎稳定性等多方面获得了很好的问题,这是第一阶段的胜利。 第二阶段:新的痛点 进入第二阶段,互惠保险遇到新的问题。 (图片起源:DevOpsDsys 2017 – 北京站) 公司发现整个交付曲线如上图,通过该曲线能够看到两头的设计、开发、测试都做得不错了,速度也很快。但从商业想法开始到包含需要剖析、年度我的项目估算等对 IT 的整体公布速率来讲是一个微小的瓶颈,这个瓶颈占到整个开发流程总工夫的60%。 另一个比较严重的瓶颈是开发之后始终到产品上线又花了大量的工夫。 公司发现只做麻利是不够的,于是开始依照解决这两个瓶颈的思路去解决问题。 解决新痛点的办法 用一个典型的价值流图去展现整个流程,并剖析这个价值流图。 ...

January 25, 2022 · 3 min · jiezi

关于cicd:装在笔记本里的私有云环境持续集成上

本篇是系列中的第五篇内容,咱们持续聊聊如何把一个简化过的公有云环境部署在笔记本里,以满足低成本、低功耗、低延时的试验环境。如果你有闲置的轻量云服务器,也能够入手试试。 写在后面作为“继续集成”章节的第一篇内容,咱们先来聊聊在单机服务器上的 CI 的应用。 对于根底的搭建,之前的文章中曾经屡次提到,所以我就不再赘述,本文将着重介绍过程中的一些细节,如果你对 Gitea 和 Drone 或者 GitLab 感兴趣,能够浏览之前的内容: 《容器形式下的轻量仓库与CI 应用计划:Gitea + Drone 根底篇》《应用容器形式编译无性能限度的 Drone CI》《轻量平安的部署计划》《应用 Docker 和 Traefik v2 搭建轻量代码仓库(Gitea)》一些 GitLab 相干的内容为了更低的保护老本,以及后续多机扩大应用,本文所有程序的应用均在容器环境下。 单机 CI 设计在开展实际细节之前,咱们得先来聊聊“设计”。 架构设计CI 过程中的参与者次要有上面这几类(本篇暂不聊软件仓库局部):用户、Git服务、CI 服务、CI 执行器。 简略针对下面的参与者进行定义:“用户”能够是有血有肉的人,也能够是自动化的脚本或者 BOT,各种数据的创造者;“Git 服务”,用于存储代码数据,提供根底的权限性能和界面治理的程序;“CI 服务”,提供继续集成的工作的调度和治理的程序;“CI 执行器”,用于执行具体的 CI 工作的程序。 思考到单机服务器上除了 Git 服务和 CI 服务之外,还会运行咱们须要更新和部署的程序,为了让资源应用效率更好、保护老本更低、防止咱们为每一个 Web 程序配置 HTTPS 证书,咱们能够增加一个反对服务发现的利用网关。 即便是单机服务器,咱们仍旧须要留神 SSH 的应用平安,在多机环境下,咱们会应用跳板机和云服务器安全策略来进行集中的平安治理,在单机场景下,我应用 SSH 服务开关来实现简略的平安防护(不必的时候,间接敞开,也为互联网上的嗅探机器人省点电)。 如果将下面的“参与者”用图例来示意,一个最根底的单机 CI 应用模式会相似上面这样: 我将图中不同角色的数据交互进行的数字序号标注,简略解释一下这些序号代表的具体内容: “1” 示意了用户应用具体的域名来拜访咱们的 Git 服务和 CI 服务,来进行仓库治理或者配置 CI 工作。这类交互应用的是 HTTP 的形式,比方在浏览器中拜访 https://gitea.lab.com、https://gitlab.lab.com、https://drone.lab.com。“2” 示意了用户或者客户端应用 SSH 的形式拜访 Git 仓库,须要搭配 RSA Key 应用。“3” 和 “4” 示意了 Traefik 应用服务发现的形式,聚合 Git 服务和 CI 服务,为用户提供域名模式的拜访形式,这里应用的代理模式同样也是 HTTP。“5” 示意了 SSH 开关和 Git SSH 服务之间的数据交互,交互模式为 TCP。“6” 和 “7” 示意了 CI 服务 别离和Git 服务、CI 执行器之间的数据交互,从 Git 获取仓库变动,而后创立 CI 工作,接着将 CI 工作执行状态一直推送至 Git 服务中,交互模式不限,能够应用 HTTP API,也能够应用各种基于 TCP 的 RPC 的形式。“8” 则示意了 CI 执行器如何从 Git 服务器的代码仓库中获取代码,或者将一些数据更新回 Git 服务器中,个别状况下是应用 HTTP 的形式,我更举荐应用 Git Over SSH 进行交互。部署模式在单机全容器模式下,咱们个别会用两种形式能够实现部署。 ...

January 3, 2022 · 3 min · jiezi

关于cicd:kubernetes-基于jenkins-spinnaker的cicd实践一增加制品镜像扫描

前言:晚期jenkins承当了kubernetes中的ci/cd全副性能Jenkins Pipeline演进,这里筹备将cd继续集成拆分进去到spinnaker!当然了 失常的思路应该是将jenkins spinnaker的用户账号先买通集成ldap.spinnaker账号零碎曾经集成ldap.jenkins之前也做过相干的试验。这里对于jenkins集成ldap的步骤就先省略了。毕竟指标是拆分pipeline流水线实际。账号零碎 互通还没有那么有紧迫性!。当然了第一步我感觉还是少了镜像的扫描的步骤,先搞一波镜像的扫描!毕竟平安才是首位的 对于jenkins流水线pipeline的镜像扫描注:image 镜像仓库应用了harbor Trivyharbor默认的镜像扫描器是Trivy。早的时候貌似是clair?记得 查看harbor的api (不能与流水线集成提供扫描报告)看了一眼harbor 的api。harbor 的api能够间接scan进行扫描: 然而这里有个缺点:我想出报告间接展现在jenkins流水线中啊,GET也只能获取log,我总不能jenkins流水线集成了harbor中主动扫描,扫描实现了持续来harbor中登陆确认镜像有没有破绽吧?所以这个性能对外来说很是鸡肋。然而抱着学习的态度体验一下jenkins pipeline中镜像的主动扫描,首先参考了一下泽阳大佬的镜像主动清理的实例: import groovy.json.JsonSlurper//Docker 镜像仓库信息registryServer = "harbor.layame.com"projectName = "${JOB_NAME}".split('-')[0]repoName = "${JOB_NAME}"imageName = "${registryServer}/${projectName}/${repoName}"harborAPI = ""//pipelinepipeline{ agent { node { label "build01"}} //设置构建触发器 triggers { GenericTrigger( causeString: 'Generic Cause', genericVariables: [[defaultValue: '', key: 'branchName', regexpFilter: '', value: '$.ref']], printContributedVariables: true, printPostContent: true, regexpFilterExpression: '', regexpFilterText: '', silentResponse: true, token: 'spinnaker-nginx-demo') } stages{ stage("CheckOut"){ steps{ script{ srcUrl = "https://gitlab.xxxx.com/zhangpeng/spinnaker-nginx-demo.git" branchName = branchName - "refs/heads/" currentBuild.description = "Trigger by ${branchName}" println("${branchName}") checkout([$class: 'GitSCM', branches: [[name: "${branchName}"]], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'gitlab-admin-user', url: "${srcUrl}"]]]) } } } stage("Push Image "){ steps{ script{ withCredentials([usernamePassword(credentialsId: 'harbor-admin-user', passwordVariable: 'password', usernameVariable: 'username')]) { sh """ sed -i -- "s/VER/${branchName}/g" app/index.html docker login -u ${username} -p ${password} ${registryServer} docker build -t ${imageName}:${data} . docker push ${imageName}:${data} docker rmi ${imageName}:${data} """ } } } } stage("scan Image "){ steps{ script{ withCredentials([usernamePassword(credentialsId: 'harbor-admin-user', passwordVariable: 'password', usernameVariable: 'username')]) { sh """ sed -i -- "s/VER/${branchName}/g" app/index.html docker login -u ${username} -p ${password} ${registryServer} docker build -t ${imageName}:${data} . docker push ${imageName}:${data} docker rmi ${imageName}:${data} """ } } } } stage("Trigger File"){ steps { script{ sh """ echo IMAGE=${imageName}:${data} >trigger.properties echo ACTION=DEPLOY >> trigger.properties cat trigger.properties """ archiveArtifacts allowEmptyArchive: true, artifacts: 'trigger.properties', followSymlinks: false } } } }}革新spinnaker-nginx-demo pipeline仍旧拿我spinnaker-nginx-demo的实例去验证,参见:对于jenkins的配置-spinnaker-nginx-demo,批改pipeline如下: ...

November 20, 2021 · 7 min · jiezi

关于cicd:自建的gitlab搭建CI工具-dangerjs

Dangerjs是用于代码审查的小工具,你所看到的什么XX Bot根本都是这玩意儿生成的,是项目管理的利器。他能够用于任何自动化的CI/CD工具链,罕用的有Github Actions,Gitlab Jobs。对于 Github/私有Gitlab 的,有一篇优良的文章举荐:https://segmentfault.com/a/11...,这里就不再阐述。这里次要探讨自建的Gitlab。 背景自建的gitlab版本: 11.9.9,没有开启MR接口(开启了能够尝试用新的dangerjs)应用可选,为你的小机器人创立一个账号必选,弄清楚三个环境变量DANGER_GITLAB_API_TOKEN, 登录机器人账号,点击右上角关上设置面板,并在左边找到Access Tokens,配置一个新的DANGER_GITLAB_HOST,自建gitlab的域名,如 https://gitlab.example.comDANGER_GITLAB_API_BASE_URL,gitlab API的base接口,如 https://gitlab.example.com/api/v4(现有的gitlab应该都是v4接口。如果不是请降级,那太老了)* 有些文章要求oauth token(官网也提到了),但其实不配置也行,这玩意儿还很简单,不如不配 必选,依赖以及目录构造目录下创立.gitlab-ci.yml及dangerfile.js .gitlab-ci.yml用于gitlab跑主动脚本,或者你用的Jekens,也能够在Jekens里配置,只有搞清楚本人须要触发条件以及蕴含对应环境变量即可dangerfile.js用于写那些你须要的条件,下图蕴含了咱们我的项目用到的一些有用的中央。npm i danger。(或者还有配套的lodash、env-cmd,看你需要)* 如果是后面提到的,MR接口未开,dangerjs须要是10.6.0以前的版本,能够选配10.5.4。(相干Issue:https://github.com/danger/dan...)(只有看到MR相干接口404就是这问题) 可选,测试一下本地测试,须要有个现成的MR。 { "scripts": { "local": "echo 'local test' && env-cmd danger pr https://gitlab.example.com/user/project/merge_requests/mrId" }}CICD润的 { "scripts": { "danger": "echo 'cicd running' && danger ci --failOnErrors -v", }}也能够配合husky这样的 { "scripts": { "prepush": "echo 'with husky' && npm danger:prepush", "danger:prepush": "env-cmd danger local --dangerfile dangerfile.js", }}必选,如何检测是否胜利看见相似于这个的,有条你的小机器人的评论就胜利 相干Repo: https://github.com/cangSDARM/...参考文章: https://segmentfault.com/a/11...官网网址/文档:https://danger.systems/js/

November 19, 2021 · 1 min · jiezi

关于cicd:Kubernetes中spinnaker使用二

背景:紧跟Kubernetes中spinnaker的应用一。实现了简略的各种Triggers触发器,还有deploy Mainfest部署一个kubernetes的简略流水线。这里依据理论的环境想更深刻一下流水线步骤:参数化的构建,webhook的触发,邮件的发送,jenkins流水线的集成等等首先明确一下pipeline是由多个stage组成的:对于默认的stage能够参照官网:https://spinnaker.io/docs/reference/pipeline/stages/。环境次要是kubernetes环境这里重视于: 从一条 pipeline开始创立application创立利用 pipeline-test,Permissions权限给运维组读写执行权限(其余组权限看集体需要,这里仅用作演示) 创立流水线pipeline创立pipeline流水线---Parameters-test1 Parameters-对于参数化构建筹备前提:参数化的构建是在Configuration步骤的依照罕用的常规将Kubernetes中spinnaker的应用一中的流水线拿来做试验! apiVersion: apps/v1kind: Deploymentmetadata: labels: k8s-app: nginxdemo name: nginxdemo namespace: devspec: replicas: 1 selector: matchLabels: k8s-app: nginxdemo template: metadata: labels: k8s-app: nginxdemo name: nginxdemo namespace: dev spec: containers: - image: 'harbor.xxxx.com/spinnaker/spinnaker-nginx-demo:1.2.4' imagePullPolicy: Always name: nginxdemo ports: - containerPort: 80 name: web protocol: TCP imagePullSecrets: - name: harbor-layame定义参数Parameters:定义image参数,设置默认镜像tag为nginx:1.18.0 deploy Mainfest这里的stage name是能够自定义名称的,间接设置stage name为公布利用:Manifest Configuration apiVersion: apps/v1kind: Deploymentmetadata: labels: k8s-app: nginxdemo name: nginxdemo namespace: devspec: replicas: 1 selector: matchLabels: k8s-app: nginxdemo template: metadata: labels: k8s-app: nginxdemo name: nginxdemo namespace: dev spec: containers: - image: '${ parameters.image }' imagePullPolicy: Always name: nginxdemo ports: - containerPort: 80 name: web protocol: TCP减少webhook stage 保留流水线Payload 如下:当然了 也能够本人更为细节的去欠缺! ...

November 17, 2021 · 2 min · jiezi