GitHub Actions 成本优化:让你的团队更具竞争力

大家好,我是张晋涛。

本周 Docker 就发布 10 周年了,为了庆祝这个里程碑,我将会发布一系列文章,涉及 Docker,CI/CD, 容器等各个方面。

这篇文章我将介绍如何降低 GitHub Actions 上的消费,以及一些建议

2023-01-24 08-12-54屏幕截图.png

根据 G2 的统计报告, GitHub Actions 是最易用的 CI/CD 工具,越来越多的人都喜欢它。

由于 GitHub Actions 是 GitHub 原生的 CI/CD 工具,在 marketplace 有上万个 Actions 可直接使用,且对于公共仓库是免费的,所以越来越多的项目也将其使用的 CI 工具切换成了 GitHub Actions。

我也很喜欢 GitHub Actions,并且几乎在我所有托管在 GitHub 上的仓库中使用它。

但是最近我在一个项目中,触发了 GitHub Actions 配额的限制。这让我花费了一些时间去关注它的费用。

https://twitter.com/zhangjintao9020/status/1616077513125691399?s=20&t=we9o9FxhgSEOXzY39czbJg

2023-03-21 08-41-52屏幕截图.png

为什么会耗尽配额

最近我发现了一个有趣的项目: upptime/upptime: ⬆️ Free uptime monitor and status page powered by GitHub

我想要尝试用它将自己的开发的一些服务监控起来,做一个 status page,但这会涉及到一些 API 的配置,我并不想将它公开,所以我将该仓库 fork 到了一个私有仓库中。 经过简单的配置后,它就正常工作了。

由于我想要得到更多数据,所以我调整了其中中 CI 调度配置。让这些任务执行的更加频繁。

workflowSchedule:
  graphs: "0 * * * *"
  responseTime: "0 * * * *"
  staticSite: "0 * * * *"
  summary: "0 * * * *"
  updateTemplate: "0 * * * *"
  updates: "0 * * * *"
  uptime: "*/5 * * * *"

根据 GitHub Actions 的费用文档,GitHub Actions 对于公开仓库是免费的,但是对私有仓库是有配额限制的。

GitHub Actions usage is free for standard GitHub-hosted runners in public repositories, and for Self-hosted runners. For private repositories, each GitHub account receives a certain amount of free minutes and storage for use with GitHub-hosted runners, depending on the product used with the account. Any usage beyond the included amounts is controlled by spending limits.

很快我就收到了 GitHub 的额度提醒邮件,提醒我配额即将用完。

这让我开始思考如何解决它。

使用 GitHub Actions 的成本

将仓库设置为公开显然是最简单的办法,但我在上文中说明了不能设置成公开仓库的原因。只能去找其他的解决办法。

显然为 GitHub Actions 付费也是一个很直接的解决办法。

在决定为它付费之前,我想要预估一下成本。 GitHub 提供了一个 Pricing Calculator,可以方便的预估花费。

由于我修改了 CI 的调度配置,最频繁运行的任务每 5 分钟会运行一次。

我使用 Meercode 采集了这个仓库中 GitHub Actions 的运行数据,它默认提供了一些 dashboard,比较方便:

2023-01-25 11-29-12屏幕截图.png

同时也允许用户自己进行自定义,我创建了自己的 dashboard,如果你对 Meercode 感兴趣,请在评论中告诉我。

ci-dashboard.png

从上面的图中可以看到,每次任务耗时不超过 0.5min,每小时会有不超过 12 个任务。使用价格计算器进行计算,大概 每月花费是 $35 ,每年 $420

2023-01-25 11-25-13屏幕截图.png

节约成本的办法

由于我的这个仓库中是运行 uptime 的 CI,它消耗的资源很少,但是任务比较频繁,所以我想知道如果我使用 Self-hosted runner 是否可以节约成本。

我对比了几家云服务提供商的价格(规避广告嫌疑,这里就不列了)

其中 1C1G 的实例最低是 $5/month

我选择了其中一家最低规格的实例,并且有 1TB 流量。

2023-01-25 17-04-35屏幕截图.png

我分别尝试了使用它的 Kubernetes 服务,和 compute instance ,它们都可以工作的很好。

2023-01-25 17-08-43屏幕截图.png

使用 compute instance

在 Linux compute instance 中部署 GitHub Actions runner 简单,只需要在项目 https://github.com/<Your name>/<Project name>/settings/actions/runners/new 添加即可。

在该页面有完整的部署步骤,按步骤执行即可。

我的执行过程如下:

moelove@polished-bush-99d8-1926a1:~$ mkdir actions-runner && cd actions-runner
moelove@polished-bush-99d8-1926a1:~/actions-runner$ curl -o actions-runner-linux-x64-2.301.1.tar.gz -L https://github.com/actions/runner/releases/download/v2.301.1/actions-runner-linux-x64-2.301.1.tar.gz
moelove@polished-bush-99d8-1926a1:~/actions-runner$ echo "3ee9c3b83de642f919912e0594ee2601835518827da785d034c1163f8efdf907  actions-runner-linux-x64-2.301.1.tar.gz" | shasum -a 256 -c
actions-runner-linux-x64-2.301.1.tar.gz: OK                                                                     
moelove@polished-bush-99d8-1926a1:~/actions-runner$ tar xzf ./actions-runner-linux-x64-2.301.1.tar.gz              
moelove@polished-bush-99d8-1926a1:~/actions-runner$ ./config.sh --url https://github.com/MoeLove/monitoring --token $TOKEN
                                                        
--------------------------------------------------------------------------------
|        ____ _ _   _   _       _          _        _   _                      |
|       / ___(_) |_| | | |_   _| |__      / \   ___| |_(_) ___  _ __  ___      |
|      | |  _| | __| |_| | | | | '_ \    / _ \ / __| __| |/ _ \| '_ \/ __|     |
|      | |_| | | |_|  _  | |_| | |_) |  / ___ \ (__| |_| | (_) | | | \__ \     |
|       \____|_|\__|_| |_|\__,_|_.__/  /_/   \_\___|\__|_|\___/|_| |_|___/     |
|                                                                              |
|                       Self-hosted runner registration                        |
|                                                                              |
--------------------------------------------------------------------------------

执行完成后,会在当前目录下增加一些文件。执行 ./env.sh 即可启动 GitHub Actions runner 。

moelove@polished-bush-99d8-1926a1:~/actions-runner$ ls
_diag  _work  actions-runner-linux-x64-2.301.1.tar.gz  bin  config.sh  env.sh  externals  run-helper.cmd.template  run-helper.sh  run-helper.sh.template  run.sh  safe_sleep.sh  svc.sh

如果想要稳定的在后台运行,可以执行 ./svc.sh install 将 runner 安装为 systemd 的 service,通过 systemd 管理它的生命周期。

使用 Kubernetes

我选择的这个服务对于 Kubernetes 的 control plane 不收费,仅对 Worker Node 收费,使用 Kubernetes 的好处在于我可以在该集群中进行自动扩缩容,并且可以轻松的运行创建多个 runner 给不同的项目使用。

由于 GitHub 官方尚未真正提供在 Kubernetes 上部署 Self-hosted runner, 我使用了 Actions Runner Controller (ARC) 项目, 该项目允许通过 Runner 自定义资源,快速的部署 Self-hosted runner。

部署过程在文档 https://github.com/actions/actions-runner-controller/blob/master/docs/quickstart.md 中已经描述的很清楚了,以下是我的部署过程。

# deploy cert-manager
(MoeLove) ➜ kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.11.0/cert-manager.yaml

# deploy ARC
(MoeLove) ➜ helm repo add actions-runner-controller https://actions-runner-controller.github.io/actions-runner-controller
(MoeLove) ➜ helm upgrade --install --namespace actions-runner-system --create-namespace\
  --set=authSecret.create=true\
  --set=authSecret.github_token="REPLACE_YOUR_TOKEN_HERE"\
  --wait actions-runner-controller actions-runner-controller/actions-runner-controller

# create runner
(MoeLove) ➜ cat <<EOF | kubectl apply -f -
apiVersion: actions.summerwind.dev/v1alpha1
kind: RunnerDeployment
metadata:
  name: moelove-runner
spec:
  replicas: 1
  template:
    spec:
      repository: MoeLove/monitoring
EOF

安装后达成了如下效果:

Fm4TAAOXkAAXP-H.png

Self-hosted vs GitHub-managed

上面的内容我介绍了我是如何使用 Meercode 度量 CI 的关键指标,以及估算 GitHub Actions 成本的。 根据我实际的低资源消耗,高耗时的场景,我选择了 Self-hosted 的模式。

那么什么时候选择 GitHub-managed runner 更合适呢?GitHub-managed 有什么优势呢?

GitHub-managed runner 有如下优势:

  • 支持多种操作系统:GitHub-managed runner 除了提供 Linux 系统外,还支持 macOS 和 Windows ,但是大多数云供应商是不提供 macOS 环境的。(我曾经为了特定场景将一些 Mac mini 作为服务器放在了机房中)
  • VM 级别的隔离性:根据 GitHub Actions 的文档,GitHub Actions 的 runner 在执行 job 的时候,是通过创建 VM 来运行所有任务的,这带来了一定的安全性和隔离性的保证。如果是 Self-hosted runner,当通过二进制运行的时候,任务将共享主机环境,如果是通过 ARC 运行,则是通过 Pod 带来隔离。这都会产生一定的安全问题。Alex创建了actuated https://actuated.dev/ 通过使用MicroVMs技术,带来轻量且安全的解决方案; cirun.io 是通过直接使用 cloud provider 创建实例。
  • 低维护成本:事实上在任何大型系统中,维护成本都是非常昂贵的。如果只是个人使用,或者仅仅有几个项目在使用 Self-hosted runner 时,维护成本相对可控。一旦规模变大,将会带来很多复杂性。显然 GitHub-managed runner 是由 GitHub 进行维护的。

此外,还有两个做 Self-hosted runner 服务的产品:

它们降低了 runner 的维护和管理成本,提供了更安全的隔离性,以及基于 Arm 环境的支持。cirun 还提供了 GPU runner 的支持。

如果有上述的需求,也可以考虑这些服务。

总结

总的来说,想要节约 GitHub Actions 的成本,需要如下步骤

  • 可视化/可观测性:通过实际数据来预估成本;
  • 比较多个厂商/解决方案:不同的厂商在不同的场景或者产品中提供了不同的定价,可以根据自己的实际情况进行选择;
  • 安全性和维护成本也需要考虑在内;

欢迎订阅我的文章公众号【MoeLove】

TheMoeLove

加载评论