For Industrial & IoT, go to portainer.industries · For AI, go to portainer.ai
Register for our August 27th webinar: Why Kubernetes Docs Keep Losing You (And What We Did About It) →
Blog

GitOps with Portainer using GitHub Actions

Key takeaways

Screenshot 2022-10-15 at 17.52.27

Based on your requirements, modify the HorizontalRunnerAutoscaler block to customize configurations such as minReplicas, maxReplicas, metrics, and so on.

Conclusion

As you can see, not only Portainer can be used to deploy applications via GUI, but it also provides APIs (The API specifications are published via Swagger) for the end users to interact with Portainer programatically.

Give Portainer a try today, experience simplified Kubernetes Operations today.

Introduction

Portainer has released an awesome GitOps feature for end-users to boost their deployments to Portainer based on Git, and our CEO, Neil has put together an excellent blog on Portainer as part of your CI/CD Pipeline for Docker and Kubernetes. In addition to this, I wanted to share how GitHub Actions can be utilized to achieve the same results in a programmatical way.

In this blog post, I will be going through:

  1. Deploy Portainer on a local Kubernetes cluster
  2. Setup self-hosted GitHub Actions runner using Portainer
  3. Write a simple GitHub Actions workflow to interact with Portainer using a simple curl operation to deploy a GitOps based application

Note: All the artefacts used in this blog can be found in this

Portainer Deployment in Kubernetes

We will need to boostrap a local Kubernetes cluster. In my case, I have utilized an Elastic Kubernetes Service (EKS) cluster in AWS, but you can use a kind, MicroK8s, K3d, minikube, or any other Kubernetes clusters.

In your Kubernetes cluster, deploy a Portainer instance using our Helm chart. Please refer to our doc for more details.

GitHub Actions Self-hosted Runners

Next, let's provision GitHub Actions self-hosted runners in our local Kubernetes environment. It would be nice if Portainer can be published in the internet so that GitHub cloud managed runners can directly interact with Portainer, but that is not ideal. In case you have to, we have a blog post on how to secure Portainer.

For GitHub Actions self-hosted runners to run, there is an awesome GitHub project called actions-runner-controller operator to host these as containers. The benefits are:

HorizontalRunnerAutoscaler)

For more details, refer to this.

In this blog post, it will use a GitHub Application for authentication, and provide self-hosted runners at an organization level. This way, the runners can be consumed by multiple repositories. Please walk-through the links thoroughly, and obtain the following:

Below are the steps to deploy our own container based self-hosted runner via Portainer:

  1. Browse to our Portainer instance ➝ Local EndpointNamespaces
  2. Create a Namespace called actions-runner-system. Resource limits will vary depend on your environment, so please use this as a guideline:

00 - GAC Namespace-png

  1. Navigate to ConfigMaps & Secrets to create a secret called controller-manager with the key/values as per the screenshot below in the actions-runner-system namespace:

01 - GAC Secret

  1. Note: For the github_app_private_key, use the Create Key/value from file option
  2. Add the actions-runner-controller Helm repository (https://actions-runner-controller.github.io/actions-runner-controller):

02 - GAC Helm Repo

  1. Deploy the Helm Chart. I have not modified the values file, but do so if required:

04 - GAC Controller check

  1. Check the status of the actions-runner-controller and ensure it is healthy:

Screenshot 2022-10-15 at 16.15.47

  1. Deploy self-hosted runners using the GitOps feature referencing to a Git repository. This way, I will be able to control runners' manifest via Git:
    ComponentValueNamespaceactions-runner-systemNameactions-runner-portainerBuild methodRepository (Use a git repository)Deployment typeKubernetesRepository URLhttps://github.com/portainer/examplesRepository Referencerefs/heads/mainManifest Path./gitops/github-actions-demo/01-github-actions-runner/runner.yamlAutomatic UpdatesEnabledMechanismPollingForce RedeploymentEnabled

Screenshot 2022-10-16 at 10.55.36Screenshot 2022-10-16 at 10.55.50

  1. Check the status of the portainer-runner, and ensure it is healthy:

06 - GAC RunnerScreenshot 2022-10-15 at 16.18.25

  1. The runner will also appear in the Runners tab in GitHub:

Screenshot 2022-10-15 at 16.23.41

Now, the self-hosted runners in the Kubernetes cluster is setup.

GitHub Actions Workflow

The second part is to execute a sample GitHub Actions workflow:

  1. Generate an access key as per the doc and create a GitHub Actions secret called PORTAINER_API_KEY. Also, interacting with a private repository, make sure a GitHub PAT is added. In this example, I have called it GIT_PAT:

08 - GitHub Actions Secrets

  1. We are all set to go. Now, navigate to ActionsPortainer GitHub Actions DemoRun workflow:

Screenshot 2022-10-16 at 11.00.56

  1. Note: portainer.portainer:9443 is specified for the Portainer URL. This is possible as our self-hosted runner runs inside the Kubernetes cluster, hence it has access to the Portainer service object
  2. Check the workflow run:

10 - GitHub Actions Reseults

  1. Navigate to the Applications page in Portainer, there will be an application called portainer-demo:

11 - Application deployed in Portainer

    There you go, the application has been provisioned based on the deployments.yaml file defined in the GitHub repository. From now on, this application can strictly be controlled by following the standard Git process.

Scale-out the number of Runners

Lastly, let's scale out the number of self-hosted runners to 10:

  1. Update the [Portainer] Deploy a Kubernetes application step to:
    - name: "[Portainer] Deploy a Kubernetes application"

shell: bash

run: |

echo "Executing the workflow with the id ${{ github.run_id }}"

sleep 300

  1. Execute the workflow 10 times, and you will see 10 portainer-runner pods popping up in the Applications tab in Portainer:

Screenshot 2022-10-15 at 17.50.34

  1. GitHub Actions tab:

Screenshot 2022-10-15 at 17.52.27

Based on your requirements, modify the HorizontalRunnerAutoscaler block to customize configurations such as minReplicas, maxReplicas, metrics, and so on.

Conclusion

As you can see, not only Portainer can be used to deploy applications via GUI, but it also provides APIs (The API specifications are published via Swagger) for the end users to interact with Portainer programatically.

Give Portainer a try today, experience simplified Kubernetes Operations today.

One platform, not twelve tools.

Govern Kubernetes across your whole fleet from a single control plane. Get 3 nodes free.

Get 3 nodes freeTalk to technical sales


Get 3 nodes free More from the blog