logo
logo

DeepFlow 使用 Spot 实例加速 GitHub Action 的探索

宋建昌 2022-11-01

Github Action 让托管在 Github 中的项目 CI 流程变得很方便,但 Github 默认提供的 2C7G 的 Runner 配置太低,跑一些大型项目编译任务会非常慢,本文是 DeepFlow 使用公有云高配廉价 Spot 实例加速 Action 的探索,经历了一系列踩坑之后,最终我们找到了解决性能、成本、ARM 等全部需求的理想方案,希望对你有用。

0x0: 使用 GitHub Action 遇到的问题

自 DeepFlow 开源代码推送到 GitHub 后,就遇到了 GitHub Action 因托管 Runner 配置太低导致编译任务耗时过长的问题,在此之前我们内部的 GitLab CI 一直使用的阿里云 32C ECI Spot 实例,几分钟就可跑完所有 Job (具体方法我们后面会单独出一篇文章介绍),看到了 Spot 实例带给我们 GitLab CI 的改变之后,DeepFlow 的 GitHub Action 从上线第一天开始就在寻求一种可以为每个 Job 分配一个独立的 Runner、支持 X86/ARM64 架构的方案,但这个过程并不顺利,前后历经 5 个版本,才最终找到了一个理想的方案。

DeepFlow 前期使用 GitHub Action 遇到的一些问题:

  1. 性能差:GitHub 托管机器配置太低编译阶段耗时过长
  2. 灵活性差:固定的 self-hosted Runner 无法动态伸缩,Job 经常排队,机器闲置时间长,包年包月配置拉满很不划算
  3. 成本高:ARM64 架构编译需要再开一台机器,阿里云在海外区域没有 ARM64 架构实例,AWS 的包年包月 ARM64 机器价格比较高(32C64G每月500$左右)
  4. 网络不稳定:GitHub 托管 Runner 推送镜像到国内阿里云仓库经常有超时现象

我们的需求:

  • 支持自动缩放,为每个 Job 分配一个至少32核 Runner
  • 使用方式和 GitHub 托管的 Runner 大致相同
  • 同时支持 X86 和 ARM64 架构
  • 低维护成本,最好不需要维护
  • 稳定快速推送镜像到国内阿里云镜像仓库

0x1: 加速 GitHub Action 的探索

基于我们的需求和 GitHub Action 社区文档,我们也找到了一些解决方案:

  1. K8s Controller: 用于 GitHub Actions 自托管运行器的 Kubernetes 控制器
  2. Terraform: 使用 Terraform 和 AWS Lambda 自动伸缩 AWS EC2 作为 GitHub Runner
  3. Github: 目前仅对 GitHub Team 和 Enterprise 组织开放的付费 Larger Runners 服务
  4. Cirun: 自动伸缩 AWS/GCP/AZURE/OpenStack 等云平台的 VM 作为GitHub Runner
K8s Controller Terraform Github Larger Runners Cirun
Runner Container Linux、Windows Linux、 Window、Mac Linux、 Windows、 Mac
支持的云平台 Kubernetes AWS - AWS、GCP、AZURE、OpenStack
是否支持 ARM64 支持 支持 不支持 支持
是否支持 Spot 不支持 支持 - 支持
部署维护成本

我们尝试的第一个方案是 K8s Controller,试用之后发现了如下缺陷:

  • AWS EKS Fargate 不支持特权 Container
  • AWS EKS Fargate 不支持 ARM64 架构
  • AWS EKS Fargate 不支持 generic-ephemeral-volumes

没办法使用 Fargate 就要准备独立节点,没办法动态伸缩节点和使用按量付费实例、Spot 实例。

接下来我们尝试使用 Terraform 方案,但同样也遇到了一些挫折:

  • 多次安装部署失败
  • 对 Terrafrom 新手不友好
  • 有维护成本

GitHub 方案不支持 ARM64 实例,直接 Pass。

最终我们选择了 Cirun:

Cirun:支持自定义任意机器规格、架构和镜像,对于开源项目免费,不需要部署维护,没有额外资源的费用,并且操作非常简单:

第一步:安装 App
GitHub Marketplace 里面 安装 Cirun APP

Install CirunInstall Cirun

第二步:添加 Repo
Cirun 控制台 添加需要的 Repo

Add RepoAdd Repo

第三步:配置 AK/SK
Cirun 控制台 配置 AWS 的 ACCESS KEYSecret KEY

AWS AUTHAWS AUTH

第四步:配置机器规格
在 GitHub Repo 中定义好机器规格和 Runner Label

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
runners:
- name: "aws-amd64-32c"
cloud: "aws"
instance_type: "c6id.8xlarge"
machine_image: "ami-097a2df4ac947655f"
preemptible: true
labels:
- "aws-amd64-32c"
- name: "aws-arm64-32c"
cloud: "aws"
instance_type: "c6g.8xlarge"
machine_image: "ami-0a9790c5a531163ee"
preemptible: true
labels:
- "aws-arm64-32c"

第五步:开始使用
切换 GitHub Job 的 runs-on 字段

1
2
3
4
5
6
7
8
9
10
jobs:
build_agent:
name: build agent
runs-on: "cirun-aws-amd64-32c--${{ github.run_id }}"
steps:
- name: Checkout
uses: actions/checkout@v3
with:
submodules: recursive
fetch-depth: 0

最终效果

GitHub Runner
AWS InstanceGitHub RunnerAWS Instance

0x2: DeepFlow 使用 Cirun 后的改变

目前 DeepFlow 使用 AWS 32C64G Spot 实例并行运行 CI,月均消费 300$。如果使用包年包月的方法,同等消费下只能运行两个 16C32G 的 X86/ARM64 实例,而且一旦有并行任务就需要漫长的排队等待。

DeepFlow 的主要 CI 都已切换到 Cirun 的 Runner 上,达到了之前所有的预期:

  • 性能:deepflow-agent 编译时间降低了 40%,且所有 CI Job 从此告别了排队
  • 成本:几乎相同成本下我们的 GitHub Action 从两个固定的 16C32G 的机器切换到了每个 Job 分配了一个 32C64G 的 AWS Spot EC2 实例
  • 灵活性:无缝切换 ARM64 X86 实例
  • 维护成本:无任何维护成本、额外资源成本
  • 网络状态:得益于 AWS 优秀的网络,相比于 GitHub 托管 Runner,推送镜像到国内阿里云镜像仓库失败率大幅降低

0x3: 未来展望

我们在使用 Cirun 的中间也遇到了一些问题,都得到了作者很好支持,详见 Issues:

同时也有一些正在进行中的工作:

  • 优化 CI 耗时,修复耗时异常的步骤
  • AWS 的 ARM64 机器 Spot 请求常因为资源不足而创建失败,目前 ARM64 架构的 Runner 没有使用 Spot 实例,Cirun 作者修复问题后切换为 Spot 实例
  • 缩短使用 Cirun Runner 的 Job 等待时间,由目前的90秒降低到30秒以内
  • GitHub Action 文档中加入 Cirun

0x4: 什么是 Spot 实例

引用 AWS 官网 的介绍:

  • 按需实例和 Spot 实例的唯一区别在于,当 EC2 需要更多容量时,它会发出两分钟的通知继而中断 Spot 实例。您可以将 EC2 Spot 用于各种容错且灵活的应用程序,如测试和开发环境、无状态 Web 服务器、图像渲染、视频转码,以运行分析、机器学习和高性能计算 (HPC) 工作负载。EC2 Spot 还可与其他 AWS 产品紧密集成,包括 EMR、Auto Scaling、Elastic Container Service (ECS)、CloudFormation等,让您可以灵活选择如何启动和维护 Spot 实例上运行的应用程序。
  • Spot实例是购买和使用 Amazon EC2 实例的新方式。Spot实例的现货价格根据供需情况定期变化。直接使用类似购买按需实例的方式启动Spot实例,价格将根据供需关系确定(不超过按需实例价格);用户也可以设置一个最高价,当设置的最高价高于当前现货价格的期间内运行此类实例。Spot实例是按需实例和预留实例的补充,为获得计算容量提供了另一种选择

0x5: 什么是 Cirun

Cirun 是开发人员和团队通过 GitHub Actions 在其安全的云基础架构上运行其 CI/CD 管道的一种方式。该项目旨在提供选择具有任何配置的云机器的自由,通过使用低成本实例来节省资金,并通过启用无限并发和高性能机器来节省时间,所有这一切都通过一个简单的开发人员友好的 yaml 文件实现。它目前支持所有主要云,包括 GCP、AWS、Oracle、DigitalOcean、Azure 和 OpenStack。Cirun 对开源项目完全免费,没有任何限制。

0x6: 什么是 DeepFlow

DeepFlow 是云杉网络开发的一款可观测性产品,旨在为复杂的云基础设施及云原生应用提供深度可观测性。DeepFlow 基于 eBPF 实现了应用性能指标、分布式追踪、持续性能剖析等观测信号的零侵扰Zero Code)采集,并结合智能标签SmartEncoding)技术实现了所有观测信号的全栈Full Stack)关联和高效存取。使用 DeepFlow,可以让云原生应用自动具有深度可观测性,从而消除开发者不断插桩的沉重负担,并为 DevOps/SRE 团队提供从代码到基础设施的监控及诊断能力。

GitHub 地址:https://github.com/deepflowio/deepflow

访问 DeepFlow Demo,体验高度自动化的可观测性新时代。