Image Mirroring

When a cluster is deployed on your cloud account, a dedicated image registry is created to serve as a mirroring system.

This mirroring registry is also available within the Qovery interface

Mirroring Registry

How does it work

Every time an application needs to be deployed on your cluster, the application image is mirrored on the mirroring registry.

Application built via the Qovery pipeline

Images within the mirroring registry are organized by "Qovery service", each service has its own repository (or namespace, naming depends on the cloud provider). This means that each service build and mirroring process is completely isolated from the others.

Before building the application A1, Qovery checks within mirroring registry at the repository of the application A1 if an image has already being built with the same version (commit id and environment variables).

If the image already exists, the built is skipped and Qovery starts the deployment of that image on the Kubernetes cluster.

Otherwise, the image is built by the Qovery pipeline the resulting image is pushed on the mirroring registry at the repository of the application A1, deleting any previous image.

Mirroring built image

In order to speed up the image build, we are using remote caches (available in AWS, GCP and Scaleway). It will avoid building the image from scratch, only the layers that changed will be built.

Given this isolation mechanism, if the same application is cloned (via the clone or preview environment feature), Qovery will re-build the application since the environment variables have changed (the ones at environment level).

Application deployed from a container registry

The Qovery behaviour in this case will depend on the chosen mirroring mode within the cluster advanced settings.

Two mirroring modes are available when deploying a service from a container registry:

Service (Default)

Images within the mirroring registry are organized by "Qovery service", each service has its own repository (or namespace, naming depends on the cloud provider). This means that each service mirroring process is completely isolated from the others.

At the beginning of the deployment of the application A1, Qovery checks within mirroring registry at the repository of the application A1 if an image with the same image name and tag exists.

If the image already exists, the mirroring process is skipped and Qovery starts the deployment of that image on the Kubernetes cluster.

Otherwise, the image is pulled from the source registry and pushed on the mirroring registry at the repository of the application A1, deleting any previous image.

Mirroring image from registry - Service case

Pro:

  • Images are automatically deleted when not needede anymore

Cons:

  • If the same image is used across environments or service, Qovery will mirror multiple time the same image, reducing the deployment speed

Cluster

Images within the mirroring registry are organized by "Qovery cluster", meaning that the application deployed on the same cluster are all mirrored on the same repository.

At the beginning of the deployment of the application A1, Qovery checks within mirroring registry at the repository of the cluster C1 if an image with the same image name and tag exists.

If the image already exists, the mirroring process is skipped and Qovery starts the deployment of that image on the Kubernetes cluster.

Otherwise, the image is pulled from the source registry and pushed on the mirroring registry at the repository of the cluster C1.

Mirroring image from registry - Cluster case

Pro:

  • If the same image is used across environments or service, this setup will avoid to mirror multiple time the same image, increasing the deployment speed.

Cons:

  • Qovery can't automatically delete the images mirrored on the mirroring registry. This will increase the cloud provider cost of your image registry since it will store more data. To reduce the amount data stored you can reduce the image TTL via the cluster advanced settings registry.image_retention_time

Why image mirroring is necessary

Image mirroring is a general best practice: you don't want your system to be strictly coupled on a third party.

Let's say that you run an application on your production environment and Kubernetes needs to pull again the image to spawn a new instance for the application. In this case, you don't want to make this fail due to the unavailability of your source container registry. This is why we make sure that a copy is always available on the container registry next to the Kubernetes cluster.

Why unique image tags are necessary

When working with containerized applications, it is crucial to employ unique image tags for precise version management. This practice ensures complete confidence in the version running within a container. Failing to use unique image tags can lead to adverse consequences due to the image caching mechanisms employed by both the Qovery mirroring system and Kubernetes:

  • Mirroring Registry: Qovery’s mirroring system stores images in a registry. If an image tag remains the same between two versions, the new version will not be mirrored. Consequently, the new version will not be deployed, affecting the overall application.
  • Kubernetes: Applications deployed by Qovery on Kubernetes adhere to the “ifNotPresent” image pull policy. This policy means that if the image already exists on the Kubernetes node’s local disk, Kubernetes will not attempt to pull it again. However, if the image tag remains unchanged, the new image version will not be fetched, resulting in your pods running the outdated application code.

In summary, maintaining unique image tags is a critical aspect of effective version control and ensuring that your applications run the intended versions without disruptions caused by caching mechanisms.