etcd nginx 容器_容器环境下的持续集成最佳实践

云原生 (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 CI Ruby YAML 不支持 公共项目免费,私有项目 $69/单进程, $129/2 进程
CircleCI Clojure YAML 不支持 单进程免费,$50/加 1 进程
Gitlab CI Ruby YAML 支持 绑定 Gitlab 代码管理
Jenkins Java Groovy 支持
Drone Go YAML 支持 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 都已经配置部署好,假设我是这个项目的唯一开发人员,如何开发一个新功能并发布新版本呢?

  1. Clone 项目到本地, 修改项目代码, 如将 Hello World 改为 Hello World V2

  2. git add .,然后书写符合约定的 Commit 并提交代码, git commit -m "feature: hello world v2”

  3. 推送代码到代码库git push,等待数分钟后,开发人员会看到单元测试结果,Github 仓库会产生一次新版本的 release,release 内容为当前版本的 ChangeLog, 同时线上已经完成了新功能的发布。

虽然在开发者看来,一次发布简单到只需 3 个指令,但背后经过了如下的若干次交互,这是一次发布实际产生交互的时序图,具体每个环节如何工作将在后文中详细说明。

9e766cc27563918de551358e411e57db.png

多人开发模式

一个项目一般不止一个开发人员,比如我是新加入这个项目的成员,在这个 Demo 中应该如何上线新功能呢?同样非常简单:

  1. Clone 项目到本地,创建一个分支来完成新功能的开发, git checkout -b feature/hello-world-v3。在这个分支修改一些代码,比如将Hello World V2修改为Hello World V3

  2. git add .,书写符合规范的 Commit 并提交代码, gi

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值