Installing and configuring the GitHub Actions Runner Controller (legacy ARC)

What is the Github Actions Runner Controller?

The GitHub Actions Runner Controller “is a Kubernetes operator that orchestrates and scales self-hosted runners for GitHub Actions”. The controller removes the need for manually managing self-hosted runners and allows you to scale them up and down based on the workload. Also, important to me, it allows you to organize the runner by project and run them in the specific namespace, where I might want to deploy the application. Especially for larger projects or projects with hardware requirements, this is an important feature (i.e. building for ARM or other architectures than the default ones).

Warning: This article is about the legacy mode of ARC. For prod deployments or larger projects, runner scale sets are the way to go!.

The setup

The setup is pretty straightforward. Using Helm via ArgoCD the installation of the controller is as simple as:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: github-arc
  namespace: default
spec:
  project: default
  source:
    chart: actions-runner-controller
    repoURL: https://actions-runner-controller.github.io/actions-runner-controller
    targetRevision: 0.23.7
    helm:
      valuesObject:
        authSecret:
          create: false
          name: github-arc-token
  destination:
    name: "in-cluster"
    namespace: github-arc

The controller requires a secret with the GitHub token to authenticate with the GitHub API. Deploy the secret. I am using External Secrets to create the secret from a GitHub token stored in Vault.

i.e. via

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: github-arc-token
  namespace: github-arc
spec:
  refreshInterval: "15s"
  secretStoreRef:
    name: vault-backend
    kind: ClusterSecretStore
  target:
    name: github-arc-token
  data:
    - secretKey: github_token
      remoteRef:
        key: github-arc-token
        property: api-token

Once everything is healthy, you can create a runner via the CRD.

apiVersion: actions.summerwind.dev/v1alpha1
kind: RunnerDeployment
metadata:
  name: test-runner-deployment
  namespace: some-namespace
spec:
  replicas: 1
  template:
    spec:
      repository: 0xC9C3/blog.stack.rip

For more information on how to configure the runner, check the documentation. There is a lot of configuration options available. Especially if your workload would benefit from stateful runners, since by default all deployed runners are ephemeral, you should take a look.

In my opinion, this is the best way to run self-hosted runners for GitHub Actions in a small / hobby / non-prod level setup.

You can also enable the Prometheus endpoint for some neat metrics.

Resources