Actions Runner Controller 를 이용해 self-hosted runner로 배포하기


Actions Runner Controller 를 이용해 self-hosted runner로 배포하기

Github actions workflow를 실행시키는 환경에는 Github가 제공하는 github-hosted 환경과 자체적으로 관리하는 self-hosted 환경이 존재한다.

대부분(나 또한 그랬듯이) github-hosted 환경에서 빌드 및 배포 작업을 진행한다. 대표적으로 ubuntu-latest 환경(windows-latest, macos-latest..)이 있다.

 

하지만 이번에 self-hosted 환경에서 애플리케이션을 빌드 및 배포하는 작업을 진행했다.

self-hosted runner를 어디에서 실행시킬지도 2가지 방법으로 나뉜다. (다른 방법이 더 존재할 수도..)

 

EC2에서 실행

ec2에서 실행시키는 과정은 생각보다 간단하다. 그냥 ec2 하나 만들어 ec2에 접속해 self-hosted runner를 설치하여 백그라운드로 실행시키기만 하면 된다.

 

k8s에서 실행

나의 경우 쿠버네티스에서 runner를 실행시켜야 했는데, 일단 나는 k8s에 대해 공부해 본 적이 없다. 그냥 머리 박으면서 이번에 배포할 때 필요한 것들만 찾아서 적용했다.

본격적으로 ARC를 이용해 self-hosted runner로 배포했던 방법에 대해 알아보자.

이번에는 k8s에 대해서는 다루지 않을 예정이다. (나도 잘 모르기 때문..)

 

ARC(Actions Runner Controller) 란


Github에서 제공하는 ARC에 대한 설명을 보면 ARC(Actions Runner Controller)는 GitHub Action을 위해 self-hosted runner를 orchestrates하고 확장하는 Kubernetes operator 라고 한다.

정확한 의미는 잘 모르겠지만 self-hosted runner를 관리 및 확장해 주는 쿠버네티스 운영자인 것 같다.

https://github.com/actions/actions-runner-controller

 

GitHub - actions/actions-runner-controller: Kubernetes controller for GitHub Actions self-hosted runners

Kubernetes controller for GitHub Actions self-hosted runners - actions/actions-runner-controller

github.com

 

ARC를 사용하는 이유를 찾아보면 확장성과 속도측면에서 이점이 있는 것 같다.

arc를 이용해 띄운 runner pod을 k8s가 자동으로 리소스 낭비 없이 확장해 주고, 또 새로운 runner pod을 빠르게 할당하여 대기상태 없이 많은 workflow를 빠르게 실행할 수 있도록 한다.

ARC에 대해 이쯤 알아보고 사용해 보자.

 

ARC를 사용하기 위한 준비


  • k8s Cluster
  • Helm

우선 ARC를 사용하기 위해서는 쿠버네티스 클러스터와 helm이 설치되어야 한다.

helm은 쿠버네티스를 위한 패키지 매니저인데 간단히 말하면 (mac 기준) brew로 어떤 프로그램을 쉽게 설치해 주는 매니저 같이 쿠버네티스에서는 helm으로 프로그램을 설치하도록 도와주는 도구라고 생각하면 된다.

helm 설치는 아래 문서를 보면 쉽게 따라 할 수 있다.

https://helm.sh/docs/intro/install/

 

Installing Helm

Learn how to install and get running with Helm.

helm.sh

 

Install ARC


helm install arc --namespace "arc-system" --create-namespace \\
oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set-controller

이 명령어(helm 이용)로 ARC 설치를 한다.

버전을 명시해줄 수 있는데 버전 확인은 문서에서 확인 가능하다.

“arc-system”이라는 namespace에 Runner Scale Set을 관리하는 Controller를 설치한다.

 

Configuring Runner Scale Set


이제 빌드 및 배포 workflow가 실행될 runner 환경을 정의하기 위해 runnser scale set 설정을 해야 한다.

runner scale set은 Github job event를 모니터링하는 리스너를 pod으로 띄운다. (즉, runner scale set 설정을 해줘야 특정 repo의 workflow envent를 읽는 리스너가 생성된다.)

모니터링할(workflow event를 감지할) repo의 인증이 필요하다. 이때 PAT(Personal Access Token) 또는 Github App을 이용해 인증 가능한데 여기서는 Github App을 이용해 인증했다.

helm install "arc-runner-set" \\
--namespace "arc-runners" \\
--create-namespace \\
-f path/to/your/modified/values.yaml \\
oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set

설치가 완료되었으면 Runner Scale Set Controller가 설치된 “arc-system” namespace의 pod을 확인해 보자.

arc-gha-rs-controller-7c5554b9f7-jn8jx   1/1     Running   0          8m
arc-runner-set-754b578d-listener         1/1     Running   0          3m22s

위와 같이 두 개의 pod이 실행중일 것이다.

방금 설치해 준 “arc-runner-set” 이름의 리스너 pod이 띄워진 것을 확인할 수 있다.

이 pod이 workflow evnet 가 발생한 것을 감지하고 “arc-runners” 네임스페이스에 생성한 “arc-runner-set” pod을 실행시켜 러너가 동작한다.

 

 

위에서 설명하지 않은 scale set 설정 시 value 파일을 살펴보자.

Github App 사용 인증 시, 아래와 같이 작성하면 된다. (PAT 인증할 때와 다른 자세한 내용은 문서를 참고해서 작성하면 된다.) https://github.com/actions/actions-runner-controller/blob/master/charts/gha-runner-scale-set/values.yaml

 

Values.yaml 파일 작성 예시


values.yaml 파일에 어떤 깃허브의 workflow를 바라볼 것인지 url을 명시해줘야 한다. 그래야 생성되는 리스너가 workflow event를 감지한다.

githubConfigUrl: "GITHUB_REPO_URL"
githubConfigSecret:
  github_app_id: ""
  github_app_installation_id: ""
  github_app_private_key: |
    -----BEGIN RSA PRIVATE KEY-----
    ...
    -----END RSA PRIVATE KEY-----
    

template:
  spec:
    containers:
      - name: runner
        image: 123456789.dkr.ecr.ap-northeast-2.amazonaws.com/actions-runner-controller:latest
        command: [ "/home/runner/run.sh" ]

template에 명시해 준 image는 repo의 self-hosted runner가 설치된 이미지를 ecr에서 가져오는 것이다.

(직접 도커 이미지를 작성해서 runner를 설치하려 했으나 환경 세팅이 쉽지 않아 https://github.com/actions/runner/pkgs/container/actions-runner 여기서 기본 베이스 이미지를 pull 받아 내 repo의 runner만 설치해 주고 태그 따서 ecr에 push 했다.)

 

이 pod이 실행되면 ecr에서 이미지를 pull하고 컨테이너를 실행시켜 정의해 준 command 명령어가 실행되어 runner가 실행된다. 이러면 자체 호스팅된 runner에서 workflow가 돌아가는 것이다.

이렇게 하면 간단하게 k8s로 actions runner를 이용할 수 있다.

테스트를 위해 github workflow를 작성하자.

run-on 부분에 아까 만들어준 runner scale set의 이름(arc-runner-set)을 작성해 주고 실행해 보자.

name: test
on:
  workflow_dispatch:

jobs:
  test:
    runs-on: arc-runner-set
    steps:
    - run: echo "test"

arc-runners 네임스페이스의 pod을 확인해 보면 arc-runner-set pod이 새로 생성되어 이 pod에서 workflow가 실행된다.

$ kubectl -n arc-runners get pod

NAME                                READY   STATUS    RESTARTS   AGE
arc-runner-set-s4c9s-runner-7lwst   1/1     Running   0          4s

 

설명이 미숙한데 자세한 내용은 공식문서에 자세히 나와있으니 참고하면 된다.

https://github.com/actions/actions-runner-controller/tree/master