Skip to content

electrocucaracha/kubevirt-actions-runner

Repository files navigation

Kubevirt Actions Runner

License GitHub Super-Linter

visitors Scc Code Badge Scc COCOMO Badge

Summary

kubevirt-actions-runner is a runner image for Actions Runner Controller (ARC) that spawns ephemeral virtual machines for jobs using KubeVirt.

Use cases

  • Windows and macOS jobs
  • Jobs that require configuring system services
  • Jobs that require stronger isolation

Usage

You need a Kubernetes cluster with Actions Runner Controller and KubeVirt installed.

1. Create VirtualMachine template

First, we need to create a VirtualMachine to act as a template for the runner VMs. kubevirt-actions-runner will create VirtualMachineInstances from it, and the VirtualMachine itself will never be started.

Create a namespace and apply the sample template:

! kubectl get namespaces "${namespace}" && kubectl create namespace "${namespace}"
kubectl apply -f scripts/vm_template.yml -n "${namespace}"

Let's take a deeper look at this sample VirtualMachine. Inside we mount the runner-info volume:

apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: ubuntu-jammy-vm
spec:
  runStrategy: Manual
  template:
    spec:
      domain:
        devices:
          filesystems:
            - name: runner-info
              virtiofs: {}

This runner-info volume will be injected by kubevirt-actions-runner, containing runner-info.json that looks like the following:

{
  "name": "runner-abcde-abcde",
  "token": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
  "url": "https://github.com/org/repo",
  "ephemeral": true,
  "groups": "",
  "labels": ""
}

2. Set up RBAC

The service account of the runner pod needs to be able to create VirtualMachineInstances. An example is as follows:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: kubevirt-actions-runner
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: kubevirt-actions-runner
rules:
  - apiGroups: ["kubevirt.io"]
    resources: ["virtualmachines"]
    verbs: ["get", "watch", "list"]
  - apiGroups: ["kubevirt.io"]
    resources: ["virtualmachineinstances"]
    verbs: ["get", "watch", "list", "create", "delete"]
  - apiGroups: ["cdi.kubevirt.io"]
    resources: ["datavolumes"]
    verbs: ["get", "watch", "list", "create", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cdi-cloner
rules:
  - apiGroups: ["cdi.kubevirt.io"]
    resources: ["datavolumes/source"]
    verbs: ["create"]

3. Create runner scale set

You can configure the runner scale set using Helm. Use the following values.yaml:

githubConfigUrl: https://github.com/<your_enterprise/org/repo>
githubConfigSecret: ...
template:
  spec:
    serviceAccountName: kubevirt-actions-runner
    containers:
      - name: runner
        image: electrocucaracha/kubevirt-actions-runner:latest
        command: []
        env:
          - name: KUBEVIRT_VM_TEMPLATE
            value: ubuntu-jammy-vm
          - name: RUNNER_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
helm upgrade --create-namespace --namespace "${namespace}" \
    --wait --install --values values.yml vm-self-hosted \
    oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set

The lifecycle of the spawned VMI is bound to the runner pod. If one of them exits, the other will be terminated as well.

About

GitHub self-host actions project for creation of Kubevirt runners

Topics

Resources

Stars

Watchers

Forks

Packages