- Create A Self-Hosted Actions Runner On Your Kubernetes Cluster
- Motivation
- Optional: Customize Your Self Hosted Runner
- Refresh Docker Image
- Setup Instructions
GitHub Actions allow you to use self hosted runners. From the docs:
Self-hosted runners offer more control of hardware, operating system, and software tools than GitHub-hosted runners provide. With self-hosted runners, you can choose to create a custom hardware configuration with more processing power or memory to run larger jobs, install software available on your local network, and choose an operating system not offered by GitHub-hosted runners. Self-hosted runners can be physical, virtual, in a container, on-premises, or in a cloud.
This repository shows how to run a self hosted runner in a Kubernetes cluster, which is useful if your Actions runner needs to create resources or update deployments.
This project builds upon github-developer/self-hosted-runners-anthos, which uses docker-in-docker in order to instantiate a self-hosted runner on kubernetes.
Note: you only need to do this if you wish to customize your Actions runner.
We have a pre-built Docker image hosted at github/k8s-actions-runner, that uses docker-in-docker to orchestrate all the necessary dependencies for a self hosted runner.
This image is tagged with the version of the actions/runner release. For example, the image github/k8s-actions-runner:2.263.0
corresponds to the actions/runner v2.263.0 release. Furthermore, the latest release is also tagged with latest
.
If you wish to customize the Actions runner with additional dependencies you can edit the Dockerfile. If you customize the docker image, you need to build and push the container to your Docker repository.
# Build Docker Image For Custom Runner (Optional)
export ACTIONS_IMAGE_NAME="your_docker_repo/your_image_name"
docker build -t $ACTIONS_IMAGE_NAME .
docker push $ACTIONS_IMAGE_NAME
Prerequisites: These instructions assume:
- You have kubectl installed and configured to access a kubernetes cluster where you wish to instantiate self-hosted runners.
- You have sufficent permissions to create resources (namespaces, deployments, secrets, etc.) in this cluster.
- Familiarity with kubernetes, especially with debugging workloads and inspecting logs.
You will need a cli tool called envsubst
. You can install envsubst like this:
- on mac:
brew install gettext
- on ubuntu:
apt-get install gettext-base
If you are sharing a cluster with others that have already setup a self-hosted Actions runner you can probably skip this step.
The scripts in this repo will use a k8s namespace called actions
. If this namespace is not available it will be created for you.
- Create a Personal Access Token. From the documentation, "Access tokens require repo scope for private repos and public_repo scope for public repos". You should use a service account, not a personal account as this will be used to register your runner with your repositories. Finally, you should only do this if you are confident that your kubernetes cluster is secure as anyone with access to your cluster will be able to obtain this token.
Store your PAT in an enviornment variable named ACTIONS_PAT
. You can do this in the terminal like so:
> export ACTIONS_PAT=<YOUR_PAT>
-
Store these secrets on your K8s cluster, along with role bindings on the
actions
namespace:./k8s_setup/setup.sh
By default, this script will not update secrets for self-hosted runners if one already exists in your cluster. You can override this with a
--force-update
flag:./k8s_setup/setup.sh --force-update
You must perform the below steps for each repository you want to bind self-hosted runners to. While it is possible to create a self-hosted runner for an organization, the tools in this repo currently only support repo-level self hosted runners.
You must set the below variables before deploying your self-hosted Actions runner:
ACTIONS_GITHUB_REPO
:- this is the GitHub repository in the form of orginization/repository. For example, a valid value is
github/semantic
which refers to this repo.
- this is the GitHub repository in the form of orginization/repository. For example, a valid value is
ACTIONS_IMAGE_NAME
: (optional)- the Docker Image that references the location of the image of your self-hosted runner. If this is a private repository, your k8s cluster must have the ability to pull from this registry. Furthermore, if your private registry requires a login, you may have to modify deployment.yml to include an ImagePullSecret, which is outside the scope of this tutorial. If no value is specified, this defaults to
github/k8s-actions-runner:latest
- the Docker Image that references the location of the image of your self-hosted runner. If this is a private repository, your k8s cluster must have the ability to pull from this registry. Furthermore, if your private registry requires a login, you may have to modify deployment.yml to include an ImagePullSecret, which is outside the scope of this tutorial. If no value is specified, this defaults to
ACTIONS_DEPLOY_NAME
: (optional)- you can name this anything you want, you need a unique name for each repo. If this is not specified the execution script will set this to
actions-runner-$ACTIONS_GITHUB_REPO
, with the forward slash/
replaced with a dash-
.
- you can name this anything you want, you need a unique name for each repo. If this is not specified the execution script will set this to
You can set your environment variables in the terminal like this:
export ACTIONS_GITHUB_REPO=<Your_Org>/<Your Repo> # ex: "github/semantic"
export ACTIONS_IMAGE_NAME=<Your Image Name> # ex: "github/k8s-actions-runner:2.263.0"
Run this from the terminal:
./deploy_runner/deploy.sh
You can check the status of your runner with
kubectl -n actions get deployment
- To see your runners, take note of the deployment names you want to shut down.
kubectl -n actions get deploy
- Delete the specific deployment(s)
kubectl -n actions delete <deployment_name>