AWS
GitLab
GitLab-CI

GitLabのgitlab-runner autoscalingをaws上でdocker-machineしてみる

概要

GitLab Runner 1.1 with Autoscalingによると、gitlab-runner自身もスケールできるよ、と。

runnerの環境にいろいろ入れるのは嫌だし、runnnerの環境にDockerを入れてそこで動かすにしても、
メモリやCPUも常時そんなに必要なわけじゃないから、runnner自体は安いインスタンスにしたい。
そう思うのは人情です。

そこで、今回はgitlab-runnerはt2.microの小さいインスタンスで動かし、
実際のビルドは、そこからdocker-machineで作成された先のインスタンス内でやろうと考えたのです。

AmazonLinuxで1からgitlab-runnerを入れ、ビルドできるところまでをステップごとに紹介します。
公式ドキュメントをコピペしていると気づかないつまづきポイントつき!

やってみた結果、思ったこと

メリット

  • gitlab-runner自身は、ビルドを行わないので、t2.microレベルで良い。やすい。
  • 複数のリクエストがきても、EC2インスタンスが新規に生成されるので、スケールしやすい。

デメリット

  • EC2インスタンスの起動から行われるため、その分ビルドに時間がかかる

aws内にDockerのレジストリ(ECR)があったり、S3にビルド用の資材が一式入ってます!みたいな人には、aws上にgitlab-runnnerを入れるメリットがありそうです。

EC2インスタンスの作成

まず、gitlab-runnerを動かすインスタンスを作成します。t2.microにしておきます。
作成する際のイメージはAmazonLinux(2017/12/06時点で ami-da9e2cbc)を指定します。

 aws ec2 run-instances \
    --image-id ami-da9e2cbc \
    --count 1 \
    --instance-type t2.micro 
    --key-name ${KEY_NAME} \
    --security-group-ids ${SECURITY_GROUP_ID} \
    --subnet-id ${SUBNET_ID}

key-nameやセキュリティグループID、サブネットのIDは作成する環境にあわせて設定しておきます。

docker-machineのインストール

docker-machineを先の手順でたてた環境にインストールします。

公式の手順は、https://docs.docker.com/machine/install-machine/#install-machine-directly にあります。

curl -L https://github.com/docker/machine/releases/download/v0.13.0/docker-machine-`uname -s`-`uname -m` >/tmp/docker-machine &&
chmod +x /tmp/docker-machine &&
sudo cp /tmp/docker-machine /usr/bin/docker-machine

つまづきポイント1

公式の手順では、docker-machineを/usr/local/bin/docker-machineにコピーしますが、
これだとインストールした自分は使えるけども、gitlab-runnerユーザには使えないことになるので、
/usr/bin/docker-machine とします。

もし、/usr/bin/local以下に入れてしまっていたら、ビルド実行時にこんなエラーになります。

ERROR: Preparation failed: exec: "docker-machine": executable file not found in $PATH

build test failed.png

gitlab-runnerのインストール

公式の入れ方はhttps://docs.gitlab.com/runner/install/linux-repository.htmlにあります。

こんな感じでyumで入れてしまいます。

curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | sudo bash
sudo yum install gitlab-runner -y

gitlab-runnnerの登録

GitLabにrunnerを登録します。
予めGitLabでトークンの確認と、docker-machineで使うオプション値を確認しておきましょう。

dockerを用いたビルドを想定する場合は、docker-privilegedオプションをつけておくのが良いです。

例はこちら。
docker-machineのオプションは、実際にビルドをするマシンとして過不足ないものを選ぶといいでしょう。

sudo gitlab-runner register --non-interactive \
  --url https://gitlab.com/ \
  --registration-token XXXXXXXXXXXXXXXXXXXXXXX \
  --executor "docker+machine" \
  --name "gitlab-ci-auto-scaling" \
  --docker-image "ubuntu" \
  --docker-privileged \
  --machine-machine-driver "amazonec2" \
  --machine-machine-name "gitlab-ci-%s" \
  --machine-machine-options "amazonec2-access-key=ACCESS_KEY" \
  --machine-machine-options "amazonec2-secret-key=SECRET_KEY" \
  --machine-machine-options "amazonec2-region=ap-northeast-1" \
  --machine-machine-options "amazonec2-root-size=30" \
  --machine-machine-options "amazonec2-instance-type=m4.large" \
  --machine-machine-options "amazonec2-vpc-id=vpc-0123456" \
  --machine-machine-options "amazonec2-subnet-id=subnet-1234567" \
  --tag-list "ec2-auto-scale,docker"

つまづきポイント2

machine-machine-optionsで指定する内容は、"KEY=VALUE"の形で、イコールでつなぐようにします。
"KEY VALUE"のようにしておくと、registerそのものは成功しますが、動作しないことになります。

つまづきポイント3

もし、docker-priviledgedがない状態(false)で、dockerコマンドを実行するようなビルドが走ったときは、こうなります。

Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
ERROR: Job failed: exit code 1

a.png

あとはCIするだけ

あとは、gitlab-ci.ymlを用意してビルドするだけ!

image: docker:latest

services:
  - docker:dind

build-test:
  stage: build
  script:
    - echo sekai no yasuda and aoki.
    - docker version
  tags:
    - ec2-auto-scale

tagsには、忘れずに自分で登録したrunnnerのタグにしておきましょう。

インスタンスが作成され、ビルドが走り、そしてインスタンスが削除される。
terminatedがたくさんAWSのコンソールで見えても気にしない!
じゃんじゃんバリバリ、CIがまわせるようになりますね。

では、Happy GitLab Lifeを!!