Github-Registry Docker Kubernetes Integration

Microservices, Kubernetes and Docker are all the rage or somewhat Standard right now. But when you're starting out with all of these things it can be a little overwhelming as you don't know where to start. So follow me along to bring you private Container to your existing Kubernetes Cluster.

We'll follow these 3 steps. Setting up the GitHub-Action, configuring the environment and creating the Kubernetes deployment


Building continuously

We'll be setting up a GitHub-Action to create a Container on every push to the main-branch. And thus safe some time. Creating something like this has become so hassle free with the GitHub Actions, that there's really now point in not doing it.

Prerequisites for this step:

  1. Your Code is already hosted on GitHub
  2. You enabled the GitHub Feature Preview for: "Improved container support"
  3. You already have a Dockerfile for you current project

Assuming you're already using GitHub for Source control it's pretty easy to elevate your project to an CI Level. We'll create a file called privateRegistry.yaml in this folder. With the following contents:

# <project-dir>/.github/workflows/privateRegistry.yaml
name: Private Registy Container 

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Set up QEMU
      uses: docker/setup-qemu-action@v1
    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v1
    - name: Login to GitHub Container Registry
      uses: docker/login-action@v1
      with:
        registry: ghcr.io
        username: ${{ github.repository_owner }}
        password: ${{ secrets.GITHUB_TOKEN }}
    - name: Push to GitHub Packages
      id: docker_build
      uses: docker/build-push-action@v2
      with:
        context: .
        push: true
        tags: ghcr.io/<user>/<project>:latest
        file: <path-to-Dockerfile>

Important notes here:

  • The setup steps of docker are needed for the Login to work.
  • ghcr.io tag prefix is needed so the Action knows, it should be pushing to the GitHub registry instead of the Docker Registry

With this setup you can push to the main branch and the Action will do its magic.

To check if everything worked fine we can try pulling the image with docker pull.

So we'll login to GitHub with Docker. For this you need a Personal Access Token as a password with the Right read:packages enabled. This will be used as your password in docker. To finally login type docker login ghcr.io to the commandline, put your github-username and as password use the Access Token.
Now we pull the image by running docker pull ghcr.io/<user>/<project>:latest.
Works fine? congratulations you pushed your image to the GitHub Container Registry! 🥳

Using the Image with Kubernetes

I'm now assuming you have at least a minikube up and running. If not subscribe to this blog as i'm planning to write a Kubernetes TLDR in the near future.
We'll be following the relevant parts of this Documentation.
From the previous steps your docker client is already logged at ghcr.io.

So running cat ~/.docker/config.json will probably yield something like this:

{
    "auths": {
        "ghcr.io": {
            "auth": "c3R...zE2"
        }
    }
}

If auths.\['ghcr.io'\].auth is empty your machine is probably using a different keystore. We need to use the config.json as auth storage for this tutorial so delete the key credsStore from the config and run docker login ghcr.io again, after this we have the needed credentials for Kubernetes.
Now we need to copy the credetials to our Node.
We do this by running

kubectl create secret generic regcred \
    --from-file=.dockerconfigjson=<path/to/.docker/config.json> \
    --type=kubernetes.io/dockerconfigjson

This will add a secret called regred to you Kubernetes secrets.

The final step!
We now want to test if our image will be pulled by docker. As I won't go to much in the details you just have to remember the following when creating a pod

apiVersion: v1
kind: Pod
metadata:
  name: private-reg
spec:
  containers:
  - name: private-reg-container
    image: ghcr.io/<user>/<project>:latest
  imagePullSecrets:
  - name: regcred

For containers.image use the image name which worked with docker pull, the login information for it is provided by imagePullSecrets.

You're done you have your Container from the GitHub Registry in your Kubernetes Cluster.