How do you run self-hosted GitHub Actions runners at scale on Kubernetes, and what are the security tradeoffs versus GitHub-hosted runners?
Quick Answer
Use Actions Runner Controller (ARC): ephemeral runner pods scale with queued jobs and are destroyed after each job, giving hosted-like isolation with self-hosted control (network access, custom images, GPUs, cost). The tradeoffs: you own patching and capacity, and self-hosted runners on public repos are dangerous — a fork PR can execute arbitrary code inside your network.
Detailed Answer
ARC runs a controller that watches GitHub's job queue (via runner scale sets) and launches one ephemeral pod per job — the pod registers, runs exactly one job, and is deleted, so state can't leak between jobs. You choose runner images, instance types, and network position (inside the VPC — the usual reason to self-host: reaching private registries, databases for integration tests, or on-prem systems). Scale-to-zero keeps idle cost near nothing. Security calculus: GitHub-hosted runners give you a fresh VM per job, patched by GitHub, with no path into your network — the safest default. Self-hosted flips that: jobs execute inside your perimeter, so treat runner pods as untrusted workloads — dedicated node pools, NetworkPolicies restricting egress to what CI needs, no cluster-admin service accounts, and workload identity (OIDC) instead of static cloud keys. The hard rule: never attach self-hosted runners to public repositories — pull_request from a fork means anyone on the internet can run code on your infrastructure. Docker-in-Docker deserves scrutiny too: prefer rootless builds (BuildKit/kaniko-style) over privileged DinD pods.
Code Example
# ARC runner scale set (values.yaml)
githubConfigUrl: https://github.com/my-org
minRunners: 0
maxRunners: 40
template:
spec:
containers:
- name: runner
image: ghcr.io/my-org/ci-runner:2026.07
resources: {limits: {cpu: '4', memory: 8Gi}}
# jobs: runs-on: arc-linux-amd64Interview Tip
'Ephemeral, one job per pod, then destroyed' is the phrase that matters, plus the hard rule about public repos — that combination shows you understand why ARC exists and what it doesn't fix.