お元気そうで残念です

もんじゃ焼きが転がってるところにいます。

actions-runner-controller使ってみた

最近とあるCIからGIthub Actionsに移行するタスクをしています。 コード管理はGithub Enterprise Serverを使っているため、Github-hosted Runnerを使えず、良い感じにself-hosted runnerを実行する方法を探していたところ、こちらを見つけました。

github.com

製作者の紹介記事はこちら

GitHub Actions の Runner の運用を自動化する | SummerWind

メリット、デメリット 使用感などをまとめていきます。

メリット

冪等性がある

公式の手順通りに実行するとjob終了後もrunnerタスクは残り続けるし、VM内で変更したファイルもそのままです。 このcontrollerでは受け取ったjobを実行するごとにpodが再作成されるため、冪等性があります。

オートスケールする

kubernetesで動作するため当たり前ですがオートスケールさせることが出来ます。 溜まっているqueueに応じてオートスケールします。

デメリット

kubernetes clusterを管理する必要がある

self-hosted runnerのためだけにclusterを管理する必要があります。
インスタンスコストはもちろん、運用コストも少なくないので本当にこのcontrollerを採用するべきなのか検討するべきです。
今回は利用するorganization、実行job数が多く、冪等性とオートスケールが必須要件でしたので採用しました。

docker in dockerになる

docker actionを実行する場合は、 sidecarで立ち上がるdockerコンテナ内で実行されます。(runner内での実行も可能) dindになるためprivileged: trueにする必要があり実行されるjobによっては危険です。

使用感

その他雑多なことを書いていきます。

使い方

詳しい設定手順は公式サイトのREADMEを参照してください。

GHES独自の部分やManifstなどについて触れていきます。

Personal Access Tokenの使用

GHESに接続するためにPersonal Access Tokenを設定します。
公式DocではGithub Appも使えると書いていますが、api urlがGHESのurlで更新されていないため、GitHub Appでは接続出来ないため注意してください。

kubectl create secret generic controller-manager \
    -n actions-runner-system \
    --from-literal=github_token=${GITHUB_TOKEN}

実行対象Repositoryを取得

HorizontalRunnerAutoscaler(HPAのRunner版 以下HRA)を正しく動作させるために実行対象Repositoryをmetrics.repositoryNamesに記載する必要があります。 Organaization内の全Repositoryは以下のコマンドで取得できるため、取得して設定してください。

curl -v -H "Authorization: token TOKEN" https://GHES_URL/api/v3/orgs/ORG/repos | jq -c -r '.[].name'

RunnerのManifest

Organization単位でRunnerを登録するManifestです。
実行ログを保存するためにsidecarでaws-cliコンテナを立てて、podが終了するときにS3に送信するようにしています。
HRAを正しく動作させるために先程取得したRepository名を設定してください。

apiVersion: actions.summerwind.dev/v1alpha1
kind: RunnerDeployment
metadata:
  name: ORG-runnerdeploy
spec:
  replicas: 1
  template:
    spec:
      labels:
        - test-runner
      initContainers:
      - name: chmod
        image: alpine
        command: ["chmod", "777", "/runner/_diag"]
        volumeMounts:
        - name: runner-log
          mountPath: /runner/_diag
      organization: ORG
      image: summerwind/actions-runner:v2.274.1
      dockerdWithinRunnerContainer: false
      env:
      - name: GITHUB_ENTERPRISE_URL
        value: "https://GHES_URL/"
      volumeMounts:
      - name: runner-log
        mountPath: /runner/_diag
      volumes:
      - name: runner-log
        emptyDir:
      sidecarContainers:
        - name: aws-cli
          image: amazon/aws-cli:2.1.1
          command: ["/bin/bash", "-c"]
          args: ["trap \"aws s3 cp /var/log/runner-log/Worker* s3://BUCKET/self-hosted-runner/`date +%Y/%m/%d/`  --region REGION\" TERM INT; sleep infinity & wait"]
          env:
          - name: AWS_ACCESS_KEY_ID
            valueFrom:
              secretKeyRef:
                name: aws-access
                key: aws_access_key_id
          - name: AWS_SECRET_ACCESS_KEY
            valueFrom:
              secretKeyRef:
                name: aws-access
                key: aws_secret_access_key
          volumeMounts:
          - name: runner-log
            mountPath: /var/log/runner-log

---
apiVersion: actions.summerwind.dev/v1alpha1
kind: HorizontalRunnerAutoscaler
metadata:
  name: ORG-runnerdeploy-autoscaler
spec:
  scaleTargetRef:
    name: ORG-runnerdeploy
  minReplicas: 1
  maxReplicas: 5
  scaleDownDelaySecondsAfterScaleOut: 300
  metrics:
  - type: TotalNumberOfQueuedAndInProgressWorkflowRuns
    repositoryNames:
    - repositoryA
    - repositoryB

ありがたいこと

Organization単位でRunnerを設定できるしオートスケールできる

RunnerとHRAをOrganization単位で設定できるので、複数Organization対応も簡単にできました。
他のツールだと複数Organizationは難しそうでしたので非常に感謝しています!

設定が楽

上記のManifestの通り設定が非常に簡単です。
Kubernetes Clusterを管理する点を除けば。

困っていること

キャッシュできない

actions-controller-runnerの問題ではなく、self-hosted runnerの問題です。
GHESで実行すると、キャッシュ出来ないので実行時間がかかりまくって使い物にならないのではという話がでています。

たまにrunnerが固まる

原因がつかめていないのですが、実行後のrunnerが削除されずqueueが溜まり続けることがあります。
runnerを手動で削除すると大体は解消しますが、たまにmanagerを再作成しないと直らないときもあります。

Repository名の設定が面倒

Repositoryが追加されると毎回Manifestに追加する必要があるため正直めんどい。
Issueは出ているので対応していただけることを切に願います。

Autoscaling for an organization runner · Issue #158 · actions-runner-controller/actions-runner-controller · GitHub

おわりに

self-hosted runnerをkubernetesで実行できるツールactions-runner-controllerを紹介しました。
非常に使いやすいポイントだらけですが、大本のrunnerの問題であるGHESでキャッシュができない点がネックです。
Githubが対応してくれないとプロダクトによっては使い続けることは難しいかもしれません。