使用Rancher和DroneCI建立超高速Docker CI/CD流水线

Higher Education(highereducation.com)是一个连接学生与高校的入学申请平台,通过引入高意图和高质量的潜在学生,以及明确、有效的操作,为网站合作的大学吸引学生入学。每年Higher Education为其大学合作伙伴招收超过15000名在线学生入学申请,有7500万高意图的用户通过网站了解大学入学项目。

本文作者为Higher Education的架构师Will Stern,他分享了Higher Education使用Rancher和DroneCI建立超高速Docker CI/CD流水线的经验。

正文

在Higher Education,为了构建我们的CI/CD流水线,我们测试使用了不少CI/CD工具。Rancher和Drone的使用体验是至今为止我们觉得最简单、速度最快、最愉快的。从代码推送/合并到部署分支的那一刻开始,云托管解决方案中将有约一半的时间在测试、构建和部署上---这一过程只需三到五分钟(有些应用程序由于更复杂的构建/测试过程需要更多时间)。

搭建Drone环境的配置和维护对我们的开发人员十分友好,在Rancher上安装Drone就和在Rancher上安装其他内容一样,非常简单。

CI/CD流水线的最大需求点

CI/CD流水线的好坏实际上是DevOps体验的核心,直接影响到我们开发人员。对开发人员来说,CI/CD流水线最重要的两点就是速度和简易性。

第一点就是速度,毕竟没有什么比推送一行代码需要等待20分钟才能投入运行的体验更糟的了。还有糟糕的一点是,当产品出现问题时,由于速度过慢,开发者推出的热修复程序在通过流水线部署时,只会让公司的钱损失的更多。

第二点是简易性,在理想状态下,开发人员可以构建和维护他们的应用部署配置。这让他们更易于使用,毕竟你肯定不会希望开发人员因某些原因搭建失败而不断艾特(Slack)你。

Docker CI/CD流水线的速度痛点

尽管使用不可变容器远远优于维护有状态的服务器,但它们还是有一些缺陷---其中最大的一点就是部署速度:相比于简单地将代码推送至现有服务器上,构建并部署容器镜像的速度更慢。下图显示了Docker部署流水线时需要花费时间的地方:

使用Rancher和DroneCI建立超高速Docker CI/CD流水线

Docker镜像仓库的延迟时间(步骤1,4,5)可能和构建Docker时花费的大量时间有关,这取决于应用程序的大小和搭建所需要的时间。应用程序构建时间(步骤2,3)可能是固定量,不过也可能受构建过程中可用内存或CPU核心的严重影响。

如果你使用的是云托管的CI解决方案,那么你就无法控制CI服务器运行的位置(镜像仓库的延迟可能非常慢),并且可能无法掌握运行服务器/实例的类型(应用程序构建可能很慢)。另外每个构建过程还将产生大量重复工作,比如每次构建都需要下载基本镜像。

开始Drone CI

和Jenkins工具类似,Drone需要运行在你的Rancher基础设施上。不同的是,Drone是Docker的原生工具——构建过程的每个部分都是一个容器。由于基础镜像可以跨搭建甚至跨项目共享,Drone运行在你的基础架构上时就能够加快构建的过程。如果你将Drone推送到自己的基础架构(如AWS的ECR)上的Docker镜像仓库,还可以很大程度上地避免延迟。

Drone的Docker本地化还消除了大量的配置兼容问题,配过Jenkins的朋友肯定知道这有多便利。

标准的Drone部署过程如下所示:

运行一个容器,通知Slack构建已经开始

为“测试”容器配置某个基本镜像,插入代码并在容器中测试运行

运行一个容器,构建和推送生产镜像(到 Docker Hub、AWS ECR等)

运行一个容器,告诉Rancher升级服务

运行一个容器,通知Slack构建已经完成/失败

A.drone.yml文件看起来和docker-compose.yml文件非常类似——一个容器列表。因为每个步骤都有专用于该任务的容器,步骤的配置通常非常简单。

启动并运行Drone

需要的简要操作如下:

注册一个新的Github OAuth app

在Rancher上创建一个Drone环境

添加一个“Drone Server”主机和一个或多个“Drone Worker”主机

给Drone Server主机添加drone=server标签

运行Drone栈

实例的大小取决于你——在Higher Education,我们倾向于使用更少、更强大的workers,这样可以加快构建的速度。(我们发现一个强大的worker能够处理7个团队的构建)

一旦你的drone服务启动,请运行这个栈:

version: '2'

services:

  drone-server:

    image: drone/drone:0.5

    environment:

      DRONE_GITHUB: 'true'

      DRONE_GITHUB_CLIENT: <github client>

      DRONE_GITHUB_SECRET: <github secret>

      DRONE_OPEN: 'true'

      DRONE_ORGS: myGithubOrg

      DRONE_SECRET: <make up a secret!>

      DRONE_GITHUB_PRIVATE_MODE: 'true'

      DRONE_ADMIN: someuser,someotheruser,

      DRONE_DATABASE_DRIVER: mysql

      DRONE_DATABASE_DATASOURCE: user:password@tcp(databaseurl:3306)/drone?parseTime=true

    volumes:

    - /drone:/var/lib/drone/

    ports:

    - 80:8000/tcp

    labels:

      io.rancher.scheduler.affinity:host_label: drone=server

  drone-agent:

    image: drone/drone:0.5

    environment:

      DRONE_SECRET: <make up a secret!>

      DRONE_SERVER: ws://drone-server:8000/ws/broker

    volumes:

    - /var/run/docker.sock:/var/run/docker.sock

    command:

    - agent

    labels:

      io.rancher.scheduler.affinity:host_label_ne: drone=server

      io.rancher.scheduler.global: 'true'

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/54e71c6b5b11a3ebc26b52a472f1d52a.html