LoginSignup
6
6

More than 5 years have passed since last update.

GitLab RunnerをKubernetes(EKS)で運用する

Last updated at Posted at 2019-03-16

eks_logo.png

TL;DR

  • GitLab Runnerのexecutor(実行形式)には、Kubernetesを指定できる
  • パイプラインのジョブは1つのPodとして実行される
  • 無制限にジョブを並列実行できる
  • スポットインスタンスを使うと低コストで運用できる
  • 月額コストは最低$150~

今回のインフラは全てTerraformで構築しており、コードはGitHubで公開している。
https://github.com/hareku/terraform-eks-gitlab-runner

GitLab Runnerのおさらい

GitLab環境でのCI/CDは、GitLab CI/CDというGitLabに統合されたものを使用し、このGitLab CI/CDはあくまでCI/CDを管理するためのものとなる。実際のビルドやリリースなどのジョブは、GitLab Runner上で実行され、本記事のように別途サーバーを立てる必要がある。

GitLab RunnerはGitLab上でのコミットを検知し、ジョブを実行する。ジョブの実行形式としてexecutorがあり、executorに指定できるのはShellやDocker、そしてKubernetesがある。これらのジョブの結果はGitLab上で見ることができる。

68747470733a2f2f646f63732e6769746c61622e636f6d2f65652f63692f696d672f706970656c696e65735f67726f757065642e706e67.png

より詳しくはClassmethodのGitLab RunnerでCI/CDしてみる|DevelopersIOが参考になる。

Kubernetes executorの全体像

今回、EKSで構築したアーキテクチャ図は以下のようになる。

gitlab-runner.png

図でも表しているが、Kubernetesがexecutorの場合は以下のようなフローでジョブが実行される。

  1. 開発者がGitLabにプッシュ
  2. GitLabがGitLab Runnerへジョブを通知する
  3. GitLab Runnerが、ジョブをPodとして起動する
  4. Podはジョブとともに終了される

月額コストは最低$150から

Amazon EKSは、Kubernetesのコントロールプレーンをマネージドで提供してくれる。料金は東京リージョンで1時間あたり0.20 USD、つまり月に144.0 USDとなっている。
それに加えて、実際にGitLab Runnerが走るスポットインスタンスの料金、そして後述するcluster-autoscalerなどのエコシステムをデプロイするためのオンデマンドインスタンスに料金が掛かる。

AutoScalingGroupのインスタンス数を0にスケールダウンすることもできるので、夜間は停止すると考える場合、スポットインスタンスの月額料金は1/2と考えていい。月額料金は以下のように試算する。

  • EKS = 144 USD
  • スポットインスタンス (m4.2xlarge 0.1331 USD /1 時間) * (24 * 30 * 1/2) * (2台) = $96
  • オンデマンドインスタンス (t3.small 0.0272 USD /1 時間) * (24 * 30) = $20
  • 合計 260 USD

m4.2xlargeを2台で計算している。m4.2xlargeは8vCPUと32GBのメモリを持つ。1つのジョブに割り当てられるリソース数は指定できるが、ジョブ1つに1vCPUと1GBのメモリを割り当てる場合、2台で常におよそ16のジョブを並列実行できる計算となる。

並列実行したいジョブ数がたった10~30程度の場合、EKSの料金が少し目立つ。そのためEKSクラスタをGitLab Runner専用として使うのではなく、他のKubernetesシステムと共存するようなクラスタと共に運用する方が望ましい。

用いるKubernetesエコシステム

ここでは、利用したKubernetesエコシステムについての説明をする。

kube2iam:IAMの管理

GitHub - jtblin/kube2iam

kube2iamでは、Kubernetes上で動作する各Podに異なるIAMロールを付与することができる。今回もPodとして起動されるジョブにIAMロールを付与することで、AWSへのアクセス権限を(ECRへのプッシュなど)与えている。

Cluster Autoscaler:NodeのAutoScaling

GitHub - autoscaler/cluster-autoscaler

Cluster Autoscalerは、需要に応じてASG(Auto Scaling Group)のノード(EC2インスタンス)の数を調整する。需要というのは「CPUやメモリのリソース不足などによる、Podが配置できない状態」を指す。EC2インスタンスのCPU使用率ではないことに注意する。

EC2 Spot Termination Notice Handler:スポットインスタンスの管理

GitHub - kube-aws/kube-spot-termination-notice-handler

Pod(Job)を起動するノードはスポットインスタンスを利用する。スポットインスタンスは、オンデマンド価格の30%程度の料金で利用できるため、コスト削減に有効である。

ただスポットインスタンスは入札価格や空き状態によって、強制的に終了される。
具体的には、終了2分前からhttp://169.254.169.254/latest/meta-data/spot/instance-actionでHTTP200レスポンスが返ってくる。kube-spot-termination-notice-handlerも、内部ではこのURLへポーリングを行っている。

2分以上かかるジョブで、途中で強制終了されては困るようなものがある場合、スポットインスタンスではなくオンデマンドで運用する方が良い。

インスタンスタイプの注意点

注意点としては、m5やt3などの次世代のインスタンスタイプだとAWS側で余っている量が少なく、スポットリクエストがcapacity not availableエラーになってスケールアウトできないケースによく陥る。

これはm4などの旧世代のインスタンスタイプだと余っている量が多く、容量不足のエラーが返ってくることがほぼ無くなる。そのため自分はm4を選択して回避している。今のところ容量不足によるCI環境のダウンは見ていないが、現状はプロダクション環境で使うのは控えたほうが良い。

またcluster-autoscalerは、スポットフリートや、それに準ずる価格モデルに基づいたASGの選択に現在対応していない。そのあたりを含め、GitHubのFAQにしっかりと目を通すことをおすすめする。
autoscaler/FAQ.md at master · kubernetes/autoscaler · GitHub

まとめ

以上がKubernetes(EKS)でGitLab Runnerを運用する紹介となる。

まだまだAWSのスポットインスタンス周りのエコシステムは成熟しきっていない。そのためAWSに固執する必要がなければ、GKE(Google Kubernetes Engine)を選択肢に入れてもよい。GCPについてはあまり詳しくないので、またいつか調べたい。

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6