关于ci:金融科技领先者Broadridge选择CloudBees-CI来加速软件交付

Broadridge公司是寰球金融科技领先者,通过丰盛客户参与度、管制危险、优化效率和发明支出增长的解决方案为客户推动业务转型。 借助CloudBees CI,Broadridge为所有应用Jenkins的开发团队提供了集中管理和自助服务的体验。Broadridge可能一直为客户提供新性能,并对市场状况作出更迅速、更灵便的反馈,同时加强公司的竞争劣势。 “Broadridge公司采纳了由CloudBees CI提供反对的DevOps办法,以从新构建其开发和交付要害业务软件的形式——从经纪人解决账簿的形式到交易大厅应用的性能。” https://www.bilibili.com/video/BV1QV4y1h7xP/?aid=870373453&ci...

June 28, 2023 · 1 min · jiezi

关于ci:是-CI-也是阿拉伯飞毯腾讯云-CODING-CI-30-云原生构建

在没有神灯和飞毯前,阿拉丁只是一名一般的程序员。 一天,老板双手环臂,站在阿拉丁的工位旁说:“阿丁,咱们最近公司业务变动快,发版节奏远远跟不上,你思考一下,解决的话请你吃意大利烧饼。”听到意大利烧饼,阿拉丁的口水都流了下来,袖管一擦,鼓足干劲,说干就干,从此踏上寻找解决方案的漫漫征途。 穿梭危机四伏的丛林,人烟稀少的荒漠,辗转间四季更替了几个轮回。正当阿拉丁要失望之时,忽然看见一条叫 CODING DevOps 的河,潺潺流水如莫比乌斯环个别,周而复始,周而复始。而在河岸旁一盏油灯闪闪发光,阿拉丁霎时被吸引过来了,他弯着腰捞起油灯,一边打量着下面神秘的花纹,一边用袖子擦拭着下面的泥土。突然一阵雾起,一个可恶的洋葱猴精灵,腾云而起,对着阿拉丁眨巴着眼说:“感激你从神灯把我解救出来,我能够帮你实现三个欲望!” 阿拉丁惊吓中带着惊喜,弱弱地说了一个欲望:“我想吃上老板说的意大利烧饼。”洋葱猴一挥手,一条缀着流苏的飞毯横空出世,风驰电掣般飞向他们。“这是什么?!”飞毯的运行速度太快了,阿拉丁的眼神都要跟不上了。洋葱猴微微一笑说:“这可是 CODING DevOps 全新推出的 CI 3.0 云原生构建工具,让你的开发工作更简略、更顺畅、更高效!” “怎么个高效顺畅法,你可别骗我。”阿拉丁将信将疑地问。洋葱猴仰起头傲娇地持续介绍:“这个领有魔法的飞毯其实是一个以 Git 为核心,基于 Docker 生态的云原生构建。通过 YAML 文件全申明式配置流水线,流水线配置作为仓库文件,和代码一样被版本治理和爱护。让你写代码一样写你的构建流水线。同时提供云端构建服务,让开发在代码仓库中毫不费力地实现从代码查看、软件构建、自动化测试到公布的流程自动化。同时无需放心服务器配置和保护老本,自动化治理你的构建和部署流程,让你能够专一于软件开发,真正做到开箱即用。对了,它还附赠了近程开发服务,为开发者提供一个基于浏览器的集成式开发环境(WebIDE)。用户无需提前装置任何软件,随时随地关上浏览器就能应用。” 看着阿拉丁还不信,洋葱猴拉着阿拉丁坐上了飞毯,飞毯持重、高效,通过应用OverlayFS 实现 "秒级代码克隆",构建性能优越,在百G大仓背后也毫不逊色,再也不必一个构建跑一天了。飞毯在地面疾驰的同时还能灵便地调整构建资源,小型构建用小机器,简单构建用大机器,真正的做到资源按需分配,更低的生产成本,更高的性价比。坐在飞毯上的阿拉丁满足且开心,脑海中全是意大利烧饼的样子。 终于,阿拉丁风尘仆仆地带上飞毯向老板交差了,老板体验完神器,立马为阿拉丁送上了金灿灿的意大利烧饼,他们都很开心。而神灯,却被阿拉丁轻轻藏了起来,因为将来,他想用神灯换更多的饼... 连忙去 CODING - 代码仓库 - 云原生构建 体验吧!

May 31, 2023 · 1 min · jiezi

关于ci:行云流水|-CI-30-云原生构建全新上线

研发过程中,如何直观且精确地获悉代码提交后的品质状态?引入继续集成,能够自动化的对代码进行代码查看、单元测试、编译构建、甚至部署与公布,大幅晋升开发人员的效率。腾讯云 CODING 推出 CI 3.0 ——云原生构建,是一款基于代码仓库的构建工具,采纳全新的设计理念。可用于继续集成、继续部署、继续交付、近程开发。面向云原生,提供性能、性能、配额三重降级,旨在为 DevOps 践行者带来更简略、更晦涩、更高效的构建体验。 劣势亮点简略——Pipeline as Code 通过仓库根目录中的 .coding-ci.yml 文件,应用开放式、可读性敌对的 YAML 语言,申明整个继续集成流水线。既能够使开发人员浏览、编写与复用流水线更加不便,又能够纳入代码仓库管理体系,像走查代码一样变更流水线配置,加强流水线的可控性与可追溯性。 晦涩——基于 DOCKER 生态 反对指定任意 Docker 镜像作为构建环境。应用 Docker 作为流水线插件,反对任意语言编写,可间接应用业界已有的 Docker 插件。流水线中反对运行原生 Docker 命令,反对任意编排 Docker 服务以满足自动化测试等须要启动依赖服务的场景。高效——基于 OverlayFS 的高性能计划 传统的 CI 流水线中通常无奈兼顾工作的并行与效率,尤其是面临代码仓库或构建缓存异样宏大的场景。基于当先的 OverlayFS 缓存霎时复制技术,即便是上百 GB 容量的代码仓库,云原生构建也可能在秒级实现代码克隆,同时在并发数继续扩充时确保性能不衰减。 疾速开始step1:创立代码仓库 云原生构建能力基于代码仓库中的 .coding-ci.yml 配置文件,因而需在 CODING 团队中提前创立一个代码仓库。进入我的项目后,点击左侧菜单栏左侧的“代码仓库”中的右上角按钮进行创立。 step2:新增配置文件 在仓库根目录中减少名为 .coding-ci.yml 的配置文件。该配置文件用于形容了当仓库产生一些事件时,应该执行什么操作。一个简略的配置文件参考如下: 配置文件含意 当有任意提交推送至 master 分支时,将触发一个名为 echo 的阶段。在此阶段将运行在 script 步骤中所定义的脚本输入命令。 更多用法请参考官网文档:https://ci.coding.net/docs/ step3:提交配置文件 在终端中运行 git push 命令,将配置文件推送至代码仓库中。 step4:查看构建后果 代码推送后将依照配置文件中的定义触发云原生构建。拜访代码仓库中的“云原生构建”,查看构建后果。 ...

May 19, 2023 · 1 min · jiezi

关于ci:解决流水线瓶颈提升编码效率的五个方法下篇

在《CI/CD | 解决流水线瓶颈、晋升编码效率的五个办法(上篇)》中,CloudBees公司产品营销经理Samantha Frost介绍了可能优化软件开发团队流水线的两个解决方案。本篇文章将为大家带来余下三个挑战的解决方案。在文章的结尾处,还将介绍她抉择的解决方案。咱们所面临的挑战是相当广泛的,咱们抉择的解决方案解决了这些问题,并且获得了可掂量的胜利,让每个人都很开心。心愿你也能在其中失去启发,为本人面临的挑战找出适宜的解决方案。 挑战3:排查流水线执行问题(又名:无穷无尽地筛查日志...)即便对流水线配置进行了全面的测试和验证,它们也始终有可能无奈按预期运行。当呈现问题时(例如无奈实现构建,或耗时比预期长得多),解决问题的责任就落到了开发人员身上。 在传统的CI环境中对流水线执行问题进行故障排查并不是很高效的形式。通常须要开发人员查看构建日志或CI控制台界面,以追溯构建问题的本源。这意味着须要进行上下文切换,会对编码工作造成很大的烦扰。 咱们的解决方案是利用源代码治理(SCM)报告性能,主动将构建问题的信息推送到GitHub或BitBucket中。咱们还应用了Slack插件,将定向音讯间接发送给提交与CI作业关联代码的开发人员。因而,只有那些须要理解构建问题的开发人员才会收到告诉,不会扩散其余开发人员的注意力。其余的益处是,Slack插件还能够将构建信息推送到Slack。 后果如何呢?我的开发人员能够在不来到他们次要编码环境的状况下,跟踪构建状态并发现问题。咱们缩小了开发人员看到的告诉,升高了对他们的烦扰,这意外地节俭了很多工夫! 挑战4:治理流水线依赖关系(又名:应用事件驱动流水线进行跨团队协调)CI流水线并不是孤立存在的。在许多状况下,一个流水线可能须要期待另一个流水线实现能力运行。传统CI环境中,流水线依赖关系的挑战在于开发人员必须手动跟踪多个流水线的状态,并依据状态手动触发新的作业。手动监控流水线不仅乏味,还会让开发人员分心,因为他们更违心专一于编码工作。 为此,咱们思考了一个工具,能够从咱们的CI流程中打消这种手动环节,无论他们在哪个团队。咱们应用了跨团队合作(Cross Team Collaboration)性能,该性能能够通过在一个流水线中生成告诉事件,而后将告诉与其余流水线共享,从而实现了流水线之间的协调。 例如,咱们有一个生成JAR文件的流水线。这个JAR文件被另一个流水线用于实现一个独立的工作。通过应用跨团队合作(Cross Team Collaboration),咱们在第一个流水线中配置了一个基于代码的事件告诉,而后在第二个流水线中配置了一个基于事件告诉的触发器。这就是一个齐全自动化的解决方案,将这两个这两个流水线连贯了起来。当JAR文件准备就绪时,不须要依赖治理第一个流水线的团队来告诉,每个流水线都能够放弃同步并主动执行。我不晓得你是否经验过这种状况,但咱们常常因为更新名称,而须要更新门路。因为这个简略的更改,咱们遇到了许多“门路未找到”的谬误,这是十分令人抓狂的。基于事件的触发器让流水线能够互相监听,对咱们来说是一个完满的解决方案。 挑战 5:构建基础设施的低效利用(又名:妈妈说得对,来到房间要关灯!)在现实的状况下,企业中的每个CI实例只在必要时处于活动状态。当没有构建工作须要运行时,它会主动敞开或休眠,从而将基础设施资源提供给其余流水线应用。 在事实中,管制资源耗费是很艰难的。开发人员通常会让CI实例放弃活动状态,即便在不须要时也是如此,而底层的基础设施平台(如Kubernetes)没有主动的办法来晓得何时应该敞开实例。后果是,真正须要资源的工作得不到资源(也就是,产生了大量对于不足容量的埋怨)。此外,咱们还得为不须要的基础设施买单。你会为此与签订估算的副总裁进行“乏味”的对话,而后转身将这种“乏味”的对话带回你的团队。这是不应该产生的,尤其是在现在自动化CI的时代。 咱们的解决方案是应用休眠性能,主动在一段预约义的不活跃期后敞开或休眠CI实例。为了设置该性能,咱们在Kubernetes集群(用于配置托管控制器)的Helm图表中启用了它。咱们配置了主动休眠,并通过界面跟踪休眠的托管控制器的状态。通过主动敞开不沉闷的托管控制器,开发人员将这些控制器占用的资源释放出来,以供理论处于活动状态的控制器应用。后果是构建更快了,因为每个构建都有更多的内存和CPU资源。 此外,当不沉闷的托管控制器敞开或休眠时,Kubernetes能够主动缩减其总节点数。这升高了企业的基础架构老本。并缩小了与领取账单的人不欢快对话的次数。 将这所有做成残缺的解决方案CI软件应该帮忙开发人员更快,更高效地工作。然而,当开发人员不得不破费大量工夫手动设置、批改和排查CI流水线时,这些工具可能会变成更加麻烦的存在,成了扩散开发人员注意力、引发开发人员挫败感的本源,而他们更违心投入工夫编写代码。 为了解决咱们面临的五个挑战,咱们利用了CloudBees CI性能,如流水线模板、流水线模板目录、配置即代码、上下文反馈、跨团队合作和休眠托管控制器。 咱们整体解决方案的教训是,它将咱们的CI软件从一种累赘变成了开发人员生产力的引擎。最终的后果是在更短的工夫外向客户交付更多的价值,开发人员满意度也更高了,因为高效的CI意味着开发人员能够专一于他们喜爱和善于的事件——写代码。 作者:萨曼莎·弗罗斯特(Samantha Frost),CloudBees公司产品营销经理。 文章起源:https://www.cloudbees.com/blog/lets-get-back-to-coding-5-appr...

April 23, 2023 · 1 min · jiezi

关于ci:解决流水线瓶颈提升编码效率的五个方法上篇

不是吹牛,但我所治理的开发团队在软件开发速度上表现出色,可能高质量地编写代码,并在白噪声的陪伴下放弃高效。 但就像所有的故事一样,一开始并不是这样的,甚至相去甚远。咱们经验了工夫、沟通、单干、失败、胜利以及许多对于生产力的会议(有时很难堪,但它们帮忙咱们找出了困扰咱们的问题......另外,我共事会制作他的拿手饼干,所以是双赢的)。接下来,我将间接跳入主题,与你分享我团队的成功经验。 首先,我会提供一些事实来为场景做铺垫:一名一般的开发人员在一天内均匀能够编写大概100行代码。这曾经是绝对高效的开发人员的产出了。有些开发人员每天可能只产出五行或十行代码。思考到一个手机应用程序大概蕴含5万行代码,所以这并不是一个特地高的数字。如果程序员每周只能生产出几百行代码,那么编写一个应用程序会须要很多很多开发工作日。 这就是为什么开发团队须要一直地寻找减速代码生产的办法。他们须要克服减缓软件开发的瓶颈,而后找到一些工具和流程,解决他们在继续编写和部署应用程序时面临的挑战(这就是咱们在吃饼干的会议中探讨的内容)。 当初,咱们都晓得,要实现这一指标,继续集成(CI)流水线是一个很好的终点。只管导致代码生产工夫超过预期的起因有很多,但初始化、配置和执行CI流水线时呈现的问题却是最常见的。开发人员在设置和治理CI流水线或解决构建失败的问题上破费的工夫越多,他们实现次要工作(编写翻新代码)的工夫就越少。此外,可能花更多工夫编写代码,而不是与CI工具纠缠不清的开发人员往往更加幸福。 这是最重要的一点,因为这是让开发人员高兴的起因。他们心愿编写有意义的代码,为最终后果做出奉献,无论代码是否反对更好的用户体验(谁没有经验过一个不能提供所需性能的应用程序的愤恨),或是减少安全性(以便任何人都能够放心使用您的软件,包含您的祖父母),或者因为写得精美播种了一众粉丝的崇拜。 大多数程序员抉择他们的职业是因为他们喜爱写代码,而不是因为他们喜爱手动设置软件,也不是因为他们喜爱在CI日志中查找为什么构建工夫超出预期。 好了,背景故事说够了,我将开始分享我在解决软件交付生命周期中的那一部分“机器”的教训——流水线。 咱们都晓得,一个构造良好的CI流水线能够确保开发人员疾速高效地编写、集成和构建新的利用程序代码。然而,设置一个高效的CI流水线可能会是一项沉重的工作。特地是在须要启动多个流水线的状况下,每个流水线都须要略微不同的配置。如果开发人员必须从头开始设置每个CI流水线并手动调整它,他们可能会在编写第一行代码之前,就破费数周的工夫来初始化流水线。如何在这里使用“防止反复准则(Do not repeat yourself,也被称为DRY软件开发准则)”呢?重复做同样的事会令人丧气,尤其是越做离指标反而越远的时候。 确保流水线配置合乎组织规范或法规要求只会让问题变得更加简单。对于开发人员来说,理解他们的流水线须要满足哪些规范都有点难,更别说以无效的形式施行这些规范了。 所以,在这里,我列出了采纳的局部性能,来帮忙咱们解决流水线挑战。此篇文章是第一篇,会带来其中两个挑战的解决方案。在系列文章的最初,我还会增加咱们抉择的解决方案。 咱们所面临的挑战是相当广泛的,咱们选的解决方案解决了这些问题,并且提供了可掂量的胜利,让每个人都很开心,包含首席执行官,他竟然笑了。心愿你也能在其中找到本人面临的挑战,并找出适宜的解决方案。 挑战1:迟缓的流水线初始化(也就是咱们防止DRY的过程)流水线模板和流水线模板目录在这里起到了关键作用,防止了在创立流水线时反复操作。这些性能让CI管理员和开发团队以模板的模式定义规范流水线配置。在创立了这样的模板之后,管理员或开发人员能够通过配置流水线模板目录将其共享给整个企业。该目录会依据团队的不同,将流水线模板组织成不同的组。后端有一组与前端不同的模板可供选择。所有这些模板都在一个中央进行保护,并且能够让团队主动地抓取和部署。 通过应用流水线模板和模板目录,开发人员在初始化流水线时节俭了大量工夫和精力,而且在确定如何配置流水线以满足特定于域的要求时,猜想也大大减少。 挑战2:自定义CI配置(又名灵活性,为了满足非凡需要)尽管在多个我的项目和开发团队中,模板是简化流水线初始化的无效办法,但一个流水线适宜某个团队,也不肯定适宜别的团队。这意味着配置须要灵便,满足当初和当前的需要。 例如,我已经有一个团队喜爱某个集成工具,但它没有内置到咱们的CI配置中。咱们须要一种办法,既能让他们自定义配置,又能合乎咱们通过测试和批准的CI配置。该怎么办呢?我当然不会阻挡开发人员想要这个工具来进步生产力的欲望。 为了解决这个问题,咱们首先让每个开发人员对CI流水线领有齐全的管理员权限。这解决了容许开发人员自定义配置的挑战。随后咱们发现这种办法存在问题,因为这导致了凌乱和不符合规范。如果单个开发人员能够在没有监督或管制的状况下,部署他们想要的任何插件或配置更改,那么团队最终可能会失去违反企业或监管规范的流水线,甚至可能导致不稳定性。咱们须要一起解决这个问题。 对咱们来说,更好的解决方案是利用配置即代码(Configuration as Code,简称CasC),它提供了一个可治理的基于Git的工作流,让开发人员能够申请CI配置更改,并在利用更改之前应用自动化测试进行验证。具体流程如下: 当开发人员想要更改托管控制器(例如Jenkins®实例)的配置时,开发人员会在Git上收回拉取申请; 拉取申请触发新的托管控制器实例,其中将自动测试配置更改; 如果测试通过,拉取申请将合并到指标托管控制器的主分支中,以便更改失效。 这种办法解决了两个要害挑战。首先,它提供了一个自助式的自动化过程,开发人员能够通过该流程申请CI配置更改,无需面对机构官僚主义或追踪管理员以申请更改。其次,基于Git的办法能够确保在利用配置更改之前,对其进行了适当的测试和验证。通过这种形式,开发团队就能够防止引入导致流水线不稳固或不达标的更改的危险。开发人员也能够领有他们所冀望的个性化设置和稳定性。 下一篇文章,咱们将为您带来余下三个挑战的解决方案,包含排查流水线执行问题、治理流水线依赖关系以及构建基础设施应用效率低下。并且,在下期文章的开端,作者会给出她抉择的解决方案——一次解决这五种挑战的外围武器,敬请期待! 作者:萨曼莎·弗罗斯特(Samantha Frost),CloudBees公司产品营销经理。 文章起源:https://www.cloudbees.com/blog/lets-get-back-to-coding-5-appr...

April 17, 2023 · 1 min · jiezi

关于ci:京东小程序CI工具实践

作者:京东物流 张俊峰 本文从整体介绍了京东小程序CI工具的用处及工作流程,读者能够通过本文理解到一种全新的京东小程序上传形式,同时联合构建脚本和流水线,可大大提高小程序的部署和公布效率。 01 前言 在往年的麻利团队建设中,我通过Suite执行器实现了一键自动化单元测试。Juint除了Suite执行器还有哪些执行器呢?由此我的Runner探索之旅开始了! 京东小程序CI工具是为京东小程序打造的效率晋升工具。通过CI工具,开发者无需依赖小程序开发者工具即可实现京东小程序的预览、上传等操作。同时联合构建脚本和流水线,能够反对代码包的近程部署,实现小程序CI/CD。   1.1  京东小程序简介 京东小程序平台是一个全面凋谢的生态模式,入驻平台后,能分享京东系APP流量福利、海量SKU和凋谢能力。晋升用户体验,给商家带来新机遇。 京东小程序架构分为视图层和逻辑层,视图层运行在WebView容器里,负责UI渲染;逻辑层运行在JSCore的沙箱容器里,负责数据处理。二者通过JSBridge通道进行数据通信。京东小程序架构图如图1所示。 图1 京东小程序架构图 1.2  对于小程序CI工具 小程序CI工具是小程序开发者工具性能的子集,它能够使开发者不依赖开发者工具,即可实现小程序相干的操作,如生成预览版小程序码、上传小程序代码包到控制台等。 02  京东小程序CI工具性能介绍 了解,首先 MCube 会根据模板缓存状态判断是否须要网络获取最新模板,当获取到模板后进行模板加载,加载阶段会将产物转换为视图树的构造,转换实现后将通过表达式引擎解析表达式并获得正确的值,通过事件解析引擎解析用户自定义事件并实现事件的绑定,实现解析赋值以及事件绑定后进行视图的渲染,最终将指标页面展现到屏幕。      京东小程序CI工具是为京东小程序开发者提供的工具包。开发者无需关上开发者工具,应用工具包即可实现小程序代码的上传、预览等操作。 2.1  应用前筹备2.1.1 秘钥 应用工具包之前,请拜访“京东小程序控制台”—设置—开发设置—小程序代码上传秘钥”获取上传秘钥,如图2所示。 图2 京东小程序控制台上传秘钥获取 2.1.2 依赖装置 【Bash】npm install jd-miniprogram-ci --save2.2  上传性能 上传性能通过指定小程序的上传秘钥、我的项目门路,以及版本号、形容等信息,将小程序上传到京东小程序控制台,上传胜利后会生成版本记录,能够进行体验版验证和版本提审。版本记录成果如图3所示。 图3 上传胜利效果图 上传后的体验版二维码没有工夫限度,能够始终应用。 2.2.1 脚本调用 脚本调用形式如下: 【Javascript】const { upload } = require('jd-miniprogram-ci')upload({ privateKey: 'your private key', projectPath: 'your project path', uv: '1.0.0', desc: '自定义形容信息', base64: false,})通过base64选项管制二维码在终端展现,还是作为上传后果返回。 2.2.2 命令行调用 命令行调用形式如下: ...

March 14, 2023 · 1 min · jiezi

关于ci:代码release过程的分支检查

个别的代码release过程的git flow: 1. 从dev分支创立release分支2. 测试组在release分支,开发组在release分支修复bug3. 提两个PR,release分支合并到main分支,release分支合并到dev分支4. 在main分支打发版tag如果按以上工作流,实践上可能保障合并后,main分支和通过测试后的release分支完全一致。 但理论我的项目中,可能存在并行操作的问题。比方在第一步创立release分支后,有bugfix合入了main,就会导致main分支上蕴含release分支没有的commit. 这个问题能够通过查看main分支是否是release分支上commit的子集来解决。 具体能够通过git命令来查看。操作流程: 1、先git log 查看main分支最新的commitId。 2、应用git branch --contains commitId ,看release分支是否蕴含commitId。只有蕴含commitId,标识release上蕴含所有main分支上的commit这个查看过程能够放到PR的CI查看里。

February 10, 2023 · 1 min · jiezi

关于ci:极狐GitLab-CI-月来袭2小时-get-CI-流水线设计秘籍

今日,小王去面试开发,但万万没想到... ... 小王:您好,我来面试开发职位。 面试官:您好,请问您有过 DevOps 教训吗? 小王:Emmm… First blood 面试官:CI/CD 是否有理解呢? 小王:…… Double kill 面试官:如果您有这方面的常识的实际,会特地加分。举荐您一个课程: 点击链接获取课程详细情况 一次演讲,一场反动2009 年,Velocity 大会,一场题为 “10+ Deploys Per Day: Dev and Ops Cooperation at Flickr” 的分享给了 DevOps 创始人 Patrick Debois 很大的触动,也拉开了 DevOps 倒退的大幕。通过 10 余年的倒退,DevOps 的理念和实际曾经遍布寰球。 从国内来看,DevOps 曾经成为了各大企业进行研发效力晋升的必备伎俩。依据中国信通院公布的《中国 DevOps 现状调查报告(2021)》显示:中国企业 DevOps 落地实际成熟度在全面级持续扩张。 成熟度处于全面级的企业最多,为 35.40%,同比增长 8.84%,具备工具化、 自动化、规范化的特点;16.53% 企业的实际成熟度处于优良级,具备平台化、 服务化、可视化与度量驱动改良的特点;0.87% 的企业处于卓越级,可能实现 DevOps 的高度智能化、数据化及社会化的特点。 在 DevOps 倒退的过程中,逐步积淀或延长出了很多落地实际的办法,诸如继续集成(Continuous Integration,简称 CI)、继续交付(Continuous Delivery,简称 CD)、继续部署(Continuous Deployment,简称 CD)、继续测试(Continuous Testing,简称 CT)、平安“左移”(DevSecOps)、部署策略及配置管理等。而其中的 CI/CD 是最为公众所熟知的。 ...

September 7, 2022 · 1 min · jiezi

关于ci:最常见的两个Jenkins问题以及解决方法

Jenkins是当今最风行的继续集成工具之一,据无关报告估算,超过70%的CI流水线都在应用Jenkins,它还是很多技术团队第一个应用的自动化工具。但它也有一个显著弱点:难以达到企业级治理和扩大,这同时催生了很多问题。 浏览本篇文章,您能理解到最常见的两个Jenkins问题:Jenkinsteins(大量的我的项目和团队应用了大量臃肿集中的装置工具集,导致性能低下,以及依赖关系和治理的噩梦)和Jenkins孤岛,以及应答这两个问题的解决办法。 如需理解更多Jenkins企业版——CloudBees的相干信息,请分割CloudBees受权合作伙伴——龙智。 继续集成和继续交付 (CI/CD) 之所以成为当今软件流水线的规范,是有起因的。在CI/CD之前,测试和交付过程是手动的。可重复性简直是不可能的,而公布则是件压力很大的事件,须要在最初时刻争先恐后地修复重大缺点。一个繁忙的团队当然做不出最好的作品,雪上加霜的是,软件品质往往不尽如人意。 Jenkins在流水线自动化方面的广泛应用(寰球70%的开发人员都在应用它!)扭转了所有。软件组织依附Jenkins来反对统一的、可反复的、晚期和经常性的测试,这反过来又意味着更频繁的提交和更高质量的软件更快地进入市场。显然,开源的Jenkins是一个杰出的CI/CD解决方案,但它有一个显著弱点:为企业治理和扩大Jenkins是一场艰辛的战斗。 为了解决与治理、开销治理、插件治理、基础设施治理和团队动静相干的挑战,催生了两种常见(且令人厌恶)的场景:Jenkinsteins和Jenkins孤岛。 “Jenkinsteins”——单体服务器创立一个Jenkins单体服务器并让组织中的每个人都应用它,这就是Jenkinstein办法。尽管看起来很正当,但它会使您的服务器变得十分软弱,并有可能使业务增长停滞。让咱们看看Jenkins单体服务器在理论利用中的四个次要问题。 迟缓的服务器:当服务器过载时,会间接影响构建和测试工夫,从而影响您疾速翻新的能力。单点故障:如果您惟一的Jenkins服务器呈现故障,整个软件组织的生产就会暂停,直到故障失去解决。插件抵触:插件是Jenkins平凡的一部分,然而因为各个团队的不同要求,领有一个Jenkins单体服务器可能会产生插件抵触。集体依赖:所有都取决于组织中“Jenkins搭档”配置和保护软弱的设置。当这些摩擦呈现时,许多团队抉择自行出击,这就产生了Jenkins孤岛。 “Jenkins孤岛”——断开连接的控制器通常,组织内的每个团队都有本人的Jenkins控制器。这的确避免了Jenkinsstein问题,但也带来了新的麻烦。所有这些独自的服务器,都营造出每个团队在只有本人的孤岛上生存的感觉。后果呢? 没有治理:让每个团队都依照本人的规定和实际工作是一场治理噩梦。简直不可能管制谁有权拜访什么,并且不会呈现最佳实际。合规性挑战:没有适当的机制来确保团队始终如一地运行测试。例如,一些团队可能会将平安扫描内置到其流水线的每个局部中,而其余团队可能不会。您将永远无奈实现合规性。不足合作:很难在不同且断开连接的Jenkins控制器之间切换工作。如果一个团队发现了一种更无效地做事的新办法,他们没有方法与其余孤立的团队共享这些信息。隐性老本:工程师不应该节约他们贵重的工夫和资源来保护一系列Jenkins实例和配置。请记住:没有人是一座孤岛,Jenkins控制器也一样。 优化和扩大Jenkins,实现更快、更牢靠的DevOps无论是Jenkins扩张、单体控制器、插件破绽、耗时的治理工作,还是一直收缩的基础设施老本,治理和扩大开源Jenkins(更不用说发明一种文化,突破孤岛,每个人都在一个共享的愿景)都是一项艰巨的工作。为了实现这所有,您须要为所有运行Jenkins的开发团队提供共享、集中管理、受管控的体验——这正是CloudBees CI所提供的。 文章起源:https://www.cloudbees.com/blo... 如需理解更多CloudBees CI的相干信息,请分割CloudBees受权合作伙伴——龙智:官网:www.shdsd.com电话:400-775-5506邮箱:marketing@shdsd.com

August 29, 2022 · 1 min · jiezi

关于ci:用对工具CI事半功倍

Hi!咱们是DevSecOps研发平安经营解决方案提供商、Atlassian寰球白金合作伙伴——龙智。在过来的十多年间,传统软件研发模式发生巨变,从瀑布式开发到麻利再到DevOps,开发和运维之间已经明确的界线正在缓缓变得含糊。 DevOps因为可能促成开发、运维、测试等不同部门的沟通、合作与整合,正在悄悄成为软件研发经营支流趋势。倒退至今,DevOps也联合了新的流程,比方继续集成和继续部署来疾速交付价值。 如果您对DevOps还知之甚少,或是想要更深刻地理解DevOps工具链,请不要错过本系列文章。龙智将从DevOps的概念、DevOps工具链、CI及工具比照、DevOps监控、DevSecOps五个方面动手,让您从起源开始,逐渐深刻理解DevOps这个已风行数十年的方法论。 撑持CI的根底CI(Continuous integration继续集成,下⽂均简称为CI)建⽴在麻利和DevOps软件开发最佳实际之上,其通过Pipeline实现⾃动化测试、版本控制、⾃动化构建和⾃动化部署。撑持CI的每⼀个根底都有着⾃⼰的⼯具和理念⽣态零碎。软件开发⼯具提供商曾经开始提供残缺的CI即服务(CI-as-a-service)产品,这些产品将撑持CI的根底都捆绑到⼀个整体的包中。为了让您更好地了解捆绑产品,让咱们回顾⼀下CI的根底。 源代码管制版本治理 CI最重要的根底是Pipeline,它从获取源代码到实现部署,连贯并治理着版本控制系统,测试管理系统,编译构建零碎等诸多不同⽬的的⼯具,⽤于沟通和解决在同⼀代码库中⼯作的多个开发⼈员之间的编辑抵触。各种各样的⼯具都提供了源代码版本与配置管理性能,其中,最风行的有Perforce Helix Core、Git和Subversion。CI即服务产品是以版本控制系统为核心的。 Subversion作为第⼆代版本控制管理系统,其采⽤的尽管是集中式的版本治理,且仅具备根本合并性能,但其通过元数据管理版本的⽅式相当易于了解和治理,作为⼀名⽼将,⾄今仍沉闷在泛滥较为小型的开发项⽬当中。 Git是典型的第三代分布式版本控制管理系统,它具备所有DVCS的长处,让您能够随时随地提交您的构想与实际。其灵活多样的分⽀策略是泛滥不同规模开发团队采⽤它的重要起因,但当许多开发人员同时应用Git时,性能和生产效率会降落。 Perforce Helix Core是⼀款⾼效灵便的版本控制软件,它具备集中式或分布式等多种部署样态,可治理大型且简单的二进制文件。其强⼤的压缩传输与⽂件级别的超细颗粒度权限治理,能给企业带来平安,疾速的使⽤体验。 自动化测试 大多数软件我的项目都蕴含一个额定的代码库,此代码库并不明确地负责业务产品和性能。这个主要的代码库是一个测试套件,充当一组断言,确保次要代码库在没有谬误的状况下正确工作。在开发过程中,这些测试由开发人员运行,用来验证新代码没有对现有性能造成任何回归。 这些测试用例也能够通过无关的工具来运行,以自动化这个验证过程。CI服务产品将针对用户指定的事件,主动运行我的项目的测试用例。通常,当开发人员应用版本控制系统推送代码时,一个事件将会触发整个测试套件主动运行。 Bitbucket Pipeline是Atlassian为Bitbucket Cloud产品增加的⼀个重要性能,为了构建强⼤的⾃动化⼯作流程。借助Bitbucket Pipeline,可⾃动执⾏测试。Bitbucket Pipeline使⽤配置即代码来治理和配置基础架构,并与Jira严密集成。 如果您使⽤的是Bitbucket本地部署的Server版或Data Center版,那么能够通过Bamboo来进⾏⾃动化测试。它⽆缝集成Jira和Bitbucket服务器,带有内置的Git分⽀和⼯作流,能够帮忙你依据分⽀名称⾃动检测、构建、测试分⽀并合并到(筹备或⽣产)服务器。 不仅是Bitbucket和Bamboo,Jira还集成了许多测试用例管理工具,能够帮忙您进行自动化测试,例如Xray、Zephyr、TestRail等。 Xray反对多种自动化测试框架,利用自动化脚本的触发性能,真正实现自动化测试,将DevOps的能力进步一个档次。 Zephyr反对将测试增加到打算、开发、缺点跟踪和报告过程中,全副在Jira内治理。 TestRail是基于Web的测试管理工具,可用于治理、跟踪和组织软件测试工作。它遵循集中的测试治理概念,有助于轻松沟通,并可能跨QA团队进行疾速开发工作。 自动化构建  “构建”是为软件我的项目的以后公布版本创立快照的制品。构建通过各种网络分发给最终用户。我的项目通常会采取一组脚本化的步骤来创立构建制品。CI工具通过应用来自版本控制系统的主动触发器,来帮忙简化此构建过程。一个示例触发器是当新代码合并到代码库的生产分支时,将构建文件上传到近程服务器以供用户下载。 您能够使⽤Bitbucket Pipeline来进⾏⾃动化构建。它将在一个bitbucket-pipelines.yml文件中存储和治理您的构建配置,只需7行代码即可开始应用。 同样的,如果您应用Bitbucket的Server版或DC版,Bamboo反对创立多阶段构建打算、设置触发器以在提交时开始构建,并将代理调配给要害的构建和部署。 自动化部署 当构建筹备好散发时,它们要通过一个部署过程。依据我的项目部署的不同,可能会有多种后果。例如,web我的项目被部署到公开可拜访的web服务器上。在此部署期间,在构建阶段生成的制品将复制到web服务器上。挪动端和桌面端的部署过程各不相同,可能须要上传至“利用商店”,以便用户下载应用程序。 在Bitbucket Pipeline中治理部署很轻松,它使部署具备可⻅性,并能跟踪和预览部署状况。 本地部署能够应用Bamboo,单调乏味的部署我的项目将会主动公布到每个环境中,同时让您可能应用按环境授予的权限来管制流程。 CI工具比拟Bitbucket Pipeline 简介:Bitbucket Pipeline是由Atlassian提供的云版本控制系统,它是⼀款间接集成到Bitbucket中的CI/CD⼯具。如果你的项⽬曾经提交到Bitbucket上了,那么Bitbucket Pipeline将是开启CI的⼀个简略步骤。Bitbucket Pipeline脚本作为配置既代码的实际,您能够很容易地执⾏以后版本中的Pipeline脚本来开始构建。此外,Bitbucket Pipeline还提供CD(继续交付),这意味着使⽤Bitbucket Pipeline构建的项⽬也能够通过脚本来部署到软件开发⽣命周期环节中的各种环境中去。理解更多... 特点: 简略的配置对立的Bitbucket体验云托管,缩小运维开销Jenkins 简介:Jenkins是⼀个被⼴泛使⽤的⽼牌CI/CD⼯具。它是开源的,由社区更新驱动。Jenkins是本地部署的。当您的企业须要本地⽀持来解决HIPAA合规性数据等敏感客户时,Jenkins是⼀个很好的抉择。理解更多... 特点: 本地部署开源弱小的插件生态系统Atlassian Bamboo 简介:Atlassian的另⼀款CI/CD 产品。Bitbucket Pipeline纯正是云托管选项,⽽Bamboo提供了⼀个⾃托管的代替⽅案。理解更多... 特点: 与Atlassian产品套件的最佳集成一个扩大的附加组件和插件市场Docker代理的容器反对触发IFTTT 性能的 APICloudBees CI 简介:CloudBees CI相当于Jenkins企业版,同时也是 Jenkins的重要贡献者,其团队奉献了Jenkins中80%以上的代码。CloudBees为企业提供灵便、可管控、可扩大的CI,让开发者领有灵活性的同时,实现大规模、可视化的集中管理。理解更多... 特点: 建设在Jenkins上大规模的集中管理Jenkins实例开发者领有灵活性跟踪管制插件基于角色的权限管制治理什么样的才是适宜公司的CI工具?在为团队抉择CI工具时,有几个重要的决策因素须要思考。 版本控制系统反对CI/CD零碎的外围支柱是底层版本控制系统(VCS)的反对和集成。最受欢迎的版本控制是Perforce Helix Core、Git、Subversion和Mercurial。云CI工具能够为这些VCS中的局部或全副提供反对。抉择一个为您的我的项目VCS提供反对的CI工具是至关重要的。 ...

July 15, 2022 · 1 min · jiezi

关于ci:CloudBees-CI使用Velero进行灾备DR概念验证

企业劫难可能是技术、天然或人为层面的。自然灾害包含洪水、龙卷风、飓风、滑坡、地震和海啸。人为和技术劫难波及的面较广,包含危险物质透露、电力或基础设施故障、化学和生物武器威逼、网络攻击、恐怖主义行为、爆炸和外患。这些都有可能造成企业IT零碎的敞开,以及妨碍企业的整体经营。对于企业来说,停机工夫和技术中断就像一个恐怖故事,所以,您须要一个劫难复原 (DR) 打算。浏览本文,您将理解古代云平台上,CloudBees CI施行此类劫难复原打算的成果。立刻分割CloudBees受权合作伙伴——龙智,取得更多对于CloudBees的征询、试用、服务等信息。 生产环境中部署的要害业务性能,必须有灾备打算,以便在零碎意外解体时,能够将业务迁徙到本地区的其它机房甚至其它地区。 这就是CloudBees决定进行概念验证的起因,可能理解在古代云平台上,为 CloudBees CI施行此类劫难复原打算的成果如何。 CloudBees专一于以下几种场景: CloudBees CI在Elastic Kubernetes Service (EKS)中运行,对于$JENKINS_HOME卷应用Elastic Block Store (EBS),并由Route 53治理域。它演示了应用罕用的OSS Velero我的项目作为备份零碎,对元数据应用简略存储服务(S3),并应用EBS快照来存储次要数据。 为什么CloudBees要抉择这一场景?因为采纳Kubernetes能使咱们关注应用程序自身,而不是基础设施。当在Kubernetes上应用相似Velero的工具时,不仅会备份和复原数据卷,而且还会备份和复原所有元数据。这意味着咱们能够通过一些简略、可移植的命令来运行次要的操作。 除了Velero,我还能应用其余工具吗?是的,当然能够。这篇文章中展现的概念能够用其余开源或商业的备份工具来实现,不论是在Kubernetes上还是其余中央,只有它们可能跨区域同步数据。例如,Google Cloud (GCP) 正在为Google Kubernetes Engine (GKE)提供一个原生的集成备份零碎。 能剧透一下后果吗?能,但持续浏览,您能播种更多乏味的信息和背景。CloudBees进行了测试,测试规模约100个在用的托管控制器,可能达成RPO(Recovery Point Objective)和RTO(Recovery Time Objective)指标。更具体地说,CloudBees能够在每15分钟安顿一次备份的根底上实现较低的RPO,而RTO则在同一范畴内。 CloudBees CI的劫难复原要求一般来说,CloudBees CI的跨区劫难复原有以下几个要求: 文件系统数据,例如$JENKINS_HOME卷,必须在劫难产生之前复制到备用区。因为劫难产生后,复原数据为时已晚。元数据,例如过程列表、网络配置或不在$JENKINS_HOME中的任何内容,也必须提前复制。应该假设次要区域是齐全不可拜访的。管理员必须有一种简略的、大部分是自动化的形式来触发切换(failover)。(当在主区域检测到问题时,不须要主动触发切换。)一旦复原到备用区域,CloudBees CI必须在没有任何严重错误(例如:文件写入不统一等)的状况下启动。故障转移过程必须包含将CloudBees CI的DNS条目切换到新的物理地位,以便任何浏览器书签、webhook或相似组件都可像复原之前那样持续工作。复原工夫指标(RTO)由管理员确定,但通常是一个小时或是更少的工夫。这意味着故障转移过程须要在几分钟内实现,CloudBees CI应该很快启动并运行,随即筹备执行构建。复原点指标(RPO)可能较长,大概为一天,但也可能与RTO相当。因而,只有多数最新的构建或配置更改可能会失落。管理员应该分明地晓得复原的零碎实际上是从备份中复原的,并有机会查看可能因故障转移而中断的任何构建。备注: 因为Jenkins架构,UI将会有一段时间无法访问,任何传入的webhook也会失落。然而,监听hook的零碎,如Multibranch我的项目,应该配置为偶然轮询作为备用。预计可能曾经因为故障转移而中断的构建,不会主动复原或重新启动,也不去尝试保留工作区的内容或节点的实时过程状态。CloudBees CI 中的劫难复原反对CloudBees CI与DR兼容,包含跨区域。从技术角度来看,它波及到以下次要组成部分: Jenkins外围和插件通常将配置和运行时的状态,都保留在文件系统层次结构中。因而,简略地将$JENKINS_HOME卷复制到新地位就足以进行备份。在可行的状况下,元数据文件都是主动编写的,并且尽所有致力容忍失落、截断或损坏的文件,但出于平安起因,也有一些例外。流水线插件的设计目标是容许构建版本在控制器重启时运行。同样的机制也实用于备份和复原或劫难复原场景中的输出等步骤,这些步骤不需节点参加就会暂停。当构建在节点块内的节点上运行,并且因为区域中断或更常见的问题而销毁或失落节点时,以后构建不可能在新的节点上重试这一阶段。然而,这种状况至多能够记录在构建日志和元数据中,并能够从头开始重新启动构建。CloudBees CI蕴含专有的性能,可检测复原场景,向管理员显示专门的告诉,并列举可能或必定受到影响的构建版本。2022年4月公布的CloudBees CI 2.332.2.6版本中有一些性能改良。咱们会持续汲取客户的意见,并作出适当的改良。 Kubernetes上的CloudBees CI还受害于Kubernetes管制立体的弱小容器治理。除了作为StatefulSet运行的经营核心(operations center)和托管控制器(managed controllers)之外,控制器还应用Jenkins Kubernetes插件在一次性节点上安顿构建,无需显式治理基础设施。假如备份区域的集群有足够的容量,那么一旦托管控制器再次启动,复原后的装置就能够运行新的构建。备份不须要蕴含Pod,因为操作核心或治理控制器Pod会主动从新创立。代理Pod无奈从备份中复原。 出于DR目标,CloudBees CI还反对托管控制器休眠。如果在最初一次备份时,托管控制器中只有一部分实际上在运行,那么复原之后也同样如此。交付给复原集群的SCM webhook能够像平常一样“唤醒”休眠的托管控制器并触发构建。 CloudBees CI还提供了配置即代码(CasC)性能。齐全转换为CasC的装置可能不须要传统备份来实现劫难复原;复原操作可简略地包含在新集群中运行CasC疏导脚本。然而,如果您须要保留长期数据(例如构建历史记录),那么出于 DR 目标,可能仍须要从备份执行文件系统级复原。 在AWS上应用VeleroVelero包含一个实用于AWS的规范插件,专门基于S3元数据存储和EBS快照。不过此插件目前暂不提供跨区域反对。 作为这个概念验证的示例,咱们为这个Velero插件开发了自定义补丁,它实现了跨区EBS快照复制。为放弃较低的RPO,咱们还为Velero核开发了自定义补丁,以并行化卷快照操作。能够将备份复原到主区域或failover区域,并在复原时主动抉择适当的快照。 重要提醒:这些补丁应该被认为是实验性的且无奈反对。他们目前的模式不被上游Velero我的项目承受。对Velero的广泛跨地区反对正在探讨中,因为它可能是基于新的基础架构。 此外,咱们还为CloudBees CI开发了简略的Velero插件,该插件并非针对AWS。它在每个StatefulSet中将以后复原的标识符记录为环境变量,这样应用Restart Aborted Builds插件的托管控制器就会收到对于从备份中复原的警报。 演示代码 有配套的存储库和公布版,可演示本篇文章的内容,并对其进行更具体的扩大。 存储库: https://github.com/cloudbees-...公布: cbci-velero-eks留神:这里介绍的架构和代码旨在进行概念验证,并没有制订对于如何在生产环境中部署CloudBees CI的规范。 ...

July 11, 2022 · 1 min · jiezi

关于ci:teamcity-for-administrator

1. 扭转teamcity server配置:Administration (右上)| Global Settings(左中) 2. teamcity 配置(Global Settings下的选项):database:构建的历史,用户及其用户数据以及其余内容存再datebase中。Date Directory:存配置文件,构建后果,和以后操作文件的目录。装置服务的机器上的.BuildServer也存有相干信息。点击broser能够看到很多配置相干的文件。<tc home>/TeamCity/conf/teamcity-startup.properties中保留了TeamCity数据寄存目录。Artifact directories:Build Artifact是一个build产生的文件。此目录寄存Build Artifact,build data,build logs。 3.Version Control SettingDefault VCS changes check interval:默认的检测版本库是否产生扭转的工夫距离。默认60s,能够通过设置VCS root进行设置。Default VCS trigger quiet period:指明了上次VCS变变动到减少一个build到队列中这个时间段。这由teamcity保护。Checkout directory: 4.Edit configuration Settings首先选定我的项目,我的项目个别都有子项目。点击我的项目前的三角形就会列举进去。选中对应我的项目后,点击右上角的build configuration home。能够看到以下几局部: General Settings:Agent requirement:Dependencies一个build配置能够依赖多个配置。能够设置两种类型的依赖:Snapshot Dependency和Artifact Dependency。 Artifact Dependency是获取其余build生成的产品。当没有相应的Snapshot Dependency设置时,它次要用于build的配置与源无关的状况。例如一个为其余build进步可重用组件(文件,压缩包等)的build。 如何增加一个artifact dependency?Dependencies|Add new artifact dependency,此时能够看到如下界面:各项阐明如下: 选项阐明Depend on为以后build配置指明一个要依赖的buil配置Get artifacts from指明build类型,将从这个build获取产品(压缩包,文件等)。类型有:last successful build(获取最近的且build胜利的产品), last pinned build(最近的固定依赖), last finished build(有Snapshot Dependency配置时,产品build和同源build获取), build from the same chain(有Snapshot Dependency配置才无效)Build number抉择last finished build with specified tag才会用到Build branch filter此项只有当依赖中有一个在VCS root settings就指定的分支时才会失效。它容许设置一个分支过滤,从而限度源build只在匹配的分支中进行Artifacts Rules参考下文Clean destination paths before downloading artifacts在copy产品前,查看这个选项去删除目标目录的内容。它将利用到所有蕴含性规定中Artifacts Rules个别格局:[+:|-:]SourcePath[!ArchivePath][=>DestinationPath]每条规定都指明了从源build要下载的文件。SourcePath指明了源build的产品的目录。它要么指明一个具体的文件或目录,要么用通配符匹配多个文件(反对通配符:*匹配任何文件名和目录名,但/和\这两个目录分隔符除外。?匹配除开目录分隔符外的任何一个字符。**匹配任何符号,蕴含目录分隔符)。下载的内容会依据规定中的SourcePath的第一个*或?开始放弃目录构造。DestinationPath指明在agent上的目标目录(放文件的中央)。如果它是相对路径,build checkout directory为当前目录。若指标门路不存在,会把文件下载到checkout根目录。 ...

May 10, 2022 · 1 min · jiezi

关于ci:设计并实现一个简单自动化部署工具

说之前先放地址 https://cycle.bucai.cc/,开发环境运行的,有点慢请急躁期待加载。 GitHub: https://github.com/notbucai/c... 这是我尝试用流程化的思路进行我的项目开发实现的记录。 至于为什么不实用市面上现有且欠缺的框架,是因为我好久没写残缺且有意义的货色了,当然仍然会“借鉴”一些成熟的我的项目。 设计需要起源近期间歇性踌躇满志的对博客性能点进行降级、优化,该我的项目分为后盾nestjs我的项目、前台nuxtjs、管理系统vue.js,目前部署形式采纳Docker进行本地的镜像编译后push到公有仓库后再进入服务器pull之后重启。还有是多人合作开发每个人都须要在本地装置服务器环境(Docker等)来确保环境一致性。 通过上述形容不难发现: 因为我的项目应用的模版、语言以及部署后的状态(动态、服务)都有区别导致编译形式无奈对立。目前的手动部署流程的重复性问题。须要匹配服务器环境,本地开发电脑配置要求高。指标冀望我的项目部署模版化,针对不同类型可抉择不同模板进行打包。将手动部署过渡成自动化部署。依赖分支监控,push主动触发部署,解决本地配置要求高。调研因为大多数人平时工作中都接触是有须要这套工具的,所以调研简略阐明。 调研指标:Netlify(国外)、腾讯云Webify(国内)。 它们解决了什么问题将资源进行部署。CI/CD 工作流。它们的毛病(强行进步当初所做的我的项目高度)Netlify 国外,dddd。Webify云厂商进行运维,保不齐什么时候就开始割韭菜。需要剖析通过上述内容很直观的失去我的项目须要性能点。 外围剖析外围性能是以“工作”为单元进行操作,创立工作和治理工作。 所谓“工作”即须要对状态进行流转的,目前工作分为 进行中、失败、已进行。 每次触发都应该生成一个子工作,如果触发时有进行中的子工作该当进行后启用新工作。 进行中的工作蕴含子状态:编译中、编译胜利、编译失败。用户交互以及外围环节请看下方流程图。 功能设计创立工作 次要对某个仓库的分支进行webhook的注册,并将工作信息写入数据库。 治理工作 次要对创立后的工作信息进行治理,删除、暂停、开始。 开始 对暂停的工作持续进行。 暂停 对正在进行中的工作进行。 删除 删除此条数据,并删除webhook。 工作执行 通过webhook触发执行,找到以后数据进行执行。 工作执行设计如何不同配置进行不同的编译/运行形式? 所有编译都采纳docker进行隔离编译,运行依据不同类型进行抉择不同的形式。 目前辨别两种类型,一种是动态、一种是动静: 动态:采纳采纳docker编译后上传cdn形式,当然只是模仿暂只放nginx动态目录中。动静:应用docker编译后docker运行。webservice无需端口端口nginx 转发资源nginx 转发端口可能须要编译可能须要编译不须要容器运行须要容器运行动作spa我的项目一般网页Ts node 我的项目一般node我的项目构建是否是是编译是否是否运行否否是是上方从资源类型和我的项目类型进行比照,直观的表白了工作的执行动作。 动态资源(web)容器构建后,通过docker cp 将镜像中dist数据copy到主机中,而后转移到nginx中。 服务资源(service)容器构建编译后,再运行起来,而后增加nginx将容器映射到机器端口上。 端口后续进行保护,容器内端口不做治理,靠nginx容器进行映射保护。 用户本人的工作容器之间能够互相通信,通过工作id即可拜访,如果是动态资源须要拜访后续通过配置将接口进行转发,同时用户能够绑定本人的域名到以后机器上。 页面设计前端采纳naive-ui作为前端布局款式组件。 其在交互上次要分为三步: 抉择托管平台 github、gitee等平台,抉择的托管平台必须是受权登录过的。 输出信息 输出工作所必须的数据字段 确认信息 确认输出的是否符合要求 因为设计比较简单,间接以图片模式展现。 工作列表字段:工作名称/ID、托管平台、模版、状态、创建人、创立工夫、更新工夫、操作工夫。 详情页 数据库设计只展现外围表的设计 用户表 托管平台表 模版表 工作表 ...

April 4, 2022 · 2 min · jiezi

关于ci:每日一题二叉搜索树节点最小距离

783. 二叉搜寻树节点最小间隔给你一个二叉搜寻树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。留神:本题与 530:https://leetcode-cn.com/problems/minimum-absolute-difference-in-bst/ 雷同示例 1:输出:root = [4,2,6,1,3]输入:1示例 2:输出:root = [1,0,48,null,null,12,49]输入:1class Solution { //DFS TreeNode pre; int min = Integer.MAX_VALUE; public int minDiffInBST(TreeNode root) { dfs(root); return min; } public void dfs(TreeNode root){ if(root == null) return; dfs(root.left); if(pre != null) min = Math.min(min,root.val - pre.val); pre = root; dfs(root.right); }}

April 18, 2021 · 1 min · jiezi

关于ci:CICD-平台迁移实践从-TravisCI-转移到-Github-Action

LCTT 的 CI 曾经在 Travis CI 上运行了多年,统一放弃着良好的应用体验。自 2019 年 Github 推出了自家的 CI 工具 Github Action 后,咱们就在思考将 CI 从 Travis-CI 迁徙到 Github,以升高保护和沟通的老本,并借助于 GitHub Action Marketplace 实现更强的性能。 最近,因为 TravisCI 每每部署出错,而咱们的账户因为应用的较多,曾经超出了收费应用的限度,以此为契机,将 CI 从 Travis CI 迁徙到 GitHub Action。 我的项目介绍Translate Project 是 LCTT 翻译组的次要合作我的项目,几百位译者通过 GitHub 进行围绕开源、Linux、软件工程等畛域的文章翻译,从 2013 年来,累计了大量的提交,以致我的项目下有十分多的文件。 Translate Project 借助于 CI 帮忙译者对根本的文章格局和拉取申请进行查看;并定时执行命令,以进行所有的申请查看,对于超时未实现翻译的工作进行回收;对于文章的状态进行标记,生成相应的徽章。 迁徙思路Travis CI 和 Github Action 在应用方面,其实总体差别不会太大,都是基于 YAML 文件格式来编写配置文件。不过,和 Travis CI 不同的是,Github Action 反对多个不同的配置文件,因而,你能够依据不同的场景,设定不同的配置文件,升高单个配置的文件的复杂度。 此外,因为咱们的脚本中依赖了一些 Travis CI 的环境变量,也须要将其替换为 Github Action 中的相应环境变量,从而确保脚本能够运行。 ...

January 16, 2021 · 2 min · jiezi

关于ci:Drone-自定义-UI

Drone 是一款开源的 CI/CD 工具,基于容器提供了弱小的插件零碎。多年前我有写过《基于Docker的CI工具——Drone》中有具体的介绍它的长处。Drone 采纳的是 Server/Agent 架构,Server 端用来解决申请派发工作给 Agent,最终在 Agent 上执行工作。 Drone 整体是应用 Golang 写的,drone/drone-ui 是它的前端页面仓库,采纳 Vue.js 进行开发(很早之前是应用 React 进行开发的)。前后端拆散的我的项目,比拟失常的两头会应用 NGINX 之类的 Web Server 进行桥接,用户通过 Web Server 拜访前端页面,而后页面在拜访 Web Server 反代后的接口。不过 Drone Server 端间接是应用的 Golang 本人起的服务,而 Golang 又是一种须要编译的语言。为了能让 Server 编译后还是单文件,作者顺便写了一款工具 bradrydzewski/togo 用来将动态资源编译成 Golang 代码。编译进去的后果实质就是文件路由和内容的哈希表,能够在官网仓库中一窥到底。 将编译后生成的 Golang 文件提交到仓库之后,就能够在 Server 中应用模块的模式将其加载进来,剩下的就是在 Server 中依据路由获取内容返回了。这种做法在开发上会比拟麻烦,不过对应用的人来说倒是不便很多了。不过因为动态资源被编译进了执行文件中,所以咱们如果要自定义前端界面的话,就须要依照这个流程从新构建编译 Server 执行文件了。 构建前端模块首先咱们须要针对 drone/drone-ui 原始仓库进行 Fork,在新的仓库中依据你们的需要进行前端代码的批改。在 RADME 中介绍了如何在开发环境中进行开发。如果改变不大的话,能够在每次 Drone 官网公布版本的时候依据上游仓库提交 Pull Request 进行需要合并。执行 npm run build 会在 dist/files 目录生成最终须要的前端动态资源。 ...

October 26, 2020 · 2 min · jiezi

关于ci:gitlab-钩子

指标:gitlab配置webhook钩子,push代码时触发webhook,向node服务器发送工作,node服务器down代码,执行打包和检测,完结后触发gitlab发邮件。 步骤:1.进入gitlab,找到本人的我的项目,查看是否有权限设置,而后设置:(Settings -> Integrations) URL:http://nodeServerIp:8080/webhook Secret Token:  ABCDEFG // 触发申请的认证码,防止DOS攻打 Trigger:  勾选Push events选项 勾选Merge request events选项  点击“Add web hook” 2.Setting --> General --> Visibility, project features, permissions --> 点击Expand --> 关上Pipelines(Build, test, and deploy your changes)--> Save Changes 3.Settings -> CI /CD --> Pipeline triggers --> Expand在开展的输入框中输出“ci ”,点击“Add trigger”, 而后将生成的Token字段复制进去。 4.在我的项目根目录增加.gitlab-ci.yml文件,文件内容如下: stages:  - ci# 定义 jobbuild:  stage: ci  script: - curl http://nodeServerIp:8080/downGitlabCiShApi > gitlab-ci.sh    - chmod 751 ./gitlab-ci.sh- ./gitlab-ci.sh

October 20, 2020 · 1 min · jiezi

关于ci:CICD-最佳实践的基本原则

继续集成和继续部署(CI/CD)是许多组织应用的麻利办法。它正在帮忙这些组织无效、平安地发行软件。 依据 GitLab 2020 DevSecOps 考察,简直 83%的开发人员示意,他们正在比以前更快、更频繁地公布代码。59%的公司示意他们简直每天都要公布屡次。而这是因为采纳了 DevOps 办法,并且次要归功于继续集成、自动化测试和继续部署。 每个组织都试图在建设 CI/CD 流水线时引入本人的办法,最终找到完满的均衡,咱们通常将其称为“最佳实际”。本文就来谈一些无效且平安的 CI/CD 流水线的根本准则。 可靠性 在软件开发生命周期中领有 CI/CD 流水线工具是组织可能疾速构建和交付应用程序的一大福音,但与此同时,抉择正确的 CI/CD 工具也相当重要,其该当可能随业务组织倒退而扩大,并且运行准确无误。而且,它还应该足够灵便,能够解决多种用例和多种软件交付需要。 CI 流水线该当很快 使 CI/CD 流水线尽可能快是十分重要的。咱们所有的自动化测试都运行在开发环境中的 CI 流水线上,而其最终会被部署到生产环境中。因而,涵盖所有边缘状况和潜在的致命生效十分重要,同时,咱们须要确保所有这些更改不会在咱们的代码中造成任何无奈意料的谬误。因而,同时放弃 CI 流水线简略、疾速和平安十分重要。 随着微服务架构的宽泛采纳,CI 流水线变得简单明了(不同于单体架构的情景)。然而如果流水线工作沉重,最好移除一些不会产生重大影响的测试,并且记录下这种取舍。咱们还应该确定测试的优先程序。运行较快的测试应首先执行。例如,单元测试比拟快,而且是程序性能或模块的根底,因而该当首先执行,而后再进行功能测试和集成测试。这样,咱们能够尽早发现错误并节省时间。开发者应该在推送代码之前在本地运行测试以尽早发现错误。 在独立环境中构建和运行 从 CI/CD 流水线的安全性以及确保它相似于预公布环境和生产环境的角度讲,在独立的环境中运行 CI/CD 流水线始终都很重要,这能够确保咱们的测试后果更加精确。 咱们能够应用 Docker 或其余任何容器化工具来运行咱们的测试套件,也能够在 Docker 容器中为咱们的利用程序安装其余依赖。这样,咱们能够确保测试在齐全隔离的环境中运行,并且不受底层主机的任何影响。因为咱们的 CI/CD 平台能够齐全拜访咱们的代码仓库,因而大多数组织也习惯于在本人的云平台基础设施中部署 CI/CD 工具以确保安全。 许多组织迈出了更大一步,他们还在隔离环境中渲染和测试 UI 组件。在将它们作为独立的构建块交付并集成到一个或多个我的项目中之前,此过程是一种验证它们的确独立的办法(这通常应用 Bit(Github)实现)。 预公布环境和生产环境等价 倡议始终保持预公布环境和生产环境等价,以防止运行测试时发生意外谬误导致公布暂停这种小概率事件。咱们的 CI/CD 流水线首先通过运行测试和在预公布环境中部署的阶段。测试后,该利用会主动降级(或手动部署)到生产环境。 使开发和测试环境齐全等价于生产环境十分艰难,但咱们能够在须要时做出决定放弃他们尽可能类似,并且理解咱们正在做出的取舍。大多数组织还应用“蓝绿部署”或“金丝雀公布”的部署策略,在该策略中,咱们首先在生产环境中部署利用并解决大概 1% 的流量。而后将流量进步到 100%,或者也能够较为轻松的回滚到之前的版本。 总结 所有 CI/CD 工具都不雷同,每个组织都尽可能以最无效和便捷的形式利用 CI/CD。但以上是一些最佳实际,每个人都应留神并遵循这些最佳实际,以防止未来呈现问题。每个组织都应受权并仅通过 CI/CD 流水线来公布软件,以进步代码品质和组织的编码标准。 ...

October 20, 2020 · 1 min · jiezi

如何使用-drone-进行持续集成

什么是 DroneDrone 是一个现代化的继续集成和继续交付平台,使繁忙的团队可能主动构建、测试和公布工作流。应用 Drone 的团队公布软件的频率更高,bug更少。1 人话:Drone 是一个轻量级的 jenkins ,能够简略的实现软件的流水线化测试、编译、部署。并且能够和 gitlab github gogs gitea 轻松的联合到一起。 前提本文对读者作出以下假如: 具备较为丰盛的 git 应用教训能够纯熟的操作某种 git 服务平台,如 gogs、github、gitlab …. 本文以gogs为例具备肯定的 linux 和 docker 的常识储备和操作教训或者也会应用 docker-compose或者懂一点 k8s环境配置: 本文应用 Gogs 为例drone 为以后最新版:1.8.x本文波及到的工程文件:https://github.com/alex-techs/drone-tutorial 本文链接:https://println.org/url/ODQ= 原理个人观点,仅供参考参加角色 角色性能用户GogsDrone ServerDrone 主服务,提供Web界面Drone Runner我了解为实现各种操作的适配器,例如ssh、docker、k8s操作Drone Agent操作宿主机 Docker API 的代理程序Docker Server宿主机的 Doker 程序 装置整个 Drone 体系都是基于docker运行的,所以无需装置,拉下几个镜像即可。当然也能够等运行的时候主动解决。 这里只是列出这些镜像和阐明其作用 主服务docker pull drone/dronedocker操作代理docker pull drone/agentssh runner以 ssh runner 为例 docker pull drone/drone-runner-ssh配置没什么配置,只是几个docker的启动参数而已。 server参数作用DRONE_GOGS_SERVER要连贯的 GOGS 服务器地址DRONE_GIT_ALWAYS_AUTH在克隆公共repo时仍然进行身份认证DRONE_RPC_SECRETDRONE 主服务对外接口的密钥,调用所有接口均须要提供DRONE_SERVER_HOSTDRONE 主服务启动时监听的地址,相似 server_name 的概念DRONE_SERVER_PROTODRONE 主服务启动时的协定,http \\https,非必须DRONE_DEBUG默认false,是否输入debug日志,非必须DRONE_PROVIDER服务提供者,申明是 gogs,非必须DRONE_DATABASE_DATASOURCE申明主服务应用的数据源,非必须DRONE_DATABASE_DRIVER申明主服务应用的数据库驱动,非必须DRONE_GOGS_SKIP_VERIFY是否强制应用TLS与gogs建设链接,默认false,非必须agent参数作用DRONE_RPC_SERVER即 DRONE_SERVER_HOSTDRONE_RPC_SECRET即 DRONE_RPC_SECRETDRONE_DEBUG默认false,是否输入debug日志,非必须DOCKER_HOST宿主机 docker 的 json api 默认监听的地址DRONE_RPC_PROTODRONE 主服务启动时的协定,http \\httpsssh-runner参数作用DRONE_RPC_PROTO即 DRONE_SERVER_PROTODRONE_RPC_HOST即 DRONE_SERVER_HOSTDRONE_RPC_SECRET即 DRONE_RPC_SECRET其它参数大全:https://docs.drone.io/server/reference/ ...

July 10, 2020 · 4 min · jiezi

Gitlab-CICD

gitlab ci: ci.yml配置文件:stages: - ci build: stage: ci script: - curl http://host:port/downGitlabCiShApi > ci.sh - chmod 751 ./ci.sh - ./ci.shgitlab webhook配置:URL: 特定事件被触发后需要回调的URLSecretToken:校验码Trigger: 监听触发的事件

July 7, 2020 · 1 min · jiezi

从0到1了解CICD初学者入门必备

本文先介绍了系统构建的先决技术与实践,自动化构建、版本控制,并给出了Java环境下一些构建工具,然后分别介绍了持续集成(CI)、持续交付和持续部署(CD)的概念及其优势,并在最后给出了一些最佳实践,如确保部署一致、保证良好的测试覆盖率等。 现代软件开发的需求加上部署到不同基础设施的复杂性使得创建应用程序成为一个繁琐的过程。当应用程序出现规模性增长,开发团队人员变得更分散时,快速且不断地生产和发布软件的流程将会变得更加困难。 为了解决这些问题,开发团队开始探索新的策略来使他们的构建、测试和发布流程自动化,以帮助其更快地部署新的生产。这就是持续交付和持续集成发展的由来。 本文将介绍什么是CI/CD并且它是如何帮助团队迅速开发部署经过充分测试、可靠的软件。在了解CI/CD及其优势之前,我们应该讨论这些系统构建的一些先决技术和实践。 自动构建流程 在软件开发过程中,构建流程会将开发人员生成的代码转换为可执行的可用软件。对于Go或者C语言等编译语言,此阶段需要通过编译器运行源代码以生成独立的二进制文件。对于Python或PHP等解释性语言,没有编译的步骤,但是代码依旧需要在特定的时间内冻结、绑定依赖项、打包以便于分发。这些过程通常称为“构建”或“发布”的工件。 虽然开发人员可以手动构建,但这样操作有诸多不利。首先,从主动开发到创建构建的转变中引入了上下文转换,使得开发人员不得不停止生产效率更高的工作来专注于构建过程。其次,每个开发人员都在制作自己的工件,这可能导致构建过程不一致。 为了解决这些顾虑,许多开发团队配置了自动构建流水线。这些系统监视源代码存储库,并在检测到更改时自动启动预配置的构建过程。这一配置无需牵涉过多的人力在其中并且确保了每个构建过程一致。 市场上有许多帮助用户自动化这些步骤的构建工具,以下列出了在Java生态下比较受欢迎的构建工具: Ant:Apache Ant是一个开源Java库,创建于2000年。它是Java领域的原始构建工具,至今仍然被频繁使用。Maven:Apache Maven是一个自动化构建工具,主要是为Java项目编写的。不同于Apache Ant,Maven遵循约定优于配置的原则,仅需要针对偏离合理默认值的构建过程的方面进行配置。Gradle:在2012年推出的1.0版本中,Gradle尝试通过结合Maven的现代功能来融合Ant和Maven的优势,同时又不失Ant提供的灵活性。构建指令是用一种名为Groovy的动态语言编写的。尽管在这个领域,这是一个相对比较新的工具,但它已被广泛采用。版本控制 大部分现代软件开发需要在共享的代码库中进行频繁协作。版本控制系统(VCS)用于帮助维护项目历史记录,并行处理离散特征,以及解决存在冲突的更改。VCS允许项目轻松采用更改并在出现问题时回滚。开发人员可以在本地计算机上处理项目,并使用VCS来管理不同的开发分支。 记录在VCS中的每个更改都称为提交。每个提交都对代码库的更改进行编目分类,元数据也包含在其中,例如关于查看提交历史记录或合并更新的描述。 图1 分布式版本控制 虽然版本控制是一个十分有价值的工具,它能帮助管理在单一代码库中许多不同的更改。但分布式开发通常会为其带来挑战。在没有定期合并到共享集成分支的情况下在代码库的独立分支中进行开发可能会使以后合并更改变得困难。为了避免这一情况,开发人员开始采纳持续集成实践。 持续集成(CI) 持续集成(CI)是一个让开发人员将工作集成到共享分支中的过程,从而增强了协作开发。频繁的集成有助于解决隔离,减少每次提交的大小,以降低合并冲突的可能性。 为了鼓励CI实践,一个强大的工具生态已经构建起来。这些系统集成了VCS库,当检测到更改时,可以自动运行构建脚本并且测试套件。集成测试确保不同组件功能可以在一个组内兼容,使得团队可以尽早发现兼容性的bug。因此,持续集成所生产的构建是经过充分测试的,并且是完全可靠的。 图2 持续集成的过程 持续交付和持续部署(CD) 持续交付和持续部署是在构建持续集成的基础之上的两种策略。持续交付是持续集成的扩展,它将构建从集成测试套件部署到预生产环境。这使得它可以直接在类生产环境中评估每个构建,因此开发人员可以在无需增加任何工作量的情况下,验证bug修复或者测试新特性。一旦部署到staging环境中,就可能需要进行额外的手动和自动测试。 持续部署则更进一步。一旦构建在staging环境中通过了自动测试,持续部署系统将会自动将它部署到生产服务器上。换言之,每个通过测试的构建都是实时的,可供用户及早反馈。这使得团队可以不断发布新特性和修复bug,并以其测试流程提供的保证为后盾。 图3 CI / CD流程路线图 CI/CD的优势 持续集成、交付和部署对软件开发过程有显著的改进。下文将简单介绍一些CI/CD的主要优势: 快速反馈回路 对于一个快速的开发周期,快速反馈回路显得尤为重要。为了能够实时接收反馈,软件必须迅速触达终端用户。而CI / CD可以通过简化更新生产部署来提供实现此目标的平台。通过要求每个更改都经过严格的测试,CI可以帮助降低每个构建的相关风险并因此使得团队可以便捷地向用户发布有价值的特性。 增加可见度 CI/CD通常是指将IT流程的各个步骤按序列组成一条流水线,且该流水线对整个IT团队(包括开发、测试、运维等团队)均可见。因此,每个团队成员可以跟踪系统中的构建状态并且可以确定任何导致测试失败的构建。团队成员通过深入了解代码库的当前状态,可以更轻松地规划最佳行动方案。这样的可见度为这一问题提供了一个明确的答案——“我提交的更改是否破坏了构建?” 简化故障排除 尽管CI的目标是集成并测试每个发生在代码库中的更改,但是更安全的方式是每次提交都是小型的并尽早将它们合并到共享代码存储库中。如此,当找到bug时,确定和问题相关的更改会更加容易。毕竟,根据问题的严重程度,团队可以选择回滚或编写并提交修复,从而减少生产中解决问题的时间。 软件质量更高 自动化构建和部署流程不仅缩短了开发周期,而且帮助团队开发出品质更好的软件。因为每个更改都会经过充分的测试并且至少会部署在一个预生产环境中,因此团队可以毫无顾虑地将更改部署到生产中。不过,只有当代码库的所有级别,从单元测试到更复杂的系统测试,都有良好的测试覆盖率时,才能实现这一点。 集成问题更少 因为自动化测试套件在每次提交时自动生成的构建上运行,所以可以尽早检测并修复集成问题。这使开发人员能够及早了解当前正在进行的工作是否可能影响其代码。它会在一开始就测试由不同贡献者编写的代码是否兼容,而不是在之后可能出现其他问题的时候才开始测试。 有更多的时间专注于开发 CI/CD系统依赖自动化来生产构建并且通过流水线来迁移新的更改。由于不需要手动干预,因此构建和测试不再占用开发团队大块的时间。进而开发人员可以心无旁骛地对代码库进行有效的更改,因为如果构建过程中出现任何问题,自动化系统会通知他们。 持续集成和交付的最佳实践 既然我们已经了解了使用CI/CD的一些优势,那么接下来,我们将讨论一些指导原则来帮助您成功实现这些流程。 对CI / CD流水线负责 开发者直到更改被部署到预生产环境中,才无需对其提交的代码负责。这意味着开发者必须确保他们的代码集成正确并且随时可以部署。如果提交的更改违反了这些要求,则开发人员有责任快速提交修复以避免影响其他人的工作。构建失败应该暂停流水线并阻止不参与修复故障的提交,这使得快速解决构建问题变得至关重要。 确保部署一致 部署过程不需要手动操作,反而流水线需要自动部署流程以确保一致性和可重复性。这减少了将破坏性构建推向生产的可能性,并有助于避免出现一些难以重现的、未经测试的配置。 将代码库提交到版本控制 将每次更改提交到版本控制是十分重要的。这会帮助团队审核所有提交的变更并且让团队可以简单地还原出现问题的提交。同时,也可以保持配置、脚本、数据库和文档的完整性。如果没有版本控制,特别是当多人使用同一个代码库时,会非常容易丢失配置和代码更改或对其处理不当。 提交小的、渐进的更改 开发人员一定要牢记:更改必须是小的。因为等待引入更大批量的更改会延迟测试反馈,会更难以确定问题的根本原因。 良好的测试覆盖率 由于CI / CD的目的是减少手动测试,因此整个代码库应该有一个良好的自动化测试覆盖率,以确保软件按预期运行。此外,还应该定期清理冗余或过时的测试以避免影响流水线。 ...

August 7, 2019 · 1 min · jiezi

从零到一实现前后端分离项目的gitlabci流程

?通过一周的尝试, 终于从0到1把gitlab-ci弄好了, 彻底抛弃travis-ci, 最大的坑还是墙外的东西太慢了, 总是timeout 整个过程分为如下几步: 如何在一个1核2G的云服务器上搭建gitlab: 十分钟搭建Gitlab使用gitlab-runner, 并选择正确的executor如何构建前端镜像如何构建后端镜像编写gitlab-ci.yml, 实现一个完整的前端后分离项目的构建部署1. 使用gitlab-runnergitlab-runner跟gitlab-ci是连体婴, 主要为gitlab-ci打工, 使用镜像的安装方式如下: docker run -d --name gitlab-runner --restart always \ -v /srv/gitlab-runner/config:/etc/gitlab-runner \ -v /var/run/docker.sock:/var/run/docker.sock \ gitlab/gitlab-runner:latest其中挂载卷/srv/gitlab-runner/config/config.toml包含了所有runner的配置信息. 通过挂载/var/run/docker.sock:/var/run/docker.sock,使得容器中的进程可以通过它与Docker守护进程通信 1.1 选择Docker作为runner的executor在启动了gitlab-runner容器后, 执行如下命令进入容器, 注册runner docker exec -it gitlab-runner /bin/bashroot@492ce6ab72f9:/# gitlab-runner register接下来需要填写的信息如下: Please enter the gitlab-ci coordinator URL:你的Gitlab地址: http(s)://gitlab.xxx.comPlease enter the gitlab-ci token for this runner:你的Gitlab admin/runners页面中的tokenPlease enter the gitlab-ci description for this runner:填写描述, 无关紧要Please enter the gitlab-ci tags for this runner (comma separated):填写标签, 没有标签谁都可以用, 是shared-runner, 有标签需要声明才可用, 回车就对了Please enter the executor: docker-ssh, ssh, docker+machine, kubernetes, docker-ssh+machine, docker, parallels, shell, virtualbox:选择你的executor: Docker应该是我观察到最常用的吧Please enter the default Docker image (e.g. ruby:2.6):选择一个默认镜像: 例如 docker:stable-alpine不出意外, 就能在gitlab中看到了 ...

July 11, 2019 · 3 min · jiezi

像-AwesomeGo-一样提升企业-Go-项目代码质量

1. Awesome-Go 项目参与过awesome-go项目的gopher都知道,每个MR都必须满足它以下的要求: Make sure that you've checked the boxes below before you submit PR: [ ] I have added my package in alphabetical order.[ ] I have an appropriate description with correct grammar.[ ] I know that this package was not listed before.[ ] I have added godoc link to the repo and to my pull request.[ ] I have added coverage service link to the repo and to my pull request.[ ] I have added goreportcard link to the repo and to my pull request.[ ] I have read Contribution guidelines, maintainers note and Quality standard.总结出来,就是两项关键质量指标: ...

June 14, 2019 · 4 min · jiezi

github上Go项目使用Travis-CI和Docker-Hub实现持续集成

介绍在本文中,我们将介绍如何使用Github,Travis-CI和Docker Hub创建一个简单的持续集成过程。 项目这次使用的一个项目是自己写的一个爬虫小程序(https://github.com/Han-Ya-Jun... 项目目录news_watch_notice├── cmd //main├── conf├── dis├── Dockerfile├── Makefile├── pkg├── qrcode├── .travis.yml├── README.md├── vendor├── utilsDockerfileFROM alpine:3.6MAINTAINER hanyajun0123@gmail.comRUN apk update && apk add curl bash tree tzdata \ && cp -r -f /usr/share/zoneinfo/Hongkong /etc/localtimeADD news_watch_notice /usr/bin/ADD news_watch_notice.sha /usr/bin/CMD ["news_watch_notice"]makefileTARGET=news_watch_noticePKG=$(TARGET)TAG=latestIMAGE_PREFIX?=hanyajunIMAGE_PREFIX_PRD=hanyajunTARGET_IMAGE_DEV=$(IMAGE_PREFIX)/$(TARGET):$(TAG)TARGET_IMAGE_PRD=$(IMAGE_PREFIX_PRD)/$(TARGET):$(TAG)all: image$(TARGET): CGO_ENABLED=0 go build -o dist/$(TARGET) $(PKG)/cmdgitlog:target: mkdir -p dist git log | head -n 1 > dist/news_watch_notice.sha docker run --rm -i -v `pwd`:/go/src/$(PKG) \ -w /go/src/$(PKG) golang:1.11.5 \ make $(TARGET)image-dev: target cd dist && cp ../Dockerfile ./ && \ docker build -t $(TARGET_IMAGE_DEV) .push-dev: docker push $(TARGET_IMAGE_DEV)image-prd: target cd dist && cp ../Dockerfile ./ && \ docker build -t $(TARGET_IMAGE_PRD) .push-prd: docker push $(TARGET_IMAGE_PRD)clean: rm -rf dist.PHONY: image target clean push $(TARGET).travis.ymllanguage: gogo: # 语言版本号 - "1.11.5" # 默认使用最新版本,注意,需要 "1.10" 版本的时候必须表示为字符串形式,如果写成 1.10 则会使用 1.1 版本;x表示对应前缀的最新版本services: - docker #需要的docker环境install: - make image-dev #buildscript: - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin - make push-dev # pushtravis的配置(https://travis-ci.org)打开项目ci开关 ...

May 16, 2019 · 3 min · jiezi

GitLab-Auto-DevOps功能与Kubernetes集成教程

介 绍在这篇文章中,我们将介绍如何将GitLab的Auto DevOps功能与Rancher管理的Kubernetes集群连接起来,利用Rancher v2.2.0中引入的授权集群端点的功能。通过本文,你将能全面了解GitLab如何与Kubernetes集成,以及Rancher如何使用授权集群端点简化这一集成工作的流程。本文非常适合Kubernetes管理员、DevOps工程师,或任何想将其开发工作流与Kubernetes进行集成的人。 背 景什么是GitLab Auto DevOps?Auto DevOps是在GitLab 10.0中引入的功能,它让用户可以设置自动检测、构建、测试和部署项目的DevOps管道。将GitLab Auto DevOps与Kubernetes集群配合使用,这意味着用户可以无需配置CI / CD资源和其他工具,即可以部署应用程序。 什么是Rancher的授权集群端点?从v2.2.0开始,Rancher引入了一项名为Authorized Cluster Endpoint的新功能,用户可以直接访问Kubernetes而无需通过Rancher进行代理。在v2.2.0之前,如果要直接与下游Kubernetes集群通信,用户必须从各个节点手动检索kubeconfig文件以及API服务器地址。这不仅增加了操作的复杂度,而且还没有提供一种机制来控制通过Rancher管理集群时可用的细化权限。 从Rancher v2.2.0开始,部署Rancher管理的集群时,默认情况下会启用授权群集端点(ACE)功能。ACE将部分Rancher身份验证和授权机制推送到下游Kubernetes集群,允许Rancher用户直接连接到这些集群,同时仍遵守安全策略。 如果您已为某些项目中的某个用户明确授予了权限,则当该用户使用授权集群端点进行连接时,这些权限能自动生效应用。现在,无论用户是通过Rancher还是直接连接到Kubernetes集群,安全性都能得到保障。 授权集群端点功能的相关文档对此有更详细的说明: https://rancher.com/docs/ranc... 注意目前,授权集群端点功能暂时仅适用于使用Rancher Kubernetes Engine(RKE)启动的下游Kubernetes进群。 前期准备要将GitLab Auto DevOps与Rancher管理的Kubernetes集群进行对接,您需要实现准备好: 一个GitLab.com帐户,或一个自托管GitLab实例上的帐户(需已启用AutoDevOps):GitLab.com帐户需要已经配置好了AutoDevOps。如果您使用的是自托管GitLab实例,则可以参考这一GitLab文档了解如何启用AutoDevOps:https://docs.gitlab.com/ee/to...运行版本v2.2.0或更高版本的Rancher实例:您可以以单节点模式启动Rancher(https://rancher.com/quick-start/),也可以创建HA安装(https://rancher.com/docs/ranc...)。Rancher管理的Kubernetes集群:您还需要一个通过RKE配置的、Rancher上管理的集群。此外,集群中需要有一个管理员用户,如果您使用的是GitLab.com,则需要通过公共网络访问控制平面节点。设置Rancher和Kubernetes首先,我们需要先将Rancher和Kubernetes设置好。该过程的第一部分主要涉及收集信息。 注意为简单起见,这些步骤使用的是Rancher中默认的admin帐户。最佳实践要求您使用独立用户执行此类过程,并限制该用户对正在集成GitLab的集群的权限。 登录Rancher并导航到要集成的下游集群。在本演示中,我们将在EC2实例上创建一个名为testing的集群,该集群在Amazon中运行: 在集群的仪表板上,单击顶部的Kubeconfig File按钮。这将打开kubeconfig集群的文件,其中包括授权集群端点的信息。 kubeconfig文件中的第一个条目是通过Rancher服务器的集群端点。向下滚动以标识此集群的授权群集端点,该集群列为单独的集群条目: 在我的示例中,此集群的名称是testing-testing-2,并且端点server是AWS提供的公共IP。 复制server和certificate-authority-data字段的值,不包括引号,并保存它们。 在kubeconfig文件中进一步向下滚动并找到您的用户名和token: 复制token字段(不包括引号)并保存。 接下来解码证书授权机构数据的base64版本,将其转换回原始版本并保存。根据您的工具,一些可行的选项包括: 设置GitLab项目通过我们从Rancher收集的信息,我们现在可以配置GitLab了。我们将首先在GitLab中创建一个新项目,该项目将使用Auto DevOps功能与我们的Kubernetes集群集成。 首先,登录GitLab,然后选择New Project。 在“新建项目”页面上,选择“从模板创建”选项卡。这将为您提供要使用的模板项目列表。选择NodeJS Express,然后单击“Use template”: 为项目命名,并将“可见性级别”设置为“ 公共”。完成后单击“ 创建项目”。 注意在我撰写本文时,可见性级别可以设为“私密”,不过这是GitLab的Auto DevOps实验性功能。 在项目页面左侧的菜单窗格中,选择“设置”>“CI / CD”。展开“ 环境变量”部分,并设置以下变量: 我们这次会禁用下图这些功能,因为我们的简单示例暂时不需要它们,并且它们会延长部署所需的时间。在实际项目中,您可以根据您的实际需求启用其中一些选项: 单击“ 保存变量”以完成GitLab项目配置。 连接GitLab和Rancher现在,我们已准备好将我们的GitLab项目与Rancher管理的Kubernetes集群集成。 ...

April 23, 2019 · 1 min · jiezi

Vue项目构建持续集成阿里云CDN

CDN加速是Web应用性能优化和用户体验提升的至关重要的一环,当一个项目构建部署时,就需要考虑到如何高效的去完成相关资源的CDN部署。本文以一个基于 vue-cli3 构建的项目实例,来简单讲解如何配合Teamcity,自动进行阿里云CDN资源部署和持续集成。项目构建vue-cli3 默认支持将项目以 test、development、production 三种模式构建,其中 production 模式将在 build 后生成 dist目录。我们在项目路径下插入 .env.[mode] 格式的文件就可以实现自定义模式。通常,默认的构建模式无法满足项目研发需求。一个项目至少需要包含本地调试 - 即开发过程中的 development 模式,不生成 dist 静态目录,使用 vue-dev-server运行项目;测试环境 - 即基本的集成测试,需要文件静态化,部署到测试环境;线上环境 - 即用户环境,也需要文件静态化,并做CDN加速等性能优化措施;按照这个模型,我们需要自定义一个 deploy 模式,来实现和普通 production打包后,资源引入路径的区别。首先,环境创建在项目根目录下创建 .env.deploy 文件,添加内容如下:NODE_ENV=productionDEPLOY=onlineNODE_ENV的设置代表webpack构建时使用production模式,即会生成 dist静态目录。DEPLOY的设置,是一个我们定义的变量,用于在配置中区分deploy和production模式。其次,配置文件在 vue.config.js 中,配置 BASE_URL// 根据自定义的变量来进行内容设置let BASE_URL = ‘/‘switch(process.env.DEPLOY) { case ‘online’: BASE_URL = ‘http://web-cdn.xxx.com/' break default: BASE_URL = ‘/’}module.exports = { publicPath: BASE_URL, ….}该配置会使得当程序使用 deploy 模式运行时,打包的资源根路径为我们的CDN地址。最后,构建命令在 package.json 中,配置使用 deploy 模式的打包命令"scripts": { “build”: “vue-cli-service build”, “deploy”: “vue-cli-service build –mode deploy”, …}当用户执行 npm run build 时,会生成以 / 为资源路径的文件;当用户执行 npm run deploy 时,生成 index.html 中的资源路径就变成了我们配置的CDN路径。<!DOCTYPE html><html> <head> <meta charset=utf-8> <meta http-equiv=X-UA-Compatible content=“IE=edge”> <meta name=viewport content=“width=device-width,initial-scale=1”> <link rel=icon href=http://web-cdn.xxx.com/favicon.ico> <title>Demo</title> <link href=http://web-cdn.xxx.com/css/chunk-0fabbc4c.08fa0fd2.css rel=prefetch> <link href=http://web-cdn.xxx.com/css/chunk-1025f268.0dc416de.css rel=prefetch> <link href=http://web-cdn.xxx.com/js/app.84dcc9e6.js rel=preload as=script> </head> <body> <div id=app></div> <script src=http://web-cdn.xxx.com/js/chunk-vendors.614ecc0c.js></script> <script src=http://web-cdn.xxx.com/js/app.84dcc9e6.js></script> </body></html>阿里云CDN配置和上传接下来,我们要做的就是配置一个CDN,并能够把这些资源传上去。首先,在阿里云上配置CDN,做好域名CNAME解析,并获取到阿里云的 accessKeyId、accessKeySecret、Region、BucketName等信息,然后选择一种语言,写好上传脚本。这里我们以Node脚本为例:// oss-deploy.jslet OSS = require(‘ali-oss’)let fs = require(‘fs’)let client = new OSS({ region: ‘oss-cn-hangzhou’, accessKeyId: ‘xxx’, accessKeySecret: ‘xxx’, bucket: ‘xxx’})// 使用async+await方法,实现同步化,方便在失败后重试处理async function put(fileName) { try { let result = await client.put(fileName, ‘../dist/’ + fileName) console.log(‘File Upload Success: ‘, fileName) } catch (e) { console.log(‘File Upload Failed: ‘, fileName) // 这里省略异常/失败的重试 }}// 读取打包后的 dist 路径,按照原文件夹结构,进行上传let readFileList = (path, filesList) => { let files = fs.readdirSync(path) files.forEach(itm => { if (itm) { let stat = fs.statSync(path + itm) if (stat.isDirectory()) { readFileList(path + itm + ‘/’, filesList) } else { filesList.push(path + itm) } } }) return filesList}let dist = readFileList(’../dist/’, [])// 递归执行文件上传操作let i = 0, l = dist.lengthlet uploadAsset = () => { if (i < l) { let name = dist[i].split(’../dist/’)[1] put(name) i++ uploadAsset() }}uploadAsset()执行npm install –save-dev ali-ossnode oss-deploy.js即可看到文件已经被上传到了CDN路径下。持续集成上面的两个模块,已经实现了基本的CDN部署。但我们在项目开发的时候,肯定不希望每次 build完,都去自己执行上传CDN,再去服务器上部署。这里我们再把 TeamCity上实现自动build、一键上线的流程简单阐述。TeamCity上的执行脚本如下:cd /apps/kaleido-cms/git pull -f origin masternpm installnpm run deploygit add dist/*git commit -m “Deploy"git push origin mastercd /apps/kaleido-cms/deploynode oss-deploy.jsssh root@10.0.0.1 “./deploy_cms.sh"ssh root@10.0.0.2 “./deploy_cms.sh"因为线上服务通常是集群模式,而 webpack在不同服务器执行build,会产生不同的哈希值版本号,会导致远程资源无法获取到。所以我们需要在持续集成部署的服务器上做build操作,生成dist路径,上传到git和cdn。最后再到集群的每个服务器上拉取静态文件即可。补充:在同一台服务器上,只要文件完全不变,我们使用vue-cli3构建生成的最终文件的哈希值版本号就不会产生改变。因此,对于用户来说当我们更新版本时,并不会对用户造成所有缓存文件失效的性能和体验影响。在阿里云的CDN上,是使用协商缓存的ETag来进行文件资源缓存,因此重名新文件覆盖旧文件时,如文件内容完全一致,Etag也会保持一致,对用户来讲也不必担心缓存问题;如文件发生变更,用户协商缓存也将无法命中,就会取新的资源文件。有些方法是把静态资源的请求发到Nginx,然后再转发到CDN地址。笔者认为,这样会造成所有资源需要重定向、并且在Nginx上无法设置缓存信息,性能上不如本文介绍的直接构建生成CDN地址的HTML文件的方法。通过这套操作,最终我们实现了在TeamCity上,一键执行打包、上传CDN、部署的整个流程。 ...

April 18, 2019 · 2 min · jiezi

如何在京东云上简单实践CI流程

在如今的互联网时代,随着软件开发复杂度的不断提高,软件开发和发布管理也越来越重要。目前已经形成一套标准的流程,最重要的组成部分就是持续集成及持续交付、部署。在此,我们在京东云上以一个案例简单实践下 CI 流程。在初探前,我们有几个概念和工具需要了解下:1)、CI/CD:持续集成(Continuous Integration,CI),它属于开发人员的自动化流程。成功的 CI 意味着应用代码的新更改会定期构建、测试并合并到共享存储库中。该解决方案可以解决在一次开发中有太多应用分支,从而导致相互冲突的问题。持续交付(Continuous Delivery,CD),通常是指开发人员对应用的更改会自动进行错误测试并上传到存储库(如 GitHub 或容器注册表),然后由运维团队将其部署到实时生产环境中。这旨在解决开发和运维团队之间可见性及沟通较差的问题。因此,持续交付的目的就是确保尽可能减少部署新代码时所需的工作量。持续部署(Continuous Deployment,CD),这是另一种“CD”,指的是自动将开发人员的更改从存储库发布到生产环境,以供客户使用。它主要为了解决因手动流程降低应用交付速度,从而使运维团队超负荷的问题。2)、Jenkins:Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能。3)、Docker:Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。4)、Git:Git(读音为/gt/),是一个开源的分布式版本控制系统,提供代码仓库,可以有效、高速地处理从很小到非常大的项目版本管理。 Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。CI流程设计图:工作流程:开发人员提交代码到Git版本仓库;Jenkins人工/定时触发项目构建;Jenkins拉取代码、代码编码、打包镜像、推送到镜像仓库;Jenkins在Docker主机创建容器并发布主机环境规划:docker-jenkins:构建;拉取代码、代码编码、打包镜像、推送镜像到镜像仓库 116.196.85.174(公) 10.0.0.20 (内)docker-git:代码仓库 116.196.86.207(公) 10.0.0.22 (内)docker-harbor:私有镜像仓库 116.196.88.91(公) 10.0.0.21 (内)buildimage:build docker镜像 116.196.89.139(公) 10.0.0.4 (内)一、主机创建在京东云控制台创建4台云主机,地址:https://console.jdcloud.com/配置如下,购买时数量直接选择4,购买完成后再修改名称,分别为:docker-jenkins、docker-git、docker-harbor、buildimage创建修改名称后如下:二、环境配置1、云主机docker-git1.1. 修改主机名为:docker-git[root@112 ~]# hostnamectl set-hostname docker-git[root@112 ~]# hostname docker-git[root@112 ~]# logout[root@docker-git ~]#Ctrl+D退出后重新登陆生效1.2. 部署Git代码版本仓库安装:[root@docker-git ~]# yum install git -y配置git用户:[root@docker-git ~]# useradd git[root@docker-git ~]# passwd git创建库:[root@docker-git ~]# su git[git@docker-git root]$ cd[git@docker-git ~]$ mkdir tomcat-java-demo.git[git@docker-git ~]$ cd tomcat-java-demo.git/[git@docker-git tomcat-java-demo.git]$ git –bare initInitialized empty Git repository in /home/git/tomcat-java-demo.git/[git@docker-git tomcat-java-demo.git]$ lsbranches config description HEAD hooks info objects refs[git@docker-git tomcat-java-demo.git]$ 2、云主机docker-jenkins2.1. 修改主机名为:docker-jenkins[root@113 ~]# hostnamectl set-hostname docker-jenkins[root@113 ~]# hostname docker-jenkins[root@113 ~]# logout[root@docker-jenkins ~]#Ctrl+D退出后重新登陆生效2.2. jenkins环境部署部署jdk环境及maven[root@docker-jenkins tomcat-java-demo]# cd[root@docker-jenkins ]# mkdir tools[root@docker-jenkins ]# cd tools[root@docker-jenkins tools]# wget https://pocenv-hcc.oss.cn-north-1.jcloudcs.com/jdk-8u191-linux-x64.tar.gz;tar zxf jdk-8u191-linux-x64.tar.gz;mv jdk1.8.0_191/ /usr/local/;ln -s /usr/local/jdk1.8.0_191/ /usr/local/jdk;[root@docker-jenkins tools]# vim /etc/profile######## JDK #######JAVA_HOME=/usr/local/jdk1.8.0_191JAVA_BIN=/usr/local/jdk1.8.0_191/binPATH=$PATH:$JAVA_BINCLASSPATH=$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jarexport JAVA_HOME JAVA_BIN PATH CLASSPATH[root@docker-jenkins tools]# source /etc/profile[root@docker-jenkins tools]# java -versionjava version “1.8.0_191"Java(TM) SE Runtime Environment (build 1.8.0_191-b12)Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode) [root@docker-jenkins tools]# wget https://pocenv-hcc.oss.cn-north-1.jcloudcs.com/apache-maven-3.5.0-bin.tar.gz;tar zxf apache-maven-3.5.0-bin.tar.gz;mv apache-maven-3.5.0 /usr/local/maven[root@docker-jenkins tools]# 安装Jenkins,下载Tomcat二进制包将war包到webapps下即可:[root@docker-jenkins tools]# wget https://pocenv-hcc.oss.cn-north-1.jcloudcs.com/jenkins.war[root@docker-jenkins tools]# wget https://pocenv-hcc.oss.cn-north-1.jcloudcs.com/apache-tomcat-8.5.38.tar.gz[root@docker-jenkins tools]# tar zxf apache-tomcat-8.5.38.tar.gz[root@docker-jenkins tools]# lsapache-maven-3.5.0-bin.tar.gz apache-tomcat-8.5.38 apache-tomcat-8.5.38.tar.gz jdk-8u191-linux-x64.tar.gz jenkins.war[root@docker-jenkins tools]# mv apache-tomcat-8.5.38 /usr/local/tomcat-jenkins[root@docker-jenkins tools]# ls /usr/local/tomcat-jenkins/webapps/docs examples host-manager manager ROOT[root@docker-jenkins tools]# rm -rf /usr/local/tomcat-jenkins/webapps/*[root@docker-jenkins tools]# mv jenkins.war /usr/local/tomcat-jenkins/webapps/ROOT.war[root@docker-jenkins tools]# ll /usr/local/tomcat-jenkins/webapps/total 75520-rw-r–r–. 1 root root 77330344 Mar 15 00:55 ROOT.war[root@docker-jenkins tools]# cd /usr/local/tomcat-jenkins/bin/[root@docker-jenkins bin]# ./startup.shUsing CATALINA_BASE: /usr/local/tomcat-jenkinsUsing CATALINA_HOME: /usr/local/tomcat-jenkinsUsing CATALINA_TMPDIR: /usr/local/tomcat-jenkins/tempUsing JRE_HOME: /usr/local/jdk1.8Using CLASSPATH: /usr/local/tomcat-jenkins/bin/bootstrap.jar:/usr/local/tomcat-jenkins/bin/tomcat-juli.jarTomcat started.[root@docker-jenkins bin]#启动后,浏览器访问(docker-jenkins):http://Jenkins主机公网IP:8080/,按提示输入密码,登录即可。在/root/.jenkins/secrets/initialAdminPassword文件里,查看密码后填入即可按照你自己的需求安装插件设置管理员开始使用Jenkins2.3. 安装DOCKER CE安装所需包yum install -y yum-utils device-mapper-persistent-data lvm2 -y设置稳定存储库yum-config-manager –add-repo https://download.docker.com/linux/centos/docker-ce.repo -y安装DOCKER CE(这一步比较慢,耐心等会儿)yum install docker-ce docker-ce-cli containerd.io -y启动Dockersystemctl start docker3、云主机docker-harbor3.1. 修改主机名为:docker-harbor[root@c-dfjgjesgqe ~]# hostnamectl set-hostname docker-harbor[root@c-dfjgjesgqe ~]# hostname docker-harborCtrl+D退出后重新登陆生效3.2. 企业级harbor镜像仓库部署Habor是由VMWare公司开源的容器镜像仓库。事实上,Habor是在Docker Registry上进行了相应的 企业级扩展,从而获得了更加广泛的应用,这些新的企业级特性包括:管理用户界面,基于角色的访 问控制,AD/LDAP集成以及审计日志等,足以满足基本企业需求。harbor各组件介绍:| 组件 | 功能 | | :——– | :——–| | harbor-adminserver | 配置管理中心 | | harbor-db | MySQL数据库 | | harbor-jobservice | 负责镜像复制 | | harbor-log | 记录操作日志 | | harbor-ui | Web管理页面和API | | nginx | 前端代理,负责前端页面和镜像上传/下载转发 | | redis | 会话 | | registry | 镜像存储 | Harbor安装有3种方式1)在线安装:从Docker Hub下载Harbor相关镜像,因此安装软件包非常小2)离线安装:安装包包含部署的相关镜像,因此安装包比较大3)OVA安装程序:当用户具有vCenter环境时,使用此安装程序,在部署OVA后启动Harb在此我们使用第二种离线安装方式来搭建基于 https 访问的 harbor 镜像仓库。3.2.1. 下载并解压离线安装包harbor离线包下载地址:https://github.com/goharbor/h…为方便下载,我在京东云对象存储上也存了一份,可直接wget:https://pocenv-hcc.oss.cn-nor…[root@docker-harbor ~]# yum install vim wget openssl -y[root@docker-harbor ~]# wget https://pocenv-hcc.oss.cn-north-1.jcloudcs.com/harbor-offline-installer-v1.7.4.tgz[root@docker-harbor ]# tar zxf harbor-offline-installer-v1.7.4.tgz[root@docker-harbor ]# cd harbor[root@docker-harbor harbor]# lltotal 570744drwxr-xr-x 3 root root 23 Apr 1 15:05 common-rw-r–r– 1 root root 939 Mar 4 15:33 docker-compose.chartmuseum.yml-rw-r–r– 1 root root 975 Mar 4 15:33 docker-compose.clair.yml-rw-r–r– 1 root root 1434 Mar 4 15:33 docker-compose.notary.yml-rw-r–r– 1 root root 5608 Mar 4 15:33 docker-compose.yml-rw-r–r– 1 root root 8033 Mar 4 15:33 harbor.cfg-rw-r–r– 1 root root 583086399 Mar 4 15:33 harbor.v1.7.4.tar.gz-rwxr-xr-x 1 root root 5739 Mar 4 15:33 install.sh-rw-r–r– 1 root root 11347 Mar 4 15:33 LICENSE-rw-r–r– 1 root root 1263409 Mar 4 15:33 open_source_license-rwxr-xr-x 1 root root 36337 Mar 4 15:33 prepare3.2.2. 自签http证书1)获取权威认证证书[root@docker-harbor harbor]# mkdir ssl[root@docker-harbor harbor]# cd ssl[root@docker-harbor ssl]# openssl genrsa -out ca.key 4096Generating RSA private key, 4096 bit long modulus……………………………..++…………………………………………………………………………………………………………………….++e is 65537 (0x10001)[root@docker-harbor ssl]# openssl req -x509 -new -nodes -sha512 -days 3650 -subj “/C=ZH/ST=ShangHai/L=ShangHai/O=example/OU=Personal/CN=reg.marin.com” -key ca.key -out ca.crt[root@docker-harbor ssl]# lltotal 8-rw-r–r– 1 root root 2037 Apr 4 18:41 ca.crt-rw-r–r– 1 root root 3243 Apr 4 18:41 ca.key2)获取服务端证书1.Create your own Private Key:[root@docker-harbor ssl]# openssl genrsa -out reg.marin.com.key 4096Generating RSA private key, 4096 bit long modulus………………………………………++………………………………………………………………………………………………………………………………………………………………………………………………….++e is 65537 (0x10001)[root@docker-harbor ssl]# openssl req -sha512 -new -subj “/C=ZH/ST=ShangHai/L=ShangHai/O=example/OU=Personal/CN=reg.marin.com” -key reg.marin.com.key -out reg.marin.com.csr[root@docker-harbor ssl]# lltotal 16-rw-r–r– 1 root root 2037 Apr 4 18:41 ca.crt-rw-r–r– 1 root root 3243 Apr 4 18:41 ca.key-rw-r–r– 1 root root 1708 Apr 4 18:42 reg.marin.com.csr-rw-r–r– 1 root root 3243 Apr 4 18:42 reg.marin.com.key[root@docker-harbor ssl]# cat > v3.ext <<-EOF> authorityKeyIdentifier=keyid,issuer> basicConstraints=CA:FALSE> keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment> extendedKeyUsage = serverAuth> subjectAltName = @alt_names> > [alt_names]> DNS.1=reg.marin.com> DNS.2=reg.marin> DNS.3=marin> EOF[root@docker-harbor ssl]# openssl x509 -req -sha512 -days 3650 -extfile v3.ext -CA ca.crt -CAkey ca.key -CAcreateserial -in reg.marin.com.csr -out reg.marin.com.crtSignature oksubject=/C=ZH/ST=ShangHai/L=ShangHai/O=example/OU=Personal/CN=reg.marin.comGetting CA Private Key[root@docker-harbor ssl]# lltotal 28-rw-r–r– 1 root root 2037 Apr 4 18:41 ca.crt-rw-r–r– 1 root root 3243 Apr 4 18:41 ca.key-rw-r–r– 1 root root 17 Apr 4 18:44 ca.srl-rw-r–r– 1 root root 2098 Apr 4 18:44 reg.marin.com.crt-rw-r–r– 1 root root 1708 Apr 4 18:42 reg.marin.com.csr-rw-r–r– 1 root root 3243 Apr 4 18:42 reg.marin.com.key-rw-r–r– 1 root root 260 Apr 4 18:43 v3.ext3)修改harbor配置,以及为Docker配置服务端证书,key和CA。[root@docker-harbor ssl]# cd ..[root@docker-harbor harbor]# vim harbor.cfg……hostname = reg.marin.comui_url_protocol = httpsssl_cert = ./ssl/reg.marin.com.crtssl_cert_key = ./ssl/reg.marin.com.keyharbor_admin_password = 123456……密码也可以不修改,默认登录用户admin,密码Harbor12345Docker守护进程会将.crt文件解释为CA证书,将.cert文件解释为客户机证书,先将.crt文件转换一份.cert文件。[root@docker-harbor harbor]# cd ssl/[root@docker-harbor ssl]# mkdir -p /etc/docker/certs.d/reg.marin.com[root@docker-harbor ssl]# openssl x509 -inform PEM -in reg.marin.com.crt -out reg.marin.com.cert[root@docker-harbor ssl]# cp reg.marin.com.cert reg.marin.com.key ca.crt /etc/docker/certs.d/reg.marin.com/到此自签成功!3.2.3. 安装DOCKER CE安装所需包yum install -y yum-utils device-mapper-persistent-data lvm2 -y设置稳定存储库yum-config-manager –add-repo https://download.docker.com/linux/centos/docker-ce.repo -y安装DOCKER CE(这一步比较慢,耐心等会儿)yum install docker-ce docker-ce-cli containerd.io -y启动Dockersystemctl start docker通过运行hello-world 映像验证是否正确安装了Docker CE 。docker run hello-world3.2.4. 初始化及安装验证初始化安装:[root@docker-harbor ssl]# [root@docker-harbor ssl]# cd ..[root@docker-harbor harbor]# ./prepareGenerated and saved secret to file: /data/secretkeyGenerated configuration file: ./common/config/nginx/nginx.confGenerated configuration file: ./common/config/adminserver/envGenerated configuration file: ./common/config/core/envGenerated configuration file: ./common/config/registry/config.ymlGenerated configuration file: ./common/config/db/envGenerated configuration file: ./common/config/jobservice/envGenerated configuration file: ./common/config/jobservice/config.ymlGenerated configuration file: ./common/config/log/logrotate.confGenerated configuration file: ./common/config/registryctl/envGenerated configuration file: ./common/config/core/app.confGenerated certificate, key file: ./common/config/core/private_key.pem, cert file: ./common/config/registry/root.crtThe configuration files are ready, please use docker-compose to start the service.执行install.sh脚本,安装harbor仓库注意:在执行install.sh脚本之前,先检查两个问题:1)docker-compose是否安装,否则在运行install.sh时会失败,报错“✖ Need to install docker-compose(1.7.1+) by yourself first and run this script again.”2)docker服务是否正常运行,否则在运行install.sh会失败,报错“Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?”安装Compose运行此命令以下载Docker Compose的当前稳定版本:curl -L “https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)” -o /usr/local/bin/docker-compose对二进制文件应用可执行权限:chmod +x /usr/local/bin/docker-compose执行install.sh脚本,安装harbor仓库[root@docker-harbor harbor]# ./install.sh[Step 0]: checking installation environment …Note: docker version: 18.09.4Note: docker-compose version: 1.24.0[Step 1]: loading Harbor images …bffe2a0fec66: Loading layer [==================================================>] 33.22MB/33.22MB38e174bed467: Loading layer [==================================================>] 8.964MB/8.964MB427e4936ae66: Loading layer [==================================================>] 35.77MB/35.77MB3bfd5214250a: Loading layer [==================================================>] 2.048kB/2.048kBf30df776629d: Loading layer [==================================================>] 3.072kB/3.072kBf87afad43f43: Loading layer [==================================================>] 22.8MB/22.8MB……953717aa0afc: Loading layer [==================================================>] 22.8MB/22.8MBLoaded image: goharbor/registry-photon:v2.6.2-v1.7.4[Step 2]: preparing environment …Clearing the configuration file: ./common/config/adminserver/envClearing the configuration file: ./common/config/core/envClearing the configuration file: ./common/config/core/app.confClearing the configuration file: ./common/config/core/private_key.pemClearing the configuration file: ./common/config/db/env……Generated certificate, key file: ./common/config/core/private_key.pem, cert file: ./common/config/registry/root.crtThe configuration files are ready, please use docker-compose to start the service.[Step 3]: checking existing instance of Harbor …[Step 4]: starting Harbor …Creating network “harbor_harbor” with the default driverCreating harbor-log … doneCreating redis … doneCreating registryctl … doneCreating harbor-db … doneCreating harbor-adminserver … doneCreating registry … doneCreating harbor-core … doneCreating harbor-jobservice … doneCreating harbor-portal … doneCreating nginx … done✔ —-Harbor has been installed and started successfully.—-Now you should be able to visit the admin portal at https://reg.marin.com. For more details, please visit https://github.com/goharbor/harbor .浏览器访问验证:浏览器访问要做域名解析,在本地hosts(C:WindowsSystem32driversetchosts)文件中加入:116.196.88.91 reg.marin.com访问:https://reg.marin.com,并登陆。登录后界面基本操作:新建项目test新建用户marin将用户marin设置为test项目管理员三、环境测试1、远程clone代码测试clone 云主机docker-git上的仓库tomcat-java-demo.git:[root@docker-jenkins ~]# yum install git vim wget -y[root@docker-jenkins ~]# git config –global user.email “hcc@c.com”[root@docker-jenkins ~]# git config –global user.name “hcc”[root@docker-jenkins ~]# git clone git@10.0.0.22:/home/git/tomcat-java-demo.gitCloning into ‘solo’…The authenticity of host ‘10.0.0.22 (10.0.0.22)’ can’t be established.ECDSA key fingerprint is SHA256:XNWQhGsAsqd84k/6OYV3xl1+mPGjtASsxeV1YVLZVas.ECDSA key fingerprint is MD5:b4:bd:16:2b🇩🇪e7:7c:fd:c5:dd:91:75:20:ff:3e:0a.Are you sure you want to continue connecting (yes/no)? yesWarning: Permanently added ‘10.0.0.22’ (ECDSA) to the list of known hosts.git@10.0.0.22’s password⚠️ You appear to have cloned an empty repository.[root@docker-jenkins ~]# lstomcat-java-demo[root@docker-jenkins ~]# ls tomcat-java-demo/doc Dockerfile LICENSE pom.xml README.md src[root@docker-jenkins ~]# 2、拉取Github demo代码模拟生产项目,拉取github上的一个demo,并上传至本地git库[root@docker-jenkins ~]# mv tomcat-java-demo tomcat-java-demo.bak[root@docker-jenkins ~]# git clone https://github.com/dingkai163/tomcat-java-demo.gitCloning into ’tomcat-java-demo’…remote: Enumerating objects: 185, done.remote: Counting objects: 100% (185/185), done.remote: Compressing objects: 100% (165/165), done.remote: Total 185 (delta 5), reused 178 (delta 4), pack-reused 0Receiving objects: 100% (185/185), 4.50 MiB | 870.00 KiB/s, done.Resolving deltas: 100% (5/5), done.[root@docker-jenkins ~]# cd tomcat-java-demo[root@docker-jenkins tomcat-java-demo]# vim .git/config[core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true[remote “origin”] url = git@10.0.0.22:/home/git/tomcat-java-demo.git # 修改为本地的git库地址 fetch = +refs/heads/:refs/remotes/origin/[branch “master”] remote = origin merge = refs/heads/master[root@docker-jenkins tomcat-java-demo]# git add .[root@docker-jenkins tomcat-java-demo]# git status# On branch masternothing to commit, working directory clean[root@docker-jenkins tomcat-java-demo]# git commit -m “all”# On branch masternothing to commit, working directory clean[root@docker-jenkins tomcat-java-demo]# git push origin mastergit@10.0.0.22’s password:Counting objects: 229, done.Compressing objects: 100% (185/185), done.Writing objects: 100% (229/229), 4.52 MiB | 0 bytes/s, done.Total 229 (delta 25), reused 229 (delta 25)To git@10.0.0.22:/home/git/tomcat-java-demo.git * [new branch] master -> master[root@docker-jenkins tomcat-java-demo]#3、自建镜像仓库上传下载用云主机buildimage上传及下载镜像修改主机名为:buildimage[root@c-dfjgjesgqe ]# hostnamectl set-hostname buildimage[root@c-dfjgjesgqe ]# hostname buildimageCtrl+D退出后重新登陆生效安装DOCKER CE安装所需包yum install -y yum-utils device-mapper-persistent-data lvm2 -y设置稳定存储库yum-config-manager –add-repo https://download.docker.com/linux/centos/docker-ce.repo -y安装DOCKER CE(这一步比较慢,耐心等会儿)yum install docker-ce docker-ce-cli containerd.io -y启动Dockersystemctl start docker首先在云主机buildimage上做本地hosts解析[root@buildimage ~]# echo “10.0.0.21 reg.marin.com” >> /etc/hosts其次编辑/etc/docker/daemon.json文件,保存退出[root@buildimage ~]# vim /etc/docker/daemon.json{“insecure-registries”:[“reg.marin.com”] }最后重启下docker,让配置生效[root@buildimage ~]# systemctl restart docker如果没有此步docker login将会报错:[root@buildimage ~]# docker login reg.marin.comUsername (admin): adminPassword: Error response from daemon: Get https://reg.marin.com/v1/users/: x509: certificate signed by unknown authority此时可以通过docker login reg.marin.com 登录harbor,输入用户名及密码:[root@buildimage ~]# docker login reg.marin.comUsername (admin): adminPassword: Login Succeeded在buildimage云主机上构建Tomcat基础镜像,并推送到harbor镜像库:[root@buildimage ~]# mkdir tomcat[root@buildimage ~]# cd tomcat[root@buildimage tomcat]# vim Dockerfile-tomcatFROM centos:7MAINTAINER hanchaochao www.jdcloud.com ENV VERSION=8.5.39 RUN yum install java-1.8.0-openjdk wget curl unzip iproute net-tools -y && \ yum clean all && \ rm -rf /var/cache/yum/RUN wget http://mirrors.shu.edu.cn/apache/tomcat/tomcat-8/v${VERSION}/bin/apache-tomcat-${VERSION}.tar.gz && \ tar zxf apache-tomcat-${VERSION}.tar.gz && \ mv apache-tomcat-${VERSION} /usr/local/tomcat && \ rm -rf apache-tomcat-${VERSION}.tar.gz /usr/local/tomcat/webapps/ && \ mkdir /usr/local/tomcat/webapps/test && \ echo “ok” > /usr/local/tomcat/webapps/test/status.html && \ sed -i ‘1a JAVA_OPTS="-Djava.security.egd=file:/dev/./urandom”’ /usr/local/tomcat/bin/catalina.sh && \ ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime ENV PATH $PATH:/usr/local/tomcat/bin EXPOSE 8080CMD [“catalina.sh”, “run”][root@harbor tomcat]# docker build -t tomcat:v1 -f Dockerfile-tomcat .[root@harbor tomcat]# docker tag tomcat:v1 reg.marin.com/test/tomcat:v1[root@docker-git-harbor tomcat]# docker login reg.marin.com[root@docker-git-harbor tomcat]# docker push reg.marin.com/test/tomcat:v1打开harbor的test仓库,查看镜像已经push成功四、CI流程测试1、Jenkins安装必要插件由于jenkins是离线安装,所有在此需要配置一下插件下载地址:系统管理–>插件管理–>Advanced(高级)修改下方地址,将https修改为http 再点提交若出现问题无法获取插件,请尝试更换地址,如:https://mirrors.tuna.tsinghua…提交后点击可选插件,此时我们可以看到很多可获得插件首先搜索并安装Pipeline插件(如果搜索不到,在已安装中查看是否已经安装完毕)pipeline 是一套运行于jenkins上的工作流框架,将原本独立运行于单个或者多个节点的任务连接起来,实现单个任务难以完成的复杂流程编排与可视化。再安装SCM to job 插件,同上步骤(搜索,安装)。2、Jenkins项目创建创建jobs选择流水线类型到这里我们就开始配置Pipeline script,点击流水线语法,来自动生成我们需要的配置。如下图,我们Git方式,配置Git仓库地址,再添加认证相关。在示例步骤中下拉选择如图选项,在Repository URL中填写docker-git上的git仓库地址,因为没有添加jenkins到docker-git容器的免密码登陆,所以截图中我们可以看到连接被拒绝的一大串红色提示,我们点击添加按钮这里我们使用的是秘钥认证方式,需要在容器docker-jenkins上生成密钥,然后将jenkins上生成的公钥发送到(docker-git)git服务器上,然后将jenkins上的生成的私钥内容粘贴到下图Key中,这样jenkins就可以免交互的拉取git仓库中的代码了。[root@docker-jenkins ~]# ssh-keygenGenerating public/private rsa key pair.Enter file in which to save the key (/root/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa.Your public key has been saved in /root/.ssh/id_rsa.pub.The key fingerprint is:SHA256:RQZ78bcVhLRQi8fWFPYmyvcnOqlxy980QwLsYFT/iz8 root@docker-jenkinsThe key’s randomart image is:+—[RSA 2048]—-+| .o=oooo*.|| .+.o=.* o|| .oo+.Bo.+|| .oo.+o.= || S .o.oo || .+..|| . .o.++|| +oo.E+|| ..+o..o|+—-[SHA256]—–+[root@docker-jenkins ~]# cd[root@docker-jenkins ~]# ls .ssh/id_rsa id_rsa.pub known_hosts[root@docker-jenkins ~]# ssh-copy-id git@10.0.0.22/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: “/root/.ssh/id_rsa.pub”/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed – if you are prompted now it is to install the new keysgit@10.0.0.22’s password: Number of key(s) added: 1Now try logging into the machine, with: “ssh ‘git@10.0.0.22’“and check to make sure that only the key(s) you wanted were added.[root@docker-jenkins ~]# cat .ssh/id_rsa—–BEGIN RSA PRIVATE KEY—–MIIEogIBAAKCAQEAvrI8lBov+W8v+zSGdu2EP4BPP7Ml+T5KUwc2MKX1RNMMNQxctPUf7PjhbJJvuTpPPbS1+9PAlrPhikDrug3K4+sF/Fiy+/YgoVMlEFrXiSJK1xHiErDLA39WGq+E4ssth3JfrQHV+AINGAh1/NR+Uk+YmPDAuQgA1l7jSH1PN6qTdrYt95HbklAA+Q3omAJJ4Uc80lk7ZdMcdCc0OAtHjCfbRv287qrH4U2OKSlOLljiBHBN……—–END RSA PRIVATE KEY—–[root@docker-jenkins ~]# 配置完成后,我们就可以生成Pipeline脚本了。点击下方生成流水线脚本,然后复制方框内的内容。将生成的流水线脚本复制出来,我生成的流水线脚本如下:checkout([$class: ‘GitSCM’, branches: [[name: ‘/master’]], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: ‘9baf7156-9ac6-435d-b0db-86cae51c8fe6’, url: ‘git@10.0.0.22:/home/git/tomcat-java-demo.git’]]])将生成的流水线脚本记录完成后,我们点击左上角返回继续点击配置,完成流水线项目tomcat-java-demo的配置点击流水线,我们所需要的Pipeline脚本如下,将其粘贴到script的拉取代码模块中,并修改分支/master为${branch},其他模块内容自行编写,具体需要修改的地方和脚本如下:node { // 拉取代码 stage(‘Git Checkout’) { checkout([$class: ‘GitSCM’, branches: [[name: ‘${branch}’]], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: ‘9baf7156-9ac6-435d-b0db-86cae51c8fe6’, url: ‘git@10.0.0.22:/home/git/tomcat-java-demo.git’]]]) } // 代码编译 stage(‘Maven Build’) { sh ’’’ export JAVA_HOME=/usr/local/jdk /usr/local/maven/bin/mvn clean package -Dmaven.test.skip=true ’’’ } // 项目打包到镜像并推送到镜像仓库 stage(‘Build and Push Image’) {sh ‘‘‘REPOSITORY=reg.marin.com/test/tomcat-java-demo:${branch}cat > Dockerfile << EOFFROM reg.marin.com/test/tomcat:v1 MAINTAINER marinRUN rm -rf /usr/local/tomcat/webapps/ADD target/.war /usr/local/tomcat/webapps/ROOT.warEOFdocker build -t $REPOSITORY .docker login reg.marin.com -u admin -p 123456docker push $REPOSITORY’’’ } // 部署到Docker主机 stage(‘Deploy to Docker’) { sh ’’’ REPOSITORY=reg.marin.com/test/tomcat-java-demo:${branch} docker rm -f tomcat-java-demo |true docker pull $REPOSITORY docker container run -d –name tomcat-java-demo -p 88:8080 $REPOSITORY ’’’ }}在Pipeline脚本里面我们指定了一个branch参数,所以我们需要传递一个参数变量,这里我们选择参数化构建,默认值为master分支。然后保存配置。3、Jenkins构建任务构建前我们还需要做两个操作:添加reg.marin.com的hosts解析[root@docker-jenkins ~]# echo “10.0.0.21 reg.marin.com” >> /etc/hosts编辑/etc/docker/daemon.json文件,输入如下信息,保存退出[root@docker-jenkins ~]# vim /etc/docker/daemon.json{“insecure-registries”:[“reg.marin.com”] }最后重启下docker,让配置生效[root@docker-jenkins ~]# systemctl restart docker返回到工作台,我们开始构建任务构建开始构建完成可以通过Console Output输出查看jenkins构建流程成功构建会提示: SUCCESS通过浏览器来访问tomcat-java-demo项目:http://Jenkins主机公网IP:88/![图片上传中…]可以看到正常访问,至此在京东云上基ker+Git 的简单CI流程实践已经成功部署了。原参考地址:https://www.toutiao.com/a6中…] ...

April 16, 2019 · 8 min · jiezi

容器环境下的持续集成最佳实践:构建基于 Drone + GitFlow + K8s 的云原生语义化 CI 工作流

云原生 (Cloud Native) 是伴随的容器技术发展出现的的一个词,最早出自 Pivotal 公司(即开发了 Spring 的公司)的一本技术小册子 Migrating to Cloud-Native Application Architectures, 其中定义了云原生应用应当具备的一些特质,如无状态、可持续交付、微服务化等。随后云原生概念被广为引用,并围绕这一概念由数家大厂牵头,成立了 CNCF 基金会来推进云原生相关技术的发展,主要投资并孵化云原生生态内的若干项目,包括了如 Kubernetes / etcd / CoreDNS 等耳熟能详的重要项目。而这张大大的云原生版图仍然在不断的扩展和完善。从个人理解来说,传统的应用由于年代久远,更多会考虑单机部署、进程间通信等典型的“单机问题”,虽然也能工作在容器下,但由于历史包袱等原因,架构上已经很难做出大的调整。而“云原生”的应用大都是从一开始就为容器而准备,很少考虑在单机环境下使用,有些甚至无法脱离容器环境工作;考虑的场景少,从而更轻量,迭代更快。比如 etcd 之于 zookeeper , traefik 之于 nginx 等,相信只要在容器环境下实现一次同样的功能,就能强烈的体会到云原生应用所特有的便捷之处。在 CNCF 的版图下,持续集成与持续交付(Continuous Integration & Delivery)板块一直缺少一个钦定的主角,虽然也不乏 Travis CI、GitLab、Jenkins 这样的知名项目,但最能给人云原生应用感觉的,应该还是 Drone 这个项目,本文将围绕 Drone 结合 GitFlow 及 Kubernetes 介绍一些容器环境下持续集成、持续发布 (CI/CD) 方面的实践经验。主流 CI/CD 应用对比之前我也介绍过基于 Travis CI 的一些持续集成实践。后来经过一些比较和调研,最终选择了 Drone 作为主力 CI 工具。截止本文,团队已经使用 Drone 有 2 年多的时间,从 v0.6 一路用到现在即将发布的 v1.0,虽然也踩了不少坑,但总的来说 Drone 还是可以满足大部分需求,并以不错的势头在完善和发展的。下面这张表总结了主流的几个 CI/CD 应用的特点项目名称开发语言配置语言公有云服务私有部署备注Travis CIRubyYAML有不支持公共项目免费,私有项目 $69/单进程, $129/2 进程CircleCIClojureYAML有不支持单进程免费,$50/加 1 进程Gitlab CIRubyYAML有支持绑定 Gitlab 代码管理JenkinsJavaGroovy无支持 DroneGoYAML有支持Cloud 版本不支持私有项目,自建版本无此限制Travis CI 和 CircleCI 是目前占有率最高的两个公有云 CI,易用性上相差无几,只是收费方式有差异。由于不支持私有部署,如果并行的任务量一大,按进程收费其实并不划算;而且由于服务器位置的原因,如果推送镜像到国内,速度很不理想。Gitlab CI 虽然好用,但和 Gitlab 是深度绑定的,我们的代码托管在 Github,整体迁移代码库的成本太大,放弃。Jenkins 作为老牌劲旅,也是目前市场占有率最高的 CI,几乎可以覆盖所有 CI 的使用场景,由于使用 Java 编写,配置文件使用 Groovy 语法,非常适合 Java 为主语言的团队。Jenkins 显然是可以满足我们需要的,只是团队并非 Java 为主,又已经习惯了使用 YAML 书写 CI 配置,抱着尝鲜的心态,将 Jenkins 作为了保底的选择。综上,最终选择 Drone 的结论也就不难得出了,Drone 即开源,又可以私有化部署,同时作为云原生应用,官方提供了针对 Docker、Docker Swarm、K8s 等多种容器场景下的部署方案,针对不同容器场景还有特别优化,比如在 Docker Swarm 下 Drone 是以 agent 方式运行 CI 任务的,而在 K8s 下则通过创建 K8s Job 来实现,显然充分利用了容器的优势所在,这也是 Drone 优于其他 CI 应用之处。个人还觉得 Drone 的语法是所有 CI 中最容易理解和掌握的,由于 Drone 每一个步骤都是运行一个 Docker 容器,本地模拟或调试也非常容易。一句话概况 Drone,可以将其看做是可以支持私有化部署的开源版 CircleCI,并且目前仍然没有看到有其他主打这个定位的 CI 工具,因此个人认为 Drone 是 CI/CD 方面云原生应用头把交椅的有力竞争者。容器环境下一次规范的发布应该包含哪些内容技术选型完成后,我想首先演示一下最终的成果,希望能直观的体现出 CI 对自动化效率起到的提升,不过这就涉及到一个问题:在容器环境下,一次发布应该包含哪些内容,其中有哪些部分是可以被 CI 自动化完成的。这个问题虽然每家公司各不相同,不过按经验来说,容器环境下一次版本发布通常包含这样一个 Checklist:[ ] 代码的下载构建及编译[ ] 运行单元测试,生成单元测试报告及覆盖率报告等[ ] 在测试环境对当前版本进行测试[ ] 为待发布的代码打上版本号[ ] 编写 ChangeLog 说明当前版本所涉及的修改[ ] 构建 Docker 镜像[ ] 将 Docker 镜像推送到镜像仓库[ ] 在预发布环境测试当前版本[ ] 正式发布到生产环境看上去很繁琐对吗,如果每次发布都需要人工去处理上述的所有内容,不仅容易出错,而且也无法应对 DevOps 时代一天至少数次的发布频率,那么下面就来使用 CI 来解决所有问题吧。CI 流程演示为了对 CI 流程有最直观的认识,我创建了一个精简版的 Github 项目 AlloVince/drone-ci-demo 来演示完整的流程,同时项目对应的 CI 地址是 cloud.drone.io/AlloVince/drone-ci-demo ,项目自动构建的 Docker 镜像会推送到 docker registry 的 allovince/drone-ci-demo,。为了方便说明,假设这个项目的核心文件只有 index.html 一个静态页面。单人开发模式目前这个项目背后的 CI 都已经配置部署好,假设我是这个项目的唯一开发人员,如何开发一个新功能并发布新版本呢?Clone 项目到本地, 修改项目代码, 如将 Hello World 改为 Hello World V2。git add .,然后书写符合约定的 Commit 并提交代码, git commit -m “feature: hello world v2”推送代码到代码库git push,等待数分钟后,开发人员会看到单元测试结果,Github 仓库会产生一次新版本的 release,release 内容为当前版本的 ChangeLog, 同时线上已经完成了新功能的发布。虽然在开发者看来,一次发布简单到只需 3 个指令,但背后经过了如下的若干次交互,这是一次发布实际产生交互的时序图,具体每个环节如何工作将在后文中详细说明。多人开发模式一个项目一般不止一个开发人员,比如我是新加入这个项目的成员,在这个 Demo 中应该如何上线新功能呢?同样非常简单:Clone 项目到本地,创建一个分支来完成新功能的开发, git checkout -b feature/hello-world-v3。在这个分支修改一些代码,比如将Hello World V2修改为Hello World V3git add .,书写符合规范的 Commit 并提交代码, git commit -m “feature: hello world v3”将代码推送到代码库的对应分支, git push origin feature/hello-world如果功能已经开发完毕,可以向 Master 分支发起一个 Pull Request,并让项目的负责人 Code ReviewReview 通过后,项目负责人将分支合并入主干,Github 仓库会产生一次新版本的 release,同时线上已经完成了新功能的发布。这个流程相比单人开发来多了 2 个环节,很适用于小团队合作,不仅强制加入了 Code Review 把控代码质量,同时也避免新人的不规范行为对发布带来影响。实际项目中,可以在 Github 的设置界面对 master 分支设置写入保护,这样就从根本上杜绝了误操作的可能。当然如果团队中都是熟手,就无需如此谨慎,每个人都可以负责 PR 的合并,从而进一步提升效率。GitFlow 开发模式在更大的项目中,参与的角色更多,一般会有开发、测试、运维几种角色的划分;还会划分出开发环境、测试环境、预发布环境、生产环境等用于代码的验证和测试;同时还会有多个功能会在同一时间并行开发。可想而知 CI 的流程也会进一步复杂。能比较好应对这种复杂性的,首选 GitFlow 工作流, 即通过并行两个长期分支的方式规范代码的提交。而如果使用了 Github,由于有非常好用的 Pull Request 功能,可以将 GitFlow 进行一定程度的简化,最终有这样的工作流:以 dev 为主开发分支,master 为发布分支开发人员始终从 dev 创建自己的分支,如 feature-afeature-a 开发完毕后创建 PR 到 dev 分支,并进行 code reviewreview 后 feature-a 的新功能被合并入 dev,如有多个并行功能亦然待当前开发周期内所有功能都合并入 dev 后,从 dev 创建 PR 到 masterdev 合并入 master,并创建一个新的 release上述是从 Git 分支角度看代码仓库发生的变化,实际在开发人员视角里,工作流程是怎样的呢。假设我是项目的一名开发人员,今天开始一期新功能的开发:Clone 项目到本地,git checkout dev。从 dev 创建一个分支来完成新功能的开发, git checkout -b feature/feature-a。在这个分支修改一些代码,比如将Hello World V3修改为Hello World Feature Agit add .,书写符合规范的 Commit 并提交代码, git commit -m “feature: hello world feature A"将代码推送到代码库的对应分支, git push origin feature/feature-a:feature/feature-a由于分支是以feature/命名的,因此 CI 会运行单元测试,并自动构建一个当前分支的镜像,发布到测试环境,并自动配置一个当前分支的域名如 test-featue-a.avnpc.com联系产品及测试同学在测试环境验证并完善新功能功能通过验收后发起 PR 到 dev 分支,由 Leader 进行 code reviewCode Review 通过后,Leader 合并当前 PR,此时 CI 会运行单元测试,构建镜像,并发布到测试环境此时 dev 分支有可能已经积累了若干个功能,可以访问测试环境对应 dev 分支的域名,如 test.avnpc.com,进行集成测试。集成测试完成后,由运维同学从 Dev 发起一个 PR 到 Master 分支,此时会 CI 会运行单元测试,构建镜像,并发布到预发布环境测试人员在预发布环境下再次验证功能,团队做上线前的其他准备工作运维同学合并 PR,CI 将为本次发布的代码及镜像自动打上版本号并书写 ChangeLog,同时发布到生产环境。由此就完成了上文中 Checklist 所需的所有工作。虽然描述起来看似冗长,但不难发现实际作为开发人员,并没有任何复杂的操作,流程化的部分全部由 CI 完成,开发人员只需要关注自己的核心任务:按照工作流规范,写好代码,写好 Commit,提交代码即可。接下来将介绍这个以 CI 为核心的工作流,是如何一步步搭建的。Step by Step 构建 CI 工作流Step.0: 基于 K8s 部署 Drone v1.0.0以 Github 为例,截止本文完成时间(2019 年 3 月 28 日), Drone 刚刚发布了第一个正式版本 v1.0.0。官方文档已经提供了分别基于 Docker、K8s 的 Drone 部署说明,不过比较简略,因此这里给出一个相对完整的配置文件。首先需要在 Github 创建一个 Auth App,用于 repo 的访问授权。应用创建好之后,会得到 Client ID 和 Client Secret 。同时 Authorization callback URL 应填写 Drone 服务对应域名下的 /login,如https://ci.avnpc.com/loginDrone 支持 SQLite、MySQL、Postgres、S3 等多种后端存储,主要用于记录 build logs 等文本信息,这些信息并不是特别重要,且我们的 CI 有可能做迁移,因此个人更推荐使用 SQLite。而在 K8s 环境下,SQLite 更适合用挂载 NAS 的方式供节点使用,因此首先将存储的部分独立为文件drone-pvc.yml,可以根据实际情况配置 nfs.path 和 nfs.serverkubectl apply -f drone-pvc.yamlDrone 的配置主要涉及两个镜像:drone/kubernetes-secrets 加密数据服务,用于读取 K8s 的 secretsdrone/drone:1.0.0-rc.6 就是 Drone 的 server 端,由于在 K8s 下 Drone 利用了 Job 机制,因此不需要部署 agent。这部分配置较长,可以直接参考示例 drone.yaml主要涉及到的配置项包括:drone/kubernetes-secrets 镜像中SECRET_KEY: 数据加密传输所用的 key,可以使用 openssl rand -hex 16 生成一个drone/drone镜像中DRONE_KUBERNETES_ENABLED: 开启 K8s 模式DRONE_KUBERNETES_NAMESPACE: Drone 所使用的 Namespace, 这里使用 defaultDRONE_GITHUB_SERVER: Github 服务器地址,一般为 https://github.comDRONE_GITHUB_CLIENT_ID: 上文创建 Github Auth App 得到的 Client IDDRONE_GITHUB_CLIENT_SECRET: 上文创建 Github Auth App 得到的 Client SecretDRONE_SERVER_HOST: Drone 服务所使用的域名DRONE_SERVER_PROTO: http 或 httpsDRONE_DATABASE_DRIVER: Drone 使用的数据库类型,这里为 sqlite3DRONE_DATABASE_DATASOURCE: 这里为 SQLite 数据库的存放路径DRONE_SECRET_SECRET: 对应上文的 SECRET_KEYDRONE_SECRET_ENDPOINT: 加密数据服务的地址,这里通过 k8s service 暴露,无需修改最后部署即可kubectl apply -f drone.yaml部署后首次登录 Drone 就会跳转到 Github Auth App 进行授权,授权完毕后可以看到所有能读写的 Repo,选择需要开启 CI 的 Repo,点击 ACTIVATE 即可。 如果开启成功,在 Github Repo 的 Settings > Webhooks 下可以看到 Drone 的回调地址。Step.1: Hello World for Drone在正式开始搭建工作流之前,首先可以测试一下 Drone 是否可用。Drone 默认的配置文件是 .drone.yml, 在需要 CI 的 repo 根目录下创建.drone.yml, 内容如下,提交并git push到代码仓库即可触发 Drone 执行 CI。kind: pipeline name: deploy steps: - name: hello-world image: docker commands: - echo “hello world"Drone v1 的语法主要参考的 K8s 的语法,非常直观,无需阅读文档也可以知道,我们首先定义了一个管道 (pipeline),管道由若干步骤 (step) 组成,Drone 的每个步骤是都基于容器实现的,因此 Step 的语法就回到了我们熟悉的 Docker,一个 Step 会拉取 image 定义的镜像,然后运行该镜像,并顺序执行 commands 定义的指令。 在上例中,Drone 首先 clone git repo 代码到本地,然后根据 .drone.yml 所定义的,拉取 Docker 的官方镜像,然后运行该进行并挂载 git repo 的代码到 /drone/src 目录。在 Drone 的界面中,也可以清楚的看到这一过程。本阶段对应代码部分: https://github.com/AlloVince/...Drone 构建记录: https://cloud.drone.io/AlloVi...Docker 镜像: 无Step.2: 单人工作流,自动化单元测试与 Docker 镜像构建有了 Hello World 的基础,接下来我们尝试将这个工作流进行扩充。为了方便说明,这里假设项目语言为 js,项目内新增了test/index.js文件用于模拟单元测试,一般在 CI 中,只要程序的返回值为 0,即代表运行成功。这个文件中我们仅仅输出一行 Log Unit test passed用于模拟单元测试通过。 我们希望将代码打包成 Docker 镜像,根目录下增加了 Dockerfile 文件,这里直接使用 Nginx 的官方镜像,构建过程只有 1 行COPY index.html /usr/share/nginx/html/, 这样镜像运行后可以通过 http 请求看到index.html的内容。至此我们可以将工作流改进为:当 master 分支接收到 push 后,运行单元测试当 github 发布一次 release, 构建 Docker 镜像,并推送到镜像仓库对应的 Drone 配置文件如下kind: pipeline name: deploy steps: - name: unit-test image: node:10 commands: - node test/index.js when: branch: master event: push - name: build-image image: plugins/docker settings: repo: allovince/drone-ci-demo username: allovince password: from_secret: DOCKER_PASSWORD auto_tag: true when: event: tag虽然比 Hello World 复杂了一些,但是可读性仍然很好,配置文件中出现了几个新概念:Step 运行条件, 即 when 部分,上例中展示了当代码分支为 master,且收到一个 push;以及当代码被标记 tag 这两种情况。Drone 还支持 repo、运行结果等很多其他条件,可以参考 Drone Conditions 文档。Plugin 插件,上例中用于构建和推送镜像的是 plugins/docker 这个 Plugin, 一个 Plugin 本质上仍然是一个 Docker 镜像,只是按照 Drone 的规范接受特定的输入,并完成特定的操作。所以完全可以将 Plugin 看做一个无法更改 command 的 Docker 镜像。Docker 这个 Plugin 由 Drone 官方提供,用于 Docker 镜像的构建和推送,具体的用法可以查看Docker 插件的文档 。例子中演示的是将镜像推送到私有仓库,如果不做特殊配置,镜像将被推送到 Docker 的官方仓库。 此外 Docker 插件还有一个很方便的功能,如果设置 auto_tag: true,将根据代码的版本号自动规划 Docker 镜像的标签,如代码版本为1.0.0,将为 Docker 镜像打三个标签 1, 1.0, 1.0.0。如果代码版本号不能被解析,则镜像标签为 latest。目前 Drone 的插件已经有很多,可以覆盖主流的云服务商和常见的工作流,并且自己制作插件的成本也不高。Secret 加密数据,镜像仓库的用户名和密码都属于敏感信息,因此可以使用 from_secret 获取加密数据。一条加密数据就是一个 key / value 对,如上例中的 DOCKER_PASSWORD 就是我们自己定义的加密数据 key。即便加密数据在 log 中被打印,UI 也只能看到 。加密数据的 value 需要提前保存好,保存的方式有 3 种:通过 Drone UI 界面中, repo -> Settings -> Secrets 添加,所添加的加密数据将保存在 Drone 的数据库中,仅能在当前 repo 中使用。通过Drone cli 加密后保存在 .drone.yml文件中, 使用范围仅限 yaml 文件内通过 K8s 保存为K8s Secret,称为 External Secrets,所有的 repo 都可以共享。如果是团队使用的话,这种保存方式显然是最方便的,但也要注意安全问题,因此 External Secrets 还支持 repo 级别的权限管理, 可以只让有当前 repo 写入权限的人才能使用对应 secret。这个阶段对应代码仓库: https://github.com/AlloVince/...push 时触发的 Drone CI: https://cloud.drone.io/AlloVi...release 时触发的 Drone CI: https://cloud.drone.io/AlloVi...release 后 CI 构建的 Docker 镜像: allovince/drone-ci-demo:latestStep.3: GitFlow 多分支团队工作流上面的工作流已经基本可以应付单人的开发了,而在团队开发时,这个工作流还需要一些扩展。不需要引入 Drone 的新功能,只需要在上文基础上根据分支做一点调整即可。首先保证单元测试位于 steps 的第一位,并且限定团队工作的分支,在 push 和 pull_request 时,都能触发单元测试。- name: unit-test image: node:10 commands: - node test/index.js when: branch: include: - feature/ - master - dev event: include: - push - pull_request然后根据 Gitflow 的流程对于不同的分支构建 Docker 镜像并打上特定标签,以 feature 分支为例,下面的配置约定了当分支名满足 feature/,并收到 push 时,会构建 Docker 镜像并打标签,标签名称为当前分支名去掉 feature/。如分支 feature/readme, 对应 docker 镜像为 allovince/drone-ci-demo:readme,考虑到 feature 分支一般都出于开发阶段,因此新的镜像会覆盖旧的。配置如下- name: build-branch-image image: plugins/docker settings: repo: allovince/drone-ci-demo username: allovince password: from_secret: DOCKER_PASSWORD tag: - ${DRONE_BRANCH##feature/} when: branch: feature/ event: push镜像的 Tag 处不再使用自动方式,其中DRONE_BRANCH是 Drone 的内置环境变量 (Environment),对应当前的分支名。##feature/是执行了一个字符串的替换操作 (Substitution)。更多的环境变量和字符串操作都可以在文档中找到。以此类推,可以查看这个阶段的完整 .drone.yml ,此时我们的工作流示例如下:团队成员从 dev 分支 checkout 自己的分支 feature/readme向feature/readme提交代码并 push, CI 运行单元测试,构建镜像allovince/drone-ci-demo:readme功能开发完成后,团队成员向 dev 分支 发起 pull request , CI 运行单元测试团队其他成员 merge pull request, CI 运行单元测试,构建镜像allovince/drone-ci-demo:test运维人员从 dev 向 master 发起 pull request,CI 运行单元测试,并构建镜像allovince/drone-ci-demo:latest运维人员 merge pull request, 并 release 新版本 pre-0.0.2, CI 构建镜像allovince/drone-ci-demo:pre-0.0.2可能细心的同学会发现 dev -> master 的 pull request 时,构建镜像失败了,这是由于 Drone 出于安全考虑限制了在 pull request 时默认无法读取加密数据,因此无法得到 Docker Registry 密码。如果是私有部署的话,可以在 Repo Settings 中勾选Allow Pull Requests,此处就可以构建成功。Step.4: 语义化发布上面基本完成了一个支持团队协作的半自动 CI 工作流,如果不是特别苛刻的话,完全可以用上面的工作流开始干活了。不过基于这个工作流工作一段时间,会发现仍然存在痛点,那就是每次发布都要想一个版本号,写 ChangeLog,并且人工去 release。标记版本号涉及到上线后的回滚,追溯等一系列问题,应该是一项严肃的工作,其实如何标记早已有比较好的方案,即语义化版本。在这个方案中,版本号一共有 3 位,形如 1.0.0,分别代表:主版本号:当你做了不兼容的 API 修改,次版本号:当你做了向下兼容的功能性新增,修订号:当你做了向下兼容的问题修正。虽然有了这个指导意见,但并没有很方便的解决实际问题,每次发布要搞清楚代码的修改到底是不是向下兼容的,有哪些新的功能等,仍然要花费很多时间。而语义化发布 (Semantic Release) 就能很好的解决这些问题。语义化发布的原理很简单,就是让每一次 Commit 所附带的 Message 格式遵守一定规范,保证每次提交格式一致且都是可以被解析的,那么进行 Release 时,只要统计一下距离上次 Release 所有的提交,就分析出本次提交做了何种程度的改动,并可以自动生成版本号、自动生成 ChangeLog 等。语义化发布中,Commit 所遵守的规范称为约定式提交 (Conventional Commits)。比如 node.js、 Angular、Electron 等知名项目都在使用这套规范。语义化发布首先将 Commit 进行分类,常用的分类 (Type) 有:feat: 新功能fix: BUG 修复docs: 文档变更style: 文字格式修改refactor: 代码重构perf: 性能改进test: 测试代码chore: 工具自动生成每个 Commit 可以对应一个作用域(Scope),在一个项目中作用域一般可以指不同的模块。当 Commit 内容较多时,可以追加正文和脚注,如果正文起始为BREAKING CHANGE,代表这是一个破坏性变更。以下都是符合规范的 Commit:feat: 增加重置密码功能fix(邮件模块): 修复邮件发送延迟BUGfeat(API): API重构BREAKING CHANGE: API v3上线,API v1停止支持有了这些规范的 Commit,版本号如何变化就很容易确定了,目前语义化发布默认的规则如下Commit版本号变更BREAKING CHANGE主版本号feat次版本号fix / perf修订号因此在 CI 部署 semantic-release 之后,作为开发人员只需要按照规范书写 Commit 即可,其他的都由 CI 完成。具体如何将语义化发布加入 CI 流程中呢, semantic-release 是 js 实现的,如果是 js 的项目,可以直接在package.json中增加配置项,而对于任意语言的项目,推荐像 Demo 中一样,在根目录下增加 配置文件release.config.js。这个配置目的是为了禁用默认开启的 npm 发布机制,可以直接套用。semantic-release 要执行 Github release,因此我们需要在 CI 中配置自己的 Personal access tokens 让 CI 有 Github repo 的读写权限, 可以通过 Github 点击自己头像 -> Settings -> Developer settings -> Personal access tokens -> Generate new token 生成一个 Token。 然后在 Drone 的 repo 设置界面新增一个 Secret, key 为 GITHUB_TOKEN, value 填入刚生成的 Token。最后在 .drone.yml 中增加这样一段就可以了。- name: semantic-release image: gtramontina/semantic-release:15.13.3 environment: GITHUB_TOKEN: from_secret: GITHUB_TOKEN entrypoint: - semantic-release when: branch: master event: push来再次模拟一下流程,feature 分支部分与上文相同从 dev 向 master 发起 pull request,CI 运行单元测试,并构建镜像allovince/drone-ci-demo:latestmerge pull request,CI 会执行单元测试并运行 semantic-release , 运行成功的话能看到 Github 新增 release v1.0.0Github release 再次触发CI 构建生产环境用 Docker 镜像allovince/drone-ci-demo:1.0.0最终我们能得到这样一个赏心悦目的 releaseStep.5: Kubernetes 自动发布Docker 镜像推送到仓库后,我们还剩最后一步就可以完成全自动发布的闭环,即通知 Kubernetes 将镜像发布到生产环境。这一步实现比较灵活,因为很多云服务商在容器服务都会提供 Trigger 机制,一般是提供一个 URL,只要请求这个 URL 就可以触发容器服务的发布。Demo 中我们使用更为通用的方法,就是将 kubectl 打包为容器,以客户端调用 K8s 集群 Master 节点 API ( kube-apiserver ) 的形式完成发布。假设我们在生产环境下 drone-ci-demo 项目的 K8s 发布文件如下— apiVersion: extensions/v1beta1 kind: Deployment metadata: name: ci-demo-deployment namespace: default spec: replicas: 1 template: spec: containers: - image: allovince/drone-ci-demo name: ci-demo restartPolicy: Always对应 .drone.yml 中增加 step 如下。这里使用的插件是honestbee/drone-kubernetes, 插件中kubectl 连接 API 使用的是证书+ Token 的方式鉴权,因此需要先获得证书及 Token, 已经授权的 Token 保存于 k8s secret,可以通过kubectl get secret [ your default secret name ] -o yaml | egrep ‘ca.crt:|token:‘获得并配置到 drone 中,注意插件要求 token 是明文的,需要 base64 解码一下:echo [ your token ] | base64 -d && echo ‘’- name: k8s-deploy image: quay.io/honestbee/drone-kubernetes settings: kubernetes_server: from_secret: KUBERNETES_SERVER kubernetes_cert: from_secret: KUBERNETES_CERT kubernetes_token: from_secret: KUBERNETES_TOKEN namespace: default deployment: ci-demo-deployment repo: allovince/drone-ci-demo container: ci-demo tag: - ${DRONE_TAG} when: event: tag在示例)中,可以看到在语义化发布之后 CI 会将新版本的 Docker 镜像自动发布到 K8s),这里为了演示仅打印了指令并未实际运行。相当于运行了如下的指令:kubectl -n default set image deployment/ci-demo-deployment ci-demo=allovince/drone-ci-demo:v1.0.2由于自动发布的环节势必要接触到生产服务器,需要格外注意安全问题,首推的方式当然是将 CI 和 K8s 集群放于同一内网中,同时可以使用 K8s 的 RBAC 权限控制,为自动发布单独创建一个用户),并删除不必要的权限。后话总结一下,本文展示了从 Hello World 到 单人单分支手动发布 到 团队多分支 GitFlow 工作流 到 团队多分支 semantic-release 语义化发布 到 通知 K8s 全自动发布,如何从零开始一步一步搭建 CI 将团队开发、测试、发布的流程全部自动化的过程,最终能让开发人员只需要认真提交代码就可以完成日常的所有 DevOps 工作。最终 Step 的完成品可以适配之前的所有 Step,如果不太在意实现细节的话,可以在此基础上稍作修改,直接使用。然而写好每一个 Commit 这个看似简单的要求,其实对于大多数团队来说并不容易做到,在实施过程中,经常会遇到团队成员不理解为什么要重视 Commit 规范,每个 Commit 都要深思熟虑是否过于吹毛求疵等等疑问。以 Commit 作为 CI 的核心,个人认为主要会带来以下几方面的影响:一个好的 Commit,代表着开发人员对当前改动之于整个系统的影响,有非常清楚的认识,代码的修改到底算 feat 还是 fix ,什么时候用 BREAKING CHANGE 等都是要仔细斟酌的,每个 Commit 都会在 ChangeLog 里“留底”,从而约束团队不随意提交未经思考的代码,提高代码质量一个好的 Commit 也代表开发人员有能力对所实现功能进行精细的划分,一个分支做的事情不宜过多,一个提交也应该专注于只解决一个问题,每次提交(至少是每次 push )都应该保持系统可构建、可运行、可测试,如果能坚持做到这些,对于合并代码时的冲突解决,以及集成测试都有很大帮助。由于每次发布能清楚的看到所有关联的 Commit 以及 Commit 的重要程度,那么线上事故的回滚也会非常轻松,回滚到哪个版本,回滚后哪些功能会受到影响,只要看 CI 自动生成的 Release 记录就一目了然。如果没有这些,回滚误伤到预期外的功能从而引发连锁反应的惨痛教训,可能很多运维都有过类似经历吧。因此 CI 自动化其实是锦上添花而非雪中送炭,如果团队原本就无视规范,Commit 全是空白或者没有任何意义的单词,分支管理混乱,发布困难,奢望引入一套自动化 CI 来能解决所有这些问题,无疑是不现实的。而只有原本就重视代码质量,有一定规范意识,再通过自动化 CI 来监督约束,团队在 CI 的帮助下代码质量提高,从而有机会进一步改进 CI 的效率,才能形成良性循环。愿天下不再有难发布的版本。References:云原生应用之路相关讨论可以在我的 Telegram Group 给我留言。 ...

April 8, 2019 · 7 min · jiezi

GitLab CI持续集成 - .gitlab-ci.yml

在之前的文章中介绍了:GitLab CI持续集成 - GitLab Runner 安装与注册GitLab CI持续集成-GitLab Runner配置好环境下一步可以正式开始使用GitLab CI进行项目集成,这里以Java项目为例,使用Gradle做为项目自动构建工具,使用Gradle工具做代码质量检查,详情参见使用Gradle做Java代码质量检查。.gitlab-ci.ymlGitlab CI使用YAML文件(.gitlab-ci.yml)来管理项目配置。该文件存放于项目仓库的根目录,它定义该项目如何构建。YAML是一个可读性高,用来表达数据序列的格式。YAML参考了其他多种语言,包括:C语言、Python、Perl,并从XML,电子邮件的数据格式中获得灵感。YAML是"YAML Ain’t a Markup Language"(YAML不是一种标记语言)的递归缩写。在开发的这种语言时,YAML的意思其实是:“Yet Another Markup Language”(仍是一种标记语言),但为了强调这种语言以数据作为中心,而不是以标记语言为重点,而用反向缩略语重命名。 — 维基百科.gitlab-ci.yml文件定义了一系列带有约束说明的任务,这些任务都是以任务名开始要包含script部分,一个.gitlab-ci.yml的例子:stages: - unit-testUnitTest: stage: unit-test tags: - spring-sample script: - gradle test - gradle jacocoTestReport - gradle sonarqube when: always下面详细解释下脚本中字段的含义构建脚本解析stages定义可以被调用的阶段,默认定义为build,test和deploy,执行顺序:相同stage的job可以平行执行。下一个stage的job会在前一个stage的job成功后开发执行这里定义了一个stage:unit-test。下面的UnitTest是定义的一个任务,这个任务在stage为unit-test时执行。tags表示他需要执行的gitlab-runner,这里在一个tag为spring-sample的tag中执行。script代表需要执行的脚本,该例子中执行的脚本包括三步:运行gradle测试进行单元测试覆盖情况检查运行sonarqube进行代码质量检查when定义何时执行任务,可以是on_success,on_failure,always(每次代码更新都触发)或者manual(手动触发)。另外,比较常用的字段还有:before_script 用来定义所有job之前运行的命令,包括部署任务等,可以是一个数组或者是多行字符串after_script 用来定义所有job之后运行的命令。它必须是一个数组或者多行字符串例如:job: before_script: - execute this instead of global before script script: - my command after_script: - execute this after my scriptcache用来指定需要缓存的文件或目录,例如:job1: script: test cache: paths: - binaries/ - .config更多字段可以参考官方文档。运行GitLab CI配置完成之后,当把代码push到版本库中时就可以在CI/CD中看到相关的jobs:进入详情可以看到详细的项目构建信息,可以根据产生的日志跟踪错误原因,这里出错的原因是在gitlab-ruuner中没有安装gradle的环境,安装完gradle环境之后构建任务运行通过。Ubuntu 安装 Java JDK & Gradle引用YAML: https://zh.wikipedia.org/wiki...GitLab CI/CD Pipeline Configuration Reference :https://docs.gitlab.com/ee/ci…通过 .gitlab-ci.yml配置任务:https://github.com/Fennay/git… ...

March 19, 2019 · 1 min · jiezi

Gitlab CI持续集成 - GitLab Runner 安装与注册

前篇文章GitLab CI持续集成-GitLab Runner主要介绍了持续集成,以及GitLab CI持续集成的环境,这边文章主要介绍下GitLab Runner的安装以及使用。GitLab Runner安装需要添加gitlab官方库: # For Debian/Ubuntu/Mint curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash # For RHEL/CentOS/Fedora curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | sudo bash通过命令安装:# MacOSsudo brew install gitlab-ci-multi-runner # For Debian/Ubuntu/Mint sudo apt-get install gitlab-ci-multi-runner # For RHEL/CentOS/Fedora sudo yum install gitlab-ci-multi-runnergitlab-runner 注册首先要先获取gitlab-ci的Token:项目主页 -> Sttings -> CI/CD -> Runners Expand使用命令注册gitlab-runner:gitlab-runner register需要按照步骤输入:输入gitlab的服务URL,这个使用的是https://gitlab.com/输入gitlab-ci的Toekn,获取方式参考上图关于集成服务中对于这个runner的描述给这个gitlab-runner输入一个标记,这个tag非常重要,在后续的使用过程中需要使用这个tag来指定gitlab-runner是否运行在没有tag的build上面。在配置gitlab-ci的时候,会有很多job,每个job可以通过tags属性来选择runner。这里为true表示如果job没有配置tags,也执行是否锁定runner到当前项目选择执行器,gitlab-runner实现了很多执行器,可用在不同场景中运行构建,详情可见GitLab Runner Executors,这里选用Shell模式刷新页面就可以看到新增的一个Runner:这个GitLabRunner就安装好了,下一步就是把项目集成到gitlab-ci中,开始持续集成了。引用GitLab Runner DocumentGitLab Runner Executors

March 18, 2019 · 1 min · jiezi

GitLab CI持续集成-GitLab Runner

GitLab CI是开源的持续集成服务,GitLab Runner是一个开源项目,用于运作任务,并把结果发送回GitLab,它与GitLab CI一起使用。持续集成持续(Continuous integration ,缩写CI)是一种软件工程流程,是将所有软件工程师对于软件的工作副本持续集成到共享主线(mainline)的一种举措。该名称最早由Grady Booch 在他的布区方法中提出,不过他并不支持在一天中进行数次集成。之后举措成为极限编程驱动开发(TDD)的作法中,通常还会搭配自动单元测试。持续集成的提出主要是为解决软件进行系统集成时面临的各项问题。-维基百科持续集成一般包括一些流程:合并代码 安装依赖编译测试发布持续集成必须依靠以下原则:维护一个代码知识库自动构建,通过一个单一指令来达成系统建构一旦代码更改好,下一个阶段应该要进行所有的测试,以确保软件开发的成果匹配预期减少冲突,一天至少提交一次每次变更必须要快速完成,如此一来便可以避免集成问题尽可能的缩小测试环境和正式环境的差距,服务虚拟化通常更容易实现这个目标尽早集成任何人都可以查看最后的建构的结果自动部署持续集成可以快速发现错误,定位错误也比较容易,它的目的就是让产品可以快速迭代,同时还能保证高质量。核心措施代码集成到主干前,必须通过自动化测试。GitLab CIGitLab CI是为GitLab提供持续集成服务的一整套系统。在GitLab8.0以后的版本是默认集成了GitLab-CI并且默认启用的。使用GitLab CI需要在仓库跟目录创建一个gitlab-ci.yml的文件,它用来指定持续集成需要运行的环境,以及要执行的脚本。还需要设置一个gitlab-runner,当有代码push变更的时候,gitlab-runner会自动开始pipeline,并在gitlab上显示持续集成的结果。GitLab RunnerGitLab Runner是使用Go语言编写的,可以做为一个二进制文件运行,不需要特定的语言要求,他创建了一个持续集成的的环境,所需要的程序使用Docker来安装,配置好GitLab Runner运行的环境。GitLab Runner实际上都是docker container,由GitLab Runner来自动创建,运行的环境由GitLab Runner程序控制,使用docker来建立runner,使得每一个虚拟环境都干净,轻量,相互隔离,互不影响。GitLab-Runner一般都是配合GitLab-CI使用的,在GitLab里面定义一个属于这个工程的软件集成脚本,用来自动化地完成一些软件集成工作。GitLab-Runner执行情况如下:本地代码改动变动代码推送到GitLab上GitLab 将这个变动通知GitLab-CIGitLab-CI找出这个工程相关联的gitlab-runnergitlab-runner把代码更新到本地根据预设置的条件配置好环境根据预定义的脚本(一般是.gitlab-ci.yml)执行把执行结果通知给GitLabGitLab显示最终执行的结果gitlab-runner可以在不同的主机上部署,也可以在同一个主机上设置多个gitlab-runner ,还可以根据不同的环境设置不同的环境,比如我们需要区分研发环境,测试环境以及正式环境等。

March 17, 2019 · 1 min · jiezi

官宣!CDF正式成立,Rancher为首届创始团队成员

Linux基金会正式成立CDF(持续交付基金会)!Rancher作为创始团队成员加入CDF,将共同促进持续交付最佳实践。作为OCI创始成员、CNCF核心成员和CNCF管理委员会委员的Rancher,在开源领域的领导力再获认可。2019年3月12日,Linux基金会在开源领导者峰会上宣布正式成立CDF(Continuous Delivery Foundation)持续交付基金会,这一基金会将成为多元化持续集成和交付(CI/CD)领域的新基础。业界领先的容器管理软件提供商Rancher Labs(以下简称Rancher)作为创始团队成员加入CDF,共同促进持续交付最佳实践。作为OCI创始成员、CNCF核心成员和CNCF管理委员会委员的Rancher,此次成为CDF创始成员,再次证明了Rancher在开源领域的影响力和认可度。CDF由Jenkins创始人Kohsuke Kawaguchi牵头组织成立,隶属Linux基金会,是Linux基金会监管下的开源项目组织之一。CDF将作为一个中立的基地,为最重要的开源项目提供持续交付和规范,以加快发布流程。CDF将促进行业顶级开发人员、最终用户和供应商之间的合作,以成立CI/CD和DevOps方法,定义并记录最佳时间,创建培训材料,最终促使世界各地的软件开发团队能实施CI/CD最佳实践。当前,CI/CD在云计算/企业IT领域得到了广泛应用,并迅速拓展到其他垂直行业。随着市场向容器化及云原生技术方向转化,CI/CD系统和相关工具的生态系统发生了根本性变化。现有CD工具的数量有所提升,但并没有关于pipelines和工作流程的行业规范定义,以帮助工作的可移植性。“CDF将建立一个项目社区,推动CI/CD的行业最佳实践和创新。”谷歌开发技术推广部副总裁、Linux基金会和CNCF首席技术官Chris Aniszczyk分享道。Rancher是一家专注于为企业提供容器相关产品及解决方案的专业公司,旗舰产品Rancher是一个开源的企业级Kubernetes平台,是业界首个且唯一可以管理所有云上、所有发行版、所有Kubernetes集群的平台,创造性地解决了生产环境中企业用户可能面临的基础设施不同的困境。Rancher执行统一的安全策略,且拥有简洁直观的界面风格及操作体验,同时还提供了企业应用服务目录、实时监控和告警、日志以及CI/CD Pipeline等一系列拓展功能。对于Rancher作为创始成员加入CDF,Rancher联合创始人及CEO梁胜表示:“Rancher作为Kubernetes管理平台领域的领导者,Rancher 与 Jenkins 和 Spinnaker等领先的CI/CD项目具有悠久的合作历史。Rancher用户在企业容器平台的使用过程当中,会将Rancher强大的功能与现有的CI/CD基础结构相结合。我们为CDF的创建感到非常的兴奋,并期待将这些新的Linux基金会项目整合到Rancher当中。”事实上,这并非是Rancher首次作为创始成员加入开源项目基金会。一直以来,Rancher都是Kubernetes和容器领域的领导者玩家,在Kubernetes和容器生态领域具备极高的认可度和强大的影响力。Rancher是OCI(Open Container Initiatives开放容器联盟)的创始成员和CNCF(Cloud Native Computing Foundation云原生计算基金会)的核心成员,Rancher联合创始人Shannon Williams是CNCF管理委员会委员。同时,Rancher也是全球首批获得CNCF Kubernetes一致性认证的平台。除此之外,Rancher在调研及媒体机构上亦备受关注。2017年,Rancher被著名评测机构Gartner评为最酷云基础设施供应商之一。2018年,Rancher在权威调研机构Forrester的企业级容器平台调研当中处于“领导者”象限。此次作为创始成员加入CDF,不仅再次验证了Rancher的生态认可度和强大影响力,还表明了Rancher在云原生开源领域的决心——Rancher始终是容器开源领域的重大贡献与参与者,未来也将始终秉承开源的理念继续创造优秀的容器产品与解决方案,让容器在企业生产环境中更简单、更快速、更安全地落地。

March 15, 2019 · 1 min · jiezi

【工程化】持续集成

持续集成(Continuous integration,简称CI)是软件开发工程化的关键流程之一。最近跟朋友做个练手的项目,用Jenkins进行持续集成和部署,相关的东西在这里进行一些记录。刚接触不多,一些东西还没有完全理清楚,埋坑待填。CI的概念CI这个概念其实是比较模糊的。这里的“集成”,最早似乎是指代码的集成。阮一峰-持续集成是什么?对相关概念有所阐述。具体而言,就是对提交到分支的代码进行较高频率的构建、测试,通过后就“集成”到主干。这个频率通常为一日多次。这篇文章提到的工作流在目前看来是比较罕见的,里面解释的持续集成跟我们现在常说的持续集成也有不小区别。而现在说起持续集成,往往是指代码提交后,自动触发自动化测试与构建的过程。这时对“集成”的解释大体有两种说法,一种是说,把测试、构建之类的步骤自动化地集成在一起;另一种说,通过测试、构建来判断代码集成得是否成功。总体而言,CI在现在的运用中,是在代码提交后触发的检查步骤,而不是代码提交前的前置步骤。代码提交这一行为,往往根据团队的工作流进行具体定制,不会跟CI强绑定。浏览网上资料的时候要注意,很多时候虽然大家说的都是持续集成这个词,但由于随时间的演化,其内涵可能有很大的不同。CI的工具CI的工具有很多,大体上分为两大类。一种是第三方平台上的,比如你用github,相关的CI平台就有Travis CI,Circle CI等。进行相关配置后,代码提交到github就能自动触发,不需要自己部署服务器,当然,这些CI服务通常是收费的。如果是开源项目会有一定的免费资源。一种是自己部署的,比如Jenkins。这种其实不复杂,规定一个触发方式,是定时触发还是通过github的钩子去触发;然后自己写个脚本做测试、构建。完了之后想要部署的话也是自己写脚本来搞。Jenkins主要是对项目、版本、每次构建做下管理,提供UI让我们进行一些配置。这里我只用过Jenkins,emmm,吐槽一下,上古界面,看起来就没有商用CI平台舒畅…未完待续。

February 12, 2019 · 1 min · jiezi

开发和维护个人开源项目之徽章收集

开发和维护个人开源项目之徽章收集常常在github、npm上看到一个个花花绿绿的badges,这些已经成为了开源项目的标配。这是一篇介绍徽章的文章,同时后面会贴出demo(get到常用的badges)。希望对你也有帮助,欢迎评论或者提issues交流。决定是否使用一个开源项目,最基本两点:是否满足需求;项目质量如何。本文要介绍的徽章就是项目质量的体现之一,它有几个好处:体现项目当前质量;体现项目自动化程度(迭代开发效率);体现项目当前使用情况。看下Vue的徽章:这些徽章不仅使README.md更加美观,通过它们我们也可以获知Vue的构建状态、测试覆盖率,使用情况,最新版本号等等。我整理了一下比较常用的进行了简单分类。常用徽章代码相关是否构建通过,可以通过持续集成工具获取。Vue使用的是CircleCI,我用的Travis CI。构建过程,可以看下Vue的配置文件.circleci/config.yml。大致是:下载依赖 => 代码lint => 测试覆盖率统计 => 端到端测试 => srr-weex测试 => 回归测试 。测试覆盖率统计,数据来源上面的构建过程,将跑完的结果发送到对应平台。Vue使用的codecov.io,我用的 coveralls.io 。代码质量分析,通过 codebeat.co 获取。这个是独立的,从复杂度,代码复用等方面进行分析。Vue没有上这个徽章。应用程度其他的徽章就都可以从shields.io上直接获取了,里面有很多很多的徽章。 选择相应的平台,填写好链接,拿到数据后,shields.io 就能帮你生成相应的badges,还可以进行自定义。github 数据下载量,一般使用npm的下载数据。其他npm上项目的当前版本证书文件大小这些徽章的数据都是动态实时的。代码相关的几个徽章,在仓库有变动时会自动构建分析,从而生成新的数据。总结我觉得最重要的是代码相关的那三个徽章,有点ISO9001认证的感觉,这也正是我们想要的 :) 。最后上个demo,折腾这个demo花了三四天时间,主要在配置karma时绕了很多弯路,点我查看demo。

January 28, 2019 · 1 min · jiezi

是时候了解下Travis CI是什么了

前言首先祝各位朋友新年快乐,工作顺利,事业有成,永无BUG。有些朋友一直疑惑Travis CI是个什么东西,网络上搜索后得知的答案是自动测试,自动发布。自动xx 这个名词貌似非常流行,这也是DevOps的一部分,什么?DevOps是什么?我们下一章讲讲这个。先来解释下“自动”这个词,自动顾名思义是自动完成一些事情,上述的自动测试,并不是各位认知中的人肉测试,而是通过我们自己的规则去测试,例如跑一遍tests内的所有测试,自动发布也是通过脚本对现有项目发布到生产环境中或预发布环境中。万事开头难,咱们只玩简单的。使用想玩起来TravisCi不需要安装任何软件,它的网址是 https://travis-ci.org/ , 你可以选择通过GitHub账号登录他。随后我们可以建立一个github库,就叫它travis_ci_test吧,测试使用就随意点好了。之后点击项目管理 https://travis-ci.org/account… ,会列出你所有的GitHub库通过点击单选按钮将库添加到TravisCi内。添加完成后并没有完事,这时候我们就该认真看看自动测试、集成、发布的脚本怎么写了。配置文件TravisCi为我们准备了超棒的配置文件,你可以在配置文件内随心所欲,例如打开某个目录,执行某条命令,他与dockerfile文件或者shell脚本很类似。只不过运行的容器在travisCi上,并非你本机开发文档:https://docs.travis-ci.com/us…从简单开始,在根目录建立文件 .travis.yml , 下面是具体的配置项language: phpphp:- 7.1before_script:- composer install没错,五行配置就足够了,之后我们回到 https://travis-ci.com/dashboard,点击 trigger a build点击当前项目看看详情。 https://travis-ci.org/CrazyCo...TravisCi 做了几个简单的事情开机克隆你的GITHUB项目composer installphpunit通过测试了就显示success(大绿色) 失败就error喽。下面来看看这个详情页面上都有什么?上图大概展示了以下几点分支名称提交版本执行时间提交时间开发语言作者名称等….下面则是跑的命令行了。具体的配置文件还需要自己去研究,希望我这个头开的还不错吧。感言当你理解了Travis CI后会感觉这是一个多么优秀的产品,程序员要写出好代码是要求,而这些产品扩展。作为一名优秀的程序员,你其实可以这样做写测试用例实现业务提交分支 (TravisCi会自动检测提交并测试)自动部署结束任务看似很复杂,不妨试试?一波免费的广告来!狂撸一款PHP现代化框架 (准备工作) https://segmentfault.com/a/11…这是我正在造的一个轮子 https://github.com/CrazyCodes… ????欢迎关注欢迎加入我的Reader Group 致谢感谢你看到这里,希望本文可以帮到你。谢谢

January 3, 2019 · 1 min · jiezi

集成spring boot + mysql + docker实战

前言网上找过很多文章,关于通过docker构建mysql容器并将应用容器和docker容器关联起来的文章不多。本文将给出具体的范例。此处为项目的源码前置条件该教程要求在宿主机上配置了:dockermavenmysql容器新建一个mysql容器和别的教程没什么区别,这里我们将直接利用官方镜像来启动一个空的mysql容器。完整的内容位于mysql目录之下。只需要直接执行脚本sh start_mysql.sh即可启动一个包含位于container_demo数据库中的user表的数据库。使用语句docker exec -it demo_db mysql -u root -p可以进入容器中的mysql进程并查看我们的初始化情况。spring mvc之后就是初始化一个springmvc项目,同样的源码为src目录下,可以在github上看到。首先使用docker ps查看本地启动的mysql的端口号,并且修改application-dev.yml中的数据库信息。此时可以直接在idea总启动项目。比如这里我看到本地的端口号为32809,所以可以通过32809这个端口号直接访问数据库。在docker中使用的是test环境的配置,所以docker中的配置都应该写在test中。对源码在使用中的问题,欢迎留言或者提issue参考文章Spring Boot with Docker docker指令学习记录customize mysql dockerdocker安装mysql

November 15, 2018 · 1 min · jiezi

安装 gitlab CI 服务.md

安装 gitlab-ce安装依赖包yum install curl policycoreutils openssh-server openssh-clientssystemctl enable sshdsystemctl start sshdyum install postfixsystemctl enable postfixsystemctl start postfixfirewall-cmd –permanent –add-service=httpsystemctl reload firewalld下载 gitlab-ce 镜像vim /etc/yum.repos.d/gitlab-ce.repo[gitlab-ce]name=Gitlab CE Repositorybaseurl=https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el$releasever/gpgcheck=0enabled=1yum makecacheyum install gitlab-ce配置vi /etc/gitlab/gitlab.rbexternal_url ‘http://ip’启动gitlabgitlab-ctl reconfigure遇到报错Error executing action run on resource ’execute[semodule -i /opt/gitlab/embedded/selinux/rhel/7/gitlab-7.2.0-ssh-keygen.pp]stop gitlabyum install libsemanage-static libsemanage-devel安装CI服务下载安装CIwget https://mirrors.tuna.tsinghua.edu.cn/gitlab-runner/yum/el7/gitlab-runner-10.5.0-1.x86_64.rpmrpm -ivh gitlab-runner-10.5.0-1.x86_64.rpmsudo useradd –comment ‘GitLab Runner’ –create-home gitlab-runner –shell /bin/bashgitlab-runner uninstallgitlab-runner install –working-directory /home/gitlab-runner/ –user gitlab-runnergitlab-runner restartgitlab-runner status注册 runnersudo gitlab-ci-multi-runner register– 输入Gitlab CI地址, (e.g. https://gitlab.xunlei.cn/ci)http://192.168.1.249/gitlab/-- 输入项目CI tokenfuXXXXXXXXXX– 输入 Runner 描述(e.g. home.xl9.xunlei.com 测试runner)测试Runner– 输入 Runner 标签,可以多个,用逗号隔开(e.g. 10.10.34.91-dev)251-dev– 输入 Runner 执行的语言 (e.g. shell)shell– 认证是否注册成功sudo gitlab-ci-multi-runner verify编写脚本在项目下面创建.gitlab-ci.ymlstages: - deploydeploy_dev: stage: deploy tags: - 251-dev only: - develop script: - deploy_stage.sh然后在部署服务器上的 gitlab-runner 用户路径下创建deploy_stage.shecho “delete old xyj-admin-api"sudo rm -rf /raid1/www/testsudo git clone git@192.168.1.249:test/xyj-test-api.git /raid1/www/testsudo git fetch –allsudo git reset –hard origin/testecho “=============重启服务====================“source /etc/profilesudo supervisorctl restart testtime=dateecho “部署结束: $time.“echo “================================================“其中 测试项目是被 supervisorctl 管理的要确保几件事改服务器能够正常从远端克隆数据命令几点要带上sudo用户sudo无密码及在tty下可以使用需要参考 Linux sudo 相关操作如果克隆下来的文件放在挂载盘,需要在 ~/ 路径下执行 clone 然后放到对应路径,否则报错 fatal: could not create work tree dir遇到无法克隆,且 gitlab 日志为gitlab JWT::DecodeError (Nil JSON web token) 修改 nginx 配置upstream gitlab-workhorse { server unix:/var/opt/gitlab/gitlab-workhorse/socket; }…proxy_pass http://gitlab-workhorse;…git push develop 后触发脚本 ...

November 11, 2018 · 1 min · jiezi