はじめましてMyReferでエンジニアとして主にバックエンドとインフラを担当している籔下です。
MyReferのエンジニアチームにてtech blogを始めることにしました。
よろしくお願いします。
MyReferは国内初のリファラル採用活性化サービスとして2015年9月にリリースしており、元々パーソルキャリアという企業内の新規事業として立ち上がったサービスでしたが、2018年8月にパーソルキャリアからスピンアウトベンチャーとして法人化し、現在株式会社MyReferとして運営しています。
ことの発端
企業の紹介は以上として、本記事の本題です。
MyReferではgitlab runnerを利用し、日々テストを回していたのですが、ある日急に動かなくなってしまいました。
理由はgitlab runnerを構築した担当者のアカウント権限をgitlab runner内の処理で利用しており、その担当者が退職したため権限を削除したのが原因でした。
さらにgitlab runnerはAWS EC2上で動いており、キーペアを共有してもらうことを忘れたまま退職されてしまいました。1
ということでこれを機に再構築したついでにMyReferで動かしているgitlab runnerの構成などについて紹介します。
構成
ざっくり構成は以下のようになってます。
現在MyReferは国内のクラウドサービス上でサービスを展開していて、Gitlab等の社内ツールも同クラウド上にオンプレで構築して運用しています。
今後は利用しているインフラ全てAWSへ移行する計画があり、現在進行形で一部サービスから徐々に移行作業を実施しています。
今回紹介するGitlab runnerもEC2のスポットインスタンスを活用して構築しています。
今回構成したgitlab runnerのジョブの動作概要
以下のような流れでgitlab runnerのジョブが実行されます。
1. git pushする
2. gitlab runner起動
3. docker-machineでEC2のスポットインスタンスを起動
4. EC2上にdocker:dindでコンテナ立ち上げ
5. 立ち上がったコンテナ内でgitlab runnerのジョブが走る
以下今回設定したgitlab runner内のジョブの流れです。
1. git cloneでリポジトリを取得
2. docker hubからdocker imageを取得(事前に必要なOS/OSSがインストールされているものを登録しています)
3. 各種設定
4. テスト実行
各種設定
gitlab runner インストール
EC2インスタンス上にgitlab runnerを導入します。
$ curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | bash $ yum install gitlab-runner-11.3.1 -y
docker-machine インストール
同じくEC2インスタンス上にdocker-machineを導入します。
$ curl -L https://github.com/docker/machine/releases/download/v0.15.0/docker-machine-`uname -s`-`uname -m` >/tmp/docker-machine $ chmod +x /tmp/docker-machine $ cp /tmp/docker-machine /usr/local/bin/docker-machine $ ln -s /usr/local/bin/docker-machine /usr/bin/docker-machine
gitlab runner 登録
gitlab runnerを登録します。
事前にgitlabのUIからRunner tokenを取得してください。
Runner tokenは「Setting」→「CI / CD」→「General pipelines settings」→「Runner token」から取得できます。
今回の構築では以下のようなコマンドで登録しました。
$ gitlab-runner register -n \ --url="[gitlabのURL]" \ --registration-token="[Runner token]" \ --executor="docker+machine" \ --limit=0 \ --docker-tlsverify=false \ --docker-image="docker:18.03.1-ce" \ --docker-privileged=true \ --docker-disable-cache=false \ --docker-volumes="/cache" \ --docker-shm-size=0 \ --cache-type="s3" \ --cache-s3-server-address="s3-ap-northeast-1.amazonaws.com" \ --cache-s3-access-key="[アクセスキー]" \ --cache-s3-secret-key="[シークレットキー]" \ --cache-s3-bucket-name="[s3バケット名]" \ --cache-s3-insecure=false \ --machine-idle-nodes=0 \ --machine-idle-time=600 \ --machine-machine-driver="amazonec2" \ --machine-machine-name="runner-%s" \ --machine-machine-options="amazonec2-instance-type=m4.large" \ --machine-machine-options="amazonec2-region=ap-northeast-1" \ --machine-machine-options="amazonec2-vpc-id=[vpcのID]" \ --machine-machine-options="amazonec2-subnet-id=[subnetのID]" \ --machine-machine-options="amazonec2-private-address-only=0" \ --machine-machine-options="amazonec2-request-spot-instance=true" \ --machine-machine-options="amazonec2-spot-price=0.04" \ --machine-machine-options="amazonec2-security-group=[セキュリティグループ名]" \ --machine-machine-options="amazonec2-tags=environment,runner-public" \ --machine-machine-options="amazonec2-monitoring=0" \ --machine-machine-options="amazonec2-root-size=16" \ --machine-off-peak-timezone="Asia/Tokyo" \ --machine-off-peak-idle-count=0 \ --machine-off-peak-idle-time=60 \ --machine-off-peak-periods="* * 0-9,17-23 * * mon-fri *" \ --machine-off-peak-periods="* * * * * sat,sun *"
成功した場合はGitlabの「Setting」→「CI / CD」→「Runners settings」→「Runners activated for this project」で確認できます。
gitlab runnerのジョブ設定
実際にgitlab runnerで実施するジョブは.gitlab-ci.yml
で設定します。
このファイルはリポジトリのルートディレクトリに配置しておきます。
.gitlab-ci.yml(一部抜粋)
image: docker:latest variables: DOCKER_DRIVER: overlay2 GIT_STRATEGY: none services: - docker:dind before_script: - hogehoge - fugafuga lint: script: - do lint - etc unittest: script: - do unittest - etc
image
は利用するdocker imageを指定します。
ここで何も指定しない場合は、gitlab-runner register
コマンドの--docker-image
オプションで指定しているイメージがデフォルトで選択されます。
variables
のDOCKER_DRIVER
はDockerコンテナが接続するストレージ・ドライバを指定します。
GIT_STRATEGY
はgitリポジトリからcloneするかfetchするかを選択するオプションですが、none
を指定することでcloneもfetchも実施しないように振舞うことが出来ます。
今回構成の関係でgitlab runnerが動作しているEC2上にproxyを立ててそこを経由してcloneしたりした関係でbefore_script
の中でcloneするような処理を呼んでいるため、none
を指定しています。
services
にdocker:dind
を指定することで、docker in dockerの構成を取ることができます。
image
にdocker:dind
が対応していないカーネルを含むイメージファイルを指定してしまうと外側のコンテナの中の処理でこけてしまうので要注意です。
外側のコンテナで何かOSに依存するようなツールをまわすなどでなければdocker:latest
で良いと思います。
before_script
では全体(上記でいうとlintとunittest)のジョブ実行前に実施する処理を定義します。
lint
やunittest
は自由に(gitlab runnerの予約語除いて)定義が可能で、この単位でタスクが実行されます。実行したい内容はscript
で定義します。
以上で各種設定・構築は完了です。
(補足)
今回、既に開発環境で利用しているコンテナや、コンテナに対して開発環境設定するスクリプトを丸々流用した結果このような構成になっており一部強引な構成になっています。
最後に
今回の再構築は、まだエンジニア組織として諸々のルールが整備されていないことが発端となり、チームとしては旧パーソル時代から構成されていたものの、新会社としての組織づくりがまだまだ追いついていないことが露骨となってしまいました。
これらの組織づくりに加えて、MyReferはリリース以降徐々に利用いただいている企業様が増えており、それに伴い、インフラ整備が急務となっています。
また、インフラに限らず、フロントエンドやバックエンドの開発に関しても現在様々な技術的負債を抱えており、サービスのアップデートを行いながらもこれらの負債の解消に向け日々技術的なチャレンジを模索しています。
まだまだエンジニアが足りず、募集中ですのでご興味ある方はカジュアル面談からでもウェルカムなので下記よりご応募お待ちしております!