3 min read

Urunner - a Kubernetes open source project

URunner is a Kubernetes utility in order to auto restart pods on image digest change even if the tag remain the same.
Urunner - a Kubernetes open source project

GitHub --> https://github.com/texano00/urunner
Artifacthub --> https://artifacthub.io/packages/helm/urunner/urunner
Repository --> https://github.com/texano00/urunner/pkgs/container/urunner / https://github.com/texano00/urunner/pkgs/container/urunner%2Fhelm%2Furunner
Logo generated by AI --> https://www.fotor.com/features/ai-image-generator/

URunner is an Open Source Kubernetes utility in order to auto restart pods on image digest change even if the tag remain the same.
In many environments (usually dev/test), it is widely used the latest tag which frequently changes over time. In these cases, Urunner can help to detect tag digest change on external container registry and restarts deployment(s) on digest change detection.

Urunner integrates external container registries (ex. Harbor, AWS ECR, Azure ACR) using standard Docker API V2 so all container registres that support Docker API V2 are supported by Urunner too.

Urunner is also fully configurable in order to watch only specific namespaces and specific tags (ex. latest, dev) based on regex.

Of course Urunner is Helm ready (visit Artifact Hub for latest version and configuration).

Artifact Hub
helm upgrade --install urunner oci://ghcr.io/texano00/urunner/helm/urunner --version 0.1.0 --values my-values.yaml -n urunner --create-namespace

Urunner Flow

GitHub Actions

CI/CD actions are already in place for both Python App and Helm Chart.

OCI artifacts are stored on github repo ghcr.io:

  • Container Image Pyhthon App ghcr.io/texano00/urunner:0.1.2
  • Helm Chart ghcr.io/texano00/urunner/helm/urunner:0.1.2

CI/CD Python App

Notes

  • trigger this pipeline only on branch main and on edit files under app/  folder
  • GHCR_USERNAME and GHCR_PASSWORD must be stored using GitHub Secrets

Steps

  1. Checkout repository
  2. Setup python 3.x
    Here I'm also using Action Cache in order to speedup dependencies installation, read more here --> https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows
  3. Install pip dependencies
  4. Lint with pylint
  5. Retrieve Python app version
  6. Build and push container image
    Here I also guaranteed the tag immutability. So if you try to build&push a version that already exists, action will fail.


Code

name: "[CI/CD] App"

on:
  push:
    branches: ['main']
    paths:
    - 'app/**'

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: texano00/urunner

jobs:
  build-and-push-image:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    defaults:
      run:
        working-directory: app
    environment: production

    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.x'
          cache: 'pip'

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt
      - name: Lint
        run: |
          pylint $(git ls-files '*.py') --fail-under=10
      - name: Get version
        id: metadata
        run: |
            version=$(cat .version)
            echo "version=${version}" >> $GITHUB_OUTPUT
              
      - name: docker build and push
        id: build_and_push
        run: |
          built_image="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.metadata.outputs.version }}"
          docker login ${{ env.REGISTRY }} -u ${{ secrets.GHCR_USERNAME }} -p ${{ secrets.GHCR_PASSWORD }}
          if docker manifest inspect ${built_image} > /dev/null; then
            echo "already exist -> do not push"
            exit 1
          else
            echo "does not exist -> push"
            docker build . -t ${built_image}
            docker push ${built_image}  
          fi

CI/CD Helm Chart

Notes

  • This github action is triggered on any changes under helm/ folder and only on branch main
  • GHCR_USERNAME and GHCR_PASSWORD must be stored using GitHub Secrets
  • Helm chart is stored using standard OCI on ghcr.io

Steps

  • Checkout repository
  • Helm lint
  • Helm package and push on ghcr.io using OCI standard

Code

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

# GitHub recommends pinning actions to a commit SHA.
# To get a newer version, you will need to update the SHA.
# You can also reference a tag or branch, but the action may change without warning.

name: "[CI/CD] Helm"

on:
  push:
    branches: ['main']
    paths:
    - 'helm/**'
env:
  REGISTRY: ghcr.io
  OCI_CHART_NAME: texano00/urunner/helm

jobs:
  build-and-push-image:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    defaults:
      run:
        working-directory: helm/urunner
    environment: production

    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Helm lint
        run: |
          helm lint

      - name: Helm lint
        run: |
          helm lint

      - name: Helm pack and push
        run: |
          helm package .
          helm registry login ${{ env.REGISTRY }} -u ${{ secrets.GHCR_USERNAME }} -p ${{ secrets.GHCR_PASSWORD }}
          helm push *.tgz oci://${{ env.REGISTRY }}/${{ env.OCI_CHART_NAME }}
          
Tweets by YBacciarini