5 min read

[k8s] Automatically pull images from GitLab container registry without change the tag

Sometimes is very useful in a continuous integration and deployment process to override and push the same image tag (ex. `latest`) to a gitlab registry and then ideally have the same new image up&running from Kubernetes cluster(s). URunner lighweight tool solves exactly this specific problem.
[k8s] Automatically pull images from GitLab container registry without change the tag


Having the same image tag (ex. latest , dev) is commonly used on environments that rapidly change and have to inherit the very new integration from development teams.

This is the case for example of an internal development environment where developers don't want to maintain a lot of different image tags nor to setup retention rules to automatically delete old tags.

Well, there's a lot of theory out there on this topic, of course each developer's group of every company have their specific needs and consequently their vertical solution.

One challenge of course may be the need to roll back to an image specific development version, using a single latest tag is not possible.

In this case, we need to rebuild/integrate the needed codebase in order to override the latest tag with the desired development version.

We probably can talk about it for weeks without any agreement since, as I said before, every development's team has its specific needs.

From my point of view, there's a point where the theory can't go on in favor of the real business scenarios and needs.


But anyway, assuming to have a CI/CD process that continuously produce and override a static tag like latest (replace it with the tag name you want).

From Kubernetes side, we will see how URunner (which is basically a lightweight k8s agent) is able to detect this change (thanks to official Docker API v2) through image tag digest.


GitHub - texano00/urunner: URunner is a lightweight Kubernetes utility in order to auto restart pods on image tag digest change. This is very useful on environments where it is commonly used the latest tag which frequently changes over time. Urunner auto detects the container image tag digest (for example the digest of tag latest) and automatically restart pods.
URunner is a lightweight Kubernetes utility in order to auto restart pods on image tag digest change. This is very useful on environments where it is commonly used the latest tag which frequently c…

I developed URunner some months ago, mainly to do some practices with:

  • Docker API V2
    On the "Docker API v2" topic I wrote something more in the following article.
    Ex. do you really know what's happening during a typical docker pull <image> command?
  • Kubernetes APIs
    In URunner I improved my confidence with Kubernetes API using the official Python sdk, so cool!

Against all odds, I discovered URunner to be running on many Kubernetes environments 🥳🤩

Going back to URunner, here how it works

Thanks to an internal sqlite DB, URunner is able to detect an image tag update (thanks to the digest info) and then restart the related pods.

That's all!

URunner installation

As described on artifacthub,

Firstly, retrieve your GitLab registry token (read only)

Authenticate with the container registry | GitLab
GitLab product documentation.

This is a screenshot from the token generator page on gitlab.com to facilitate you

Then define your values.yaml (replace secret.gitlab.token values with the one retrieved previously)

  repository: urunner
  pullPolicy: IfNotPresent
  tag: dev

  # se to false in order to disallow ssl verify to container registry
  # Text logging level for the message ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL').
  # incluster, kubeconfig allowed
  # path on which urunner store its sqllight database
  # urunner check frequency
  # container registry url
  # harbor, aws_ecr, digitalocean, gitlab
  create: true
  # for expected keys see secret.yaml
    token: XXXX

imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""

  # Specifies whether a service account should be created
  create: true
  # Annotations to add to the service account
  annotations: {}
  # The name of the service account to use.
  # If not set and create is true, a name is generated using the fullname template
  name: ""

podSecurityContext: {}
  # fsGroup: 2000

securityContext: {}
  # capabilities:
  #   drop:
  #   - ALL
  # readOnlyRootFilesystem: true
  # runAsNonRoot: true
  # runAsUser: 1000

resources: {}
  # We usually recommend not to specify default resources and to leave this as a conscious
  # choice for the user. This also increases chances charts run on environments with little
  # resources, such as Minikube. If you do want to specify resources, uncomment the following
  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
  # limits:
  #   cpu: 100m
  #   memory: 128Mi
  # requests:
  #   cpu: 100m
  #   memory: 128Mi

nodeSelector: {}

tolerations: []

affinity: {}

We're ready!

Let's install (replace the version with the latest one --> https://artifacthub.io/packages/helm/urunner/urunner)

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


  • URunner by default does not watch for any namespaces.
    You have to label the namespaces you want to be watched by URunner as follow
    kubectl label ns your-namespace urunner=enable
    For more details / usage see the doc
  • instead of putting the gitlab token on the values.yaml you can manually create the secret and use secret.create=false and secret.secretName=<your-secret-name>
    Refer to artifacthub for the secret template.
  • replace -n urunner on the helm upgrade .. command with the namespace you want.
    Here URunner will run one deployment resource.
  • to date URunner officially supports AWS ECR, Digital Ocean Registry, Harbor, GitLab
    but it theoretically supports all containers' registry since it is based on Docker v2 standard API without any vendor specific APIs.
    See Github README for latest updates.

You're setted up!

Starting from now, all pods on your-namespace that are using of course an image from registry.gitlab.com will be watched by URunner.

If any digest change on a latest tag version, for example, is detected, that a rollout restart will be performed by URunner.

See URunner logs for more info on how it's going on and enjoy URunner.

Tweets by YBacciarini