LoginSignup
7
5

More than 3 years have passed since last update.

Drone AutoscalerをAWSに構築する

Last updated at Posted at 2019-06-25

Drone はモダンなCIサービスを実現するOSSです。CircleCIやTravisCI風のCIを自前で構築することができます。

単一のマシンにインストール、複数マシンをエージェント(実際にジョブを走らせるノード)として使う、あるいはkubernetesを使う選択肢がありますが ( https://docs.drone.io/installation/github/ )、別の選択肢として Drone Autoscale という仕組みが存在し、これはジョブの待ち状況によってエージェント(AWSの場合はEC2)の数を自動で増減させるものです。droneはkubernetesでも動かせるので似たようなことはできるかもしれませんが、autoscalerの方が素直な感じがするというかkubernetesの知識が不要で楽です。

ライセンス

droneは5000 builds per yearまでならStarterプランとして無料で使えるようです。

あれ、AutoscaleのFAQにはそんなことが書かれていませんね。どっちが正しいんでしょうか?

Open Source Editionでは使えないようです。Open Source EditionはSingle Nodeなのでそれはそう。Open Source Editionの説明は今の https://drone.io からのリンクが見当たらないような気がしますね。

構成

楽するためにdrone serverとdrone autoscalerを一つのEC2インスタンスで立てる構成を考えました。レジストリはECRを使います。

Drone autoscaler.png

以下のdocker-compose.ymlでなんとなく動きます。

docker-compose.yml
version: '3.7'

services:
  server:
    image: drone/drone:1
    volumes:
    - serverdata:/data
    ports: [ "80:80" ]
    restart: always
    environment:
    - DRONE_GITHUB_SERVER=https://github.com
    - DRONE_SERVER_HOST=your.drone.server
    - DRONE_GITHUB_CLIENT_ID=${GITHUB_CLIENT_ID}
    - DRONE_GITHUB_CLIENT_SECRET=${GITHUB_CLIENT_SECRET}
    - DRONE_RPC_SECRET=${DRONE_SERVER_SECRET}
    - DRONE_USER_CREATE=username:${DRONE_ADMIN_USER},machine:false,admin:true,token:${DRONE_ADMIN_TOKEN}
    - DRONE_AGENTS_ENABLED=true
    - DRONE_SERVER_PROTO=http
    - DRONE_LOGS_TRACE=true
    - DRONE_GIT_ALWAYS_AUTH=true  # github enterpriseの場合は必要
  autoscaler:
    image: drone/autoscaler
    links:
    - server:your.drone.server
    volumes:
    - autoscalerdata:/data
    ports: [ "8080:8080" ]
    restart: always
    environment:
    - DRONE_SERVER_PROTO=http
    - DRONE_SERVER_HOST=your.drone.server
    - DRONE_SERVER_TOKEN=${DRONE_ADMIN_TOKEN}
    - DRONE_AGENT_TOKEN=${DRONE_SERVER_SECRET}
    - DRONE_LOGS_TRACE=true
    - DRONE_INTERVAL=30s
    - DRONE_POOL_MIN_AGE=2h
    - DRONE_POOL_MIN=0
    - DRONE_POOL_MAX=4
    - DRONE_AMAZON_SUBNET_ID=${DRONE_AMAZON_SUBNET_ID}
    - DRONE_AMAZON_SECURITY_GROUP=${DRONE_AMAZON_SECURITY_GROUP}
    - DRONE_AMAZON_IMAGE=${DRONE_AMAZON_IMAGE}
    - DRONE_AMAZON_IAM_PROFILE_ARN=${DRONE_AMAZON_IAM_PROFILE_ARN}
    - DRONE_AMAZON_SSHKEY=${DRONE_AMAZON_SSHKEY}
    - DRONE_AMAZON_REGION=ap-northeast-1
    - DRONE_AMAZON_INSTANCE=t2.small
    - DRONE_AMAZON_DEVICE_NAME=/dev/xvda
    - AWS_IAM=true

volumes:
  serverdata:
  autoscalerdata:

必要な環境変数は.envなどに書きます。

  • server/autoscalerのDRONE_LOGS_TRACE

よくわからんところで止まるので、ログはたくさん出すようにしましょう。

  • autoscalerのDRONE_SERVER_HOST

autoscalerのDRONE_SERVER_HOSTはautoscalerがserverとやり取りするためのものですが、agentにもそのまま渡されるので、agentからも到達可能なドメインを指定する必要があります。ここではDRONE_SERVER_HOSTとしてはpublicなドメインを指定して、linksでautoscalerからも名前解決できるようにしています。

  • volume

droneはデフォルトではsqliteを使います。そのファイルを置く場所です。

  • DRONE_SERVER_SECRET

agentがserverとやり取りするときに使われる値です。server側はDRONE_RPC_SECRET、autoscaler側はDRONE_AGENT_TOKENという環境変数に与えます。autoscalerがagentを起動するときにそのまま渡すものだと思います。

  • DRONE_ADMIN_USER, DRONE_ADMIN_TOKEN

DRONE_USER_CREATEという環境変数があれば、これに従ってserver起動時にuserが作られます。autoscaler側でもサーバに対してAPI呼び出しをするためにadmin userのtokenが必要なので、一緒に指定します( autoscaler側ではDRONE_SERVER_TOKEN )。

  • min ageの挙動

agentが起動してからDRONE_POOL_MIN_AGE以内はそのインスタンスは削除されません。越えると削除されます。今までどれくらいビルドしてたかは関係ないみたいです。初めはなんとなく、最後のビルドが終わってからDRONE_POOL_MIN_AGEが経過すれば削除されるのかなと思っていましたが、そんなことはありませんでした。

  • IAM Roleとagentの起動とセキュリティグループ

アクセスキーとアクセスシークレットを指定します。あるいは、AWS_IAM=trueにするとEC2 IAM Roleが使われます。必要なactionは以下でした。

ec2:CreateTags
ec2:DescribeInstances
ec2:RunInstances
ec2:TerminateInstances

EC2インスタンス作成後、autoscalerはagentノードに対してagentのdockerイメージをpull & runします。このため、autoscalerからagentに対して2376ポートでアクセスできるようにします。ここは分かりにくいところで、FAQにも記載があります。

  • DRONE_AMAZON_IMAGE

DRONE_AMAZON_IMAGEに何も指定しなければそのリージョンのデフォルトのAMIが使われます。気になる人は自分でAMIを作りましょう。dockerがインストールしてあって起動後自動でdockerが立ち上がるようになっていればOKです。このときAMIによってはDRONE_AMAZON_DEVICE_NAMEに何か値を指定する必要があるかもしれません。違ったdevice nameだとインスタンスが起動後すぐ停止します。

  • DRONE_AMAZON_IAM_PROFILE_ARN

今回はECRを使いたいので、ECRが使えるIAM Roleを作って、そのARNをこの環境変数に指定します。agentノード立ち上げ時にそのIAM Roleが割り当てられます。

ECRへのアクセスはこちらを参考にしました。

ホストの/var/run/docker.sockをマウントし、事前のstepでイメージをpullします。ホストのディレクトリをマウントするのでリポジトリがtrustedである必要があります。serviceでprivate imageが使いたい場合はこれでpullしてから普通のstepでdetach: trueにすればできます ( https://docs.drone.io/user-guide/pipeline/services/#detached-steps )。

steps:
- name: pull
  image: docker:18
  commands:
  - apk --update add python3 && pip3 install awscli
  - $(aws ecr get-login --region ap-northeast-1 --no-include-email)
  - docker pul account.dkr.ecr.ap-northeast-1.amazonaws.com/image
  volumes:
  - name: docker
    path: /var/run/docker.sock
  • CLI

本体とautoscalerのドキュメントで情報が違います。autoscalerを使う場合はautoscalerの方が参考になります。

https://docs.drone.io/cli/
https://autoscale.drone.io/cli/

DRONE_TOKEN=http://localhost
DRONE_AUTOSCALER=http://localhost:8080
DRONE_TOKEN=${DRONE_ADMIN_TOKEN}

上記の設定で、EC2内からdrone cliが使えます。

感想

AWSのアクセスキーは発行したくないとかセキュリティグループはなるべく厳しくしたいとか考えており、そもそもの情報不足と色々知識がないせいもあって難しかったです。droneの気持ちになるというか全体的な動作の仕組みが頭に入っていると構築がやりやすいと思います。

7
5
1

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
7
5