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 流水线的好坏实际上是 DevOps 体验的核心,直接影响到我们开发人员。对开发人员来说,CI/CD 流水线最重要的两点就是速度和简易性。
第一点就是速度,毕竟没有什么比推送一行代码需要等待 20 分钟才能投入运行的体验更糟的了。还有糟糕的一点是,当产品出现问题时,由于速度过慢,开发者推出的热修复程序在通过流水线部署时,只会让公司的钱损失的更多。
第二点是简易性,在理想状态下,开发人员可以构建和维护他们的应用部署配置。这让他们更易于使用,毕竟你肯定不会希望开发人员因某些原因搭建失败而不断艾特(Slack)你。
尽管使用不可变容器远远优于维护有状态的服务器,但它们还是有一些缺陷 --- 其中最大的一点就是部署速度:相比于简单地将代码推送至现有服务器上,构建并部署容器镜像的速度更慢。下图显示了 Docker 部署流水线时需要花费时间的地方:
Docker 镜像仓库的延迟时间(步骤 1,4,5)可能和构建 Docker 时花费的大量时间有关,这取决于应用程序的大小和搭建所需要的时间。应用程序构建时间(步骤 2,3)可能是固定量,不过也可能受构建过程中可用内存或 CPU 核心的严重影响。
如果你使用的是云托管的 CI 解决方案,那么你就无法控制 CI 服务器运行的位置(镜像仓库的延迟可能非常慢),并且可能无法掌握运行服务器/实例的类型(应用程序构建可能很慢)。另外每个构建过程还将产生大量重复工作,比如每次构建都需要下载基本镜像。
和 Jenkins 工具类似,Drone 需要运行在你的 Rancher 基础设施上。不同的是,Drone 是 Docker 的原生工具——构建过程的每个部分都是一个容器。由于基础镜像可以跨搭建甚至跨项目共享,Drone 运行在你的基础架构上时就能够加快构建的过程。如果你将 Drone 推送到自己的基础架构(如 AWS 的 ECR)上的 Docker 镜像仓库,还可以很大程度上地避免延迟。
Drone 的 Docker 本地化还消除了大量的配置兼容问题,配过 Jenkins 的朋友肯定知道这有多便利。
A.drone.yml 文件看起来和 docker-compose.yml 文件非常类似——一个容器列表。因为每个步骤都有专用于该任务的容器,步骤的配置通常非常简单。
需要的简要操作如下:
实例的大小取决于你——在 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'
这将在你的 drone=server 主机上运行一个 Drone 服务,并为你环境上的其他每一台主机运行一个 drone 代理。我们强烈推荐你使用 MySQL 备份 Drone,设定 DATABASE_DRIVER 和 DATASOURCE 值即可实现。在本例中我们使用了一个小的 RDS 实例。
当栈启动运行后,你可以登录到 Drone 服务的 IP 地址,打开一个仓库用于搭建(从账户菜单)。这里你会注意到 Drone UI 的每一个仓库都没有配置。这一切都需要一个. drone.yml 文件来负责。
我们来搭建并测试一个 Node.js 项目,添加一个. drone.yml 文件到你的仓库,就像这样:
- pipeline:
- build:
- image: node: 6.10.0
- commands:
- -yarn install
- - yarn test
文件的内容非常简洁,你只需在搭建步骤设置放置仓库代码的容器镜像,指定要在该容器中运行的命令即可。
其他的项目也可以由 Drone 插件管理,这些插件相当于针对一个任务的容器。而且因为插件都在 Docker Hub 上,你不需要安装它们,只需将它们添加到. drone.yml 文件中即可。
下面是一个详细使用 Slack、ECR 和 Rancher 插件创建. drone.yml 的例子:
- pipeline:
- slack:
- image: plugins / slack
- webhook: <your slack webhook url >
- channel: deployments
- username: drone
- template: "<{{build.link}}|Deployment #{{build.number}} started> on <http://github.com/
- {{repo.owner}}/{{repo.name}}/tree/{{build.branch}}|{{repo.name}}:{{build.branch}}> by {{build.author}}"
- when:
- branch: [master, staging]
- build:
- image: <your base image,
- say node: 6.10.0 >
- commands:
- -yarn install
- - yarn test
- environment:
- -SOME_ENV_VAR = some - value
- ecr:
- image: plugins / ecr
- access_key: $ {
- AWS_ACCESS_KEY_ID
- }
- secret_key: $ {
- AWS_SECRET_ACCESS_KEY
- }
- repo: <your repo name >
- dockerfile: Dockerfile
- storage_path: /drone/docker
- rancher:
- image: peloton / drone - rancher
- url: <your rancher url >
- access_key: $ {
- RANCHER_ACCESS_KEY
- }
- secret_key: $ {
- RANCHER_SECRET_KEY
- }
- service: core / platform
- docker_image: <image to pull >
- confirm: true
- timeout: 240
- slack:
- image: plugins / slack
- webhook: <your slack webhook >
- channel: deployments
- username: drone
- when:
- branch: [master, staging]
- status: [success, failure]
尽管上面的代码已经接近 40 行,但它的可读性非常强,而且其中 80% 的代码是拷贝自 Drone 插件文档。(如果你想在云托管的 CI 平台中进行这些操作,可能需要一天时间去阅读文档)需要注意的是,每个插件实际并不需要繁琐的配置。
如果你要使用 Docker Hub 而不是 ECR,使用 Docker 插件 即可。
以上就是关于搭建 CI/CD 流水线的介绍。在几分钟内,你可以启动运行具有完整功能的 CD 流水线。另外,使用 Rancher Janitor 目录栈确保你的 workers 的磁盘空间也是一个好主意,你只需知道的是,清理的次数越少,构建的速度就会越快,因为更多的层已经缓存好了。
来源: http://www.tuicool.com/articles/ZFRB3ii