Thanks! We'll be in touch in the next 12 hours
Oops! Something went wrong while submitting the form.

How to deploy GitHub Actions Self-Hosted Runners on Kubernetes

Mahesh Khade

Cloud & DevOps

GitHub Actions jobs are run in the cloud by default; however, sometimes we want to run jobs in our own customized/private environment where we have full control. That is where a self-hosted runner saves us from this problem. 

To get a basic understanding of running self-hosted runners on the Kubernetes cluster, this blog is perfect for you. 

We’ll be focusing on running GitHub Actions on a self-hosted runner on Kubernetes. 

An example use case would be to create an automation in GitHub Actions to execute MySQL queries on MySQL Database running in a private network (i.e., MySQL DB, which is not accessible publicly).

A self-hosted runner requires the provisioning and configuration of a virtual machine instance; here, we are running it on Kubernetes. For running a self-hosted runner on a Kubernetes cluster, the action-runner-controller helps us to make that possible.

This blog aims to try out self-hosted runners on Kubernetes and covers:

  1. Deploying MySQL Database on minikube, which is accessible only within Kubernetes Cluster.
  2. Deploying self-hosted action runners on the minikube.
  3. Running GitHub Action on minikube to execute MySQL queries on MySQL Database.

Steps for completing this tutorial:

Create a GitHub repository

  1. Create a private repository on GitHub. I am creating it with the name velotio/action-runner-poc.

Setup a Kubernetes cluster using minikube

  1. Install Docker.
  2. Install Minikube.
  3. Install Helm 
  4. Install kubectl

Install cert-manager on a Kubernetes cluster

  • By default, actions-runner-controller uses cert-manager for certificate management of admission webhook, so we have to make sure cert-manager is installed on Kubernetes before we install actions-runner-controller. 
  • Run the below helm commands to install cert-manager on minikube.

CODE: https://gist.github.com/velotiotech/324337059c95670d82a76afe8f3b3313.sh

  • Verify installation using “kubectl --namespace cert-manager get all”. If everything is okay, you will see an output as below:

Setting Up Authentication for Hosted Runners

There are two ways for actions-runner-controller to authenticate with the GitHub API (only 1 can be configured at a time, however):

  1. Using a GitHub App (not supported for enterprise-level runners due to lack of support from GitHub.)
  2. Using a PAT (personal access token)

To keep this blog simple, we are going with PAT.

To authenticate an action-runner-controller with the GitHub API, we can use a  PAT with the action-runner-controller registers a self-hosted runner.

  • Go to account > Settings > Developers settings > Personal access token. Click on “Generate new token”. Under scopes, select “Full control of private repositories”.
  •  Click on the “Generate token” button.
  • Copy the generated token and run the below commands to create a Kubernetes secret, which will be used by action-runner-controller deployment.

CODE: https://gist.github.com/velotiotech/6222fffb26b2969c8a7d3265ec7d6d4c.js

Create namespace “actions-runner-system”
CODE: https://gist.github.com/velotiotech/2efc0b32c30f4dc9b5ab748910944c80.js

Create secret

CODE: https://gist.github.com/velotiotech/f6e6b5f2ab2bdbc540d9953fb6bc48a1.js

Install action runner controller on the Kubernetes cluster

  • Run the below helm commands

CODE: https://gist.github.com/velotiotech/62c12c1a8fbb1df43947ec58a341e119.js

  • Verify that the action-runner-controller installed properly using below command

CODE: https://gist.github.com/velotiotech/962dd612daf759491cc84dd283b79c19.js


Create a Repository Runner

  • Create a RunnerDeployment Kubernetes object, which will create a self-hosted runner named k8s-action-runner for the GitHub repository velotio/action-runner-poc
  • Please Update Repo name from “velotio/action-runner-poc” to “<Your-repo-name>”
  • To create the RunnerDeployment object, create the file runner.yaml as follows:

CODE: https://gist.github.com/velotiotech/5fe1f4f795343268cf62fffac4d230ab.js

  • To create, run this command:

CODE: https://gist.github.com/velotiotech/1b09e8d0288d8526c42e2008aeb99f3c.js

Check that the pod is running using the below command:

CODE: https://gist.github.com/velotiotech/979bd2514c3c6056f205d2c0116e3ae0.js

  • If everything goes well, you should see two action runners on the Kubernetes, and the same are registered on Github. Check under Settings > Actions > Runner of your repository.
  • Check the pod with kubectl get po -n actions-runner-system


Install a MySQL Database on the Kubernetes cluster

  • Create PV and PVC for MySQL Database. 
  • Create mysql-pv.yaml with the below content.

CODE: https://gist.github.com/velotiotech/850202ea6d7ada7090e95525b90757dc.js

  • Create mysql namespace

CODE: https://gist.github.com/velotiotech/8744ba06f9c512f9c13ab60f863dd083.js

  • Now apply mysql-pv.yaml to create PV and PVC 

CODE: https://gist.github.com/velotiotech/ed8261dd98d70f4b3fc7004512a8da99.js

Create the file mysql-svc-deploy.yaml and add the below content to mysql-svc-deploy.yaml

Here, we have used MYSQL_ROOT_PASSWORD as “password”.

CODE: https://gist.github.com/velotiotech/d5b8bc4ce55312726e4b9202133f75b1.js

  • Create the service and deployment

CODE: https://gist.github.com/velotiotech/766d383a6b8df457bd9d7a9b2f411d28.js

  • Verify that the MySQL database is running

CODE: https://gist.github.com/velotiotech/67fc260556f3bd1889832e4b7c7061b4.js

Create a GitHub repository secret to store MySQL password

As we will use MySQL password in the GitHub action workflow file as a good practice, we should not use it in plain text. So we will store MySQL password in GitHub secrets, and we will use this secret in our GitHub action workflow file.

  • Create a secret in the GitHub repository and give the name to the secret as “MYSQL_PASS”, and in the values, enter “password”. 

Create a GitHub workflow file

  • YAML syntax is used to write GitHub workflows. For each workflow, we use a separate YAML file, which we store at .github/workflows/ directory. So, create a .github/workflows/ directory in your repository and create a file .github/workflows/mysql_workflow.yaml as follows.

CODE: https://gist.github.com/velotiotech/c3b98a872f9fb85734978588cd69fd76.js

  • If you check the docker run command in the mysql_workflow.yaml file, we are referring to the .sql file, i.e., test.sql. So, create a test.sql file in your repository as follows:

CODE: https://gist.github.com/velotiotech/b6693d34409c8948b41348804620372e.js

  • In test.sql, we are running MySQL queries like create tables.
  • Push changes to your repository main branch.
  • If everything is fine, you will be able to see that the GitHub action is getting executed in a self-hosted runner pod. You can check it under the “Actions” tab of your repository.
  • You can check the workflow logs to see the output of SHOW TABLES—a command we have used in the test.sql file—and check whether the persons tables is created.

References

Get the latest engineering blogs delivered straight to your inbox.
No spam. Only expert insights.
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Did you like the blog? If yes, we're sure you'll also like to work with the people who write them - our best-in-class engineering team.

We're looking for talented developers who are passionate about new emerging technologies. If that's you, get in touch with us.

Explore current openings

How to deploy GitHub Actions Self-Hosted Runners on Kubernetes

GitHub Actions jobs are run in the cloud by default; however, sometimes we want to run jobs in our own customized/private environment where we have full control. That is where a self-hosted runner saves us from this problem. 

To get a basic understanding of running self-hosted runners on the Kubernetes cluster, this blog is perfect for you. 

We’ll be focusing on running GitHub Actions on a self-hosted runner on Kubernetes. 

An example use case would be to create an automation in GitHub Actions to execute MySQL queries on MySQL Database running in a private network (i.e., MySQL DB, which is not accessible publicly).

A self-hosted runner requires the provisioning and configuration of a virtual machine instance; here, we are running it on Kubernetes. For running a self-hosted runner on a Kubernetes cluster, the action-runner-controller helps us to make that possible.

This blog aims to try out self-hosted runners on Kubernetes and covers:

  1. Deploying MySQL Database on minikube, which is accessible only within Kubernetes Cluster.
  2. Deploying self-hosted action runners on the minikube.
  3. Running GitHub Action on minikube to execute MySQL queries on MySQL Database.

Steps for completing this tutorial:

Create a GitHub repository

  1. Create a private repository on GitHub. I am creating it with the name velotio/action-runner-poc.

Setup a Kubernetes cluster using minikube

  1. Install Docker.
  2. Install Minikube.
  3. Install Helm 
  4. Install kubectl

Install cert-manager on a Kubernetes cluster

  • By default, actions-runner-controller uses cert-manager for certificate management of admission webhook, so we have to make sure cert-manager is installed on Kubernetes before we install actions-runner-controller. 
  • Run the below helm commands to install cert-manager on minikube.

CODE: https://gist.github.com/velotiotech/324337059c95670d82a76afe8f3b3313.sh

  • Verify installation using “kubectl --namespace cert-manager get all”. If everything is okay, you will see an output as below:

Setting Up Authentication for Hosted Runners

There are two ways for actions-runner-controller to authenticate with the GitHub API (only 1 can be configured at a time, however):

  1. Using a GitHub App (not supported for enterprise-level runners due to lack of support from GitHub.)
  2. Using a PAT (personal access token)

To keep this blog simple, we are going with PAT.

To authenticate an action-runner-controller with the GitHub API, we can use a  PAT with the action-runner-controller registers a self-hosted runner.

  • Go to account > Settings > Developers settings > Personal access token. Click on “Generate new token”. Under scopes, select “Full control of private repositories”.
  •  Click on the “Generate token” button.
  • Copy the generated token and run the below commands to create a Kubernetes secret, which will be used by action-runner-controller deployment.

CODE: https://gist.github.com/velotiotech/6222fffb26b2969c8a7d3265ec7d6d4c.js

Create namespace “actions-runner-system”
CODE: https://gist.github.com/velotiotech/2efc0b32c30f4dc9b5ab748910944c80.js

Create secret

CODE: https://gist.github.com/velotiotech/f6e6b5f2ab2bdbc540d9953fb6bc48a1.js

Install action runner controller on the Kubernetes cluster

  • Run the below helm commands

CODE: https://gist.github.com/velotiotech/62c12c1a8fbb1df43947ec58a341e119.js

  • Verify that the action-runner-controller installed properly using below command

CODE: https://gist.github.com/velotiotech/962dd612daf759491cc84dd283b79c19.js


Create a Repository Runner

  • Create a RunnerDeployment Kubernetes object, which will create a self-hosted runner named k8s-action-runner for the GitHub repository velotio/action-runner-poc
  • Please Update Repo name from “velotio/action-runner-poc” to “<Your-repo-name>”
  • To create the RunnerDeployment object, create the file runner.yaml as follows:

CODE: https://gist.github.com/velotiotech/5fe1f4f795343268cf62fffac4d230ab.js

  • To create, run this command:

CODE: https://gist.github.com/velotiotech/1b09e8d0288d8526c42e2008aeb99f3c.js

Check that the pod is running using the below command:

CODE: https://gist.github.com/velotiotech/979bd2514c3c6056f205d2c0116e3ae0.js

  • If everything goes well, you should see two action runners on the Kubernetes, and the same are registered on Github. Check under Settings > Actions > Runner of your repository.
  • Check the pod with kubectl get po -n actions-runner-system


Install a MySQL Database on the Kubernetes cluster

  • Create PV and PVC for MySQL Database. 
  • Create mysql-pv.yaml with the below content.

CODE: https://gist.github.com/velotiotech/850202ea6d7ada7090e95525b90757dc.js

  • Create mysql namespace

CODE: https://gist.github.com/velotiotech/8744ba06f9c512f9c13ab60f863dd083.js

  • Now apply mysql-pv.yaml to create PV and PVC 

CODE: https://gist.github.com/velotiotech/ed8261dd98d70f4b3fc7004512a8da99.js

Create the file mysql-svc-deploy.yaml and add the below content to mysql-svc-deploy.yaml

Here, we have used MYSQL_ROOT_PASSWORD as “password”.

CODE: https://gist.github.com/velotiotech/d5b8bc4ce55312726e4b9202133f75b1.js

  • Create the service and deployment

CODE: https://gist.github.com/velotiotech/766d383a6b8df457bd9d7a9b2f411d28.js

  • Verify that the MySQL database is running

CODE: https://gist.github.com/velotiotech/67fc260556f3bd1889832e4b7c7061b4.js

Create a GitHub repository secret to store MySQL password

As we will use MySQL password in the GitHub action workflow file as a good practice, we should not use it in plain text. So we will store MySQL password in GitHub secrets, and we will use this secret in our GitHub action workflow file.

  • Create a secret in the GitHub repository and give the name to the secret as “MYSQL_PASS”, and in the values, enter “password”. 

Create a GitHub workflow file

  • YAML syntax is used to write GitHub workflows. For each workflow, we use a separate YAML file, which we store at .github/workflows/ directory. So, create a .github/workflows/ directory in your repository and create a file .github/workflows/mysql_workflow.yaml as follows.

CODE: https://gist.github.com/velotiotech/c3b98a872f9fb85734978588cd69fd76.js

  • If you check the docker run command in the mysql_workflow.yaml file, we are referring to the .sql file, i.e., test.sql. So, create a test.sql file in your repository as follows:

CODE: https://gist.github.com/velotiotech/b6693d34409c8948b41348804620372e.js

  • In test.sql, we are running MySQL queries like create tables.
  • Push changes to your repository main branch.
  • If everything is fine, you will be able to see that the GitHub action is getting executed in a self-hosted runner pod. You can check it under the “Actions” tab of your repository.
  • You can check the workflow logs to see the output of SHOW TABLES—a command we have used in the test.sql file—and check whether the persons tables is created.

References

Did you like the blog? If yes, we're sure you'll also like to work with the people who write them - our best-in-class engineering team.

We're looking for talented developers who are passionate about new emerging technologies. If that's you, get in touch with us.

Explore current openings