actions-runner-controller使ってみた
最近とあるCIからGIthub Actionsに移行するタスクをしています。 コード管理はGithub Enterprise Serverを使っているため、Github-hosted Runnerを使えず、良い感じにself-hosted runnerを実行する方法を探していたところ、こちらを見つけました。
製作者の紹介記事はこちら
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は出ているので対応していただけることを切に願います。
おわりに
self-hosted runnerをkubernetesで実行できるツールactions-runner-controllerを紹介しました。
非常に使いやすいポイントだらけですが、大本のrunnerの問題であるGHESでキャッシュができない点がネックです。
Githubが対応してくれないとプロダクトによっては使い続けることは難しいかもしれません。