Confusion about correct use of ARC self-hosted runners #163996
-
Why are you starting this discussion?Question What GitHub Actions topic or product is this about?ARC (Actions Runner Controller) Discussion DetailsI have a question about how to correctly use the GitHub Actions Runner Controller to self-host runners. Problem statement: Run entire CI pipeline on self-hosted Kubernetes cluster. We also have multiple teams so each team will have at least 1 CI pipeline in the same cluster. Questions:
Apologies in advanced if this is a very basic question. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
But you're right: if each branch can have its own runner image, then you would need a different RunnerDeployment (runner-set) per image, since each RunnerDeployment uses one image. ARC doesn’t support dynamically changing the image per job at runtime. This can get complex if many branches have different images.
Also: Kubernetes mode in ARC is mainly about how runners are run (as pods, via controllers), not about switching images dynamically. |
Beta Was this translation helpful? Give feedback.
-
|
Hi @sharvil10, Your use case is quite common in enterprise environments. Let me address your questions with practical solutions: 1. ARC vs azure/k8s-deploy You're absolutely correct. ARC is the appropriate choice for running CI workloads on Kubernetes. The azure/k8s-deploy action is designed for deploying applications to clusters, not for executing CI jobs within pods. 2. Dynamic Image Management Strategy Instead of creating separate runner-sets for each branch, here's a more scalable approach: # Use ARC's containerMode with dynamic image selection
apiVersion: actions.summerwind.dev/v1alpha1
kind: RunnerDeployment
metadata:
name: dynamic-runner
spec:
template:
spec:
containers:
- name: runner
image: ghcr.io/actions/actions-runner:latest # Base runner
- name: docker
image: docker:dind # For building images3. Implement a Job-Level Image Strategy Use GitHub Actions to dynamically build and use images within the job: jobs:
ci:
runs-on: [self-hosted, kubernetes]
steps:
- uses: actions/checkout@v4
- name: Build CI Image
run: |
# Build image specific to this branch/commit
docker build -t ci-image:${{ github.sha }} .
- name: Run Tests in Custom Image
uses: docker://ci-image:${{ github.sha }}
with:
args: |
make test4. Kubernetes Jobs Mode (Recommended) Consider using ARC's Kubernetes mode with ephemeral runners: apiVersion: actions.summerwind.dev/v1alpha1
kind: RunnerDeployment
metadata:
name: ephemeral-runner
spec:
template:
spec:
ephemeral: true # Runner terminates after job
dockerEnabled: true
dockerdWithinRunnerContainer: trueThis allows you to:
5. Multi-Team Isolation Pattern For multiple teams, implement namespace-based isolation: # Create team-specific namespaces
kubectl create namespace team-a-runners
kubectl create namespace team-b-runners
# Deploy ARC per namespace with RBAC
helm install arc-team-a \
--namespace team-a-runners \
--set githubConfigUrl="https://github.com/org/team-a" \
actions-runner-controller/actions-runner-controllerAlternative Architecture: If branch-specific images are critical, consider a GitOps approach:
# Example controller logic
def on_workflow_requested(event):
branch = event['ref']
image = f"ghcr.io/org/ci-image:{branch}"
# Create RunnerDeployment if not exists
if not runner_exists(branch):
create_runner_deployment(branch, image)
# Set TTL for auto-cleanup
set_runner_ttl(branch, "1h")This approach scales better than static runner-sets per branch and maintains the flexibility you need. |
Beta Was this translation helpful? Give feedback.
Hi @sharvil10,
Your use case is quite common in enterprise environments. Let me address your questions with practical solutions:
1. ARC vs azure/k8s-deploy
You're absolutely correct. ARC is the appropriate choice for running CI workloads on Kubernetes. The azure/k8s-deploy action is designed for deploying applications to clusters, not for executing CI jobs within pods.
2. Dynamic Image Management Strategy
Instead of creating separate runner-sets for each branch, here's a more scalable approach: