Aller au contenu
Conteneurs & Orchestration medium

kube-image-keeper : cache et haute disponibilité des images Kubernetes

15 min de lecture

logo kube-image-keeper

Ce guide vous montre comment installer kube-image-keeper (kuik) pour garantir l’accès à vos images conteneur même quand Docker Hub ou votre registry est indisponible. Vous apprendrez à configurer le routage d’images vers des miroirs et la réplication entre registries. Prérequis : un cluster Kubernetes fonctionnel et Helm installé.

  • Installer kuik et ses prérequis (cert-manager)
  • Comprendre l’architecture et les CRDs de kuik v2
  • Configurer le routage d’images avec ClusterImageSetMirror
  • Mettre en place la réplication avec ClusterReplicatedImageSet
  • Diagnostiquer les problèmes courants

kube-image-keeper (kuik, prononcé “quick”) est un système de routage et de mise en cache d’images conteneur pour Kubernetes, développé par Enix. Il résout un problème que tout administrateur Kubernetes a rencontré : l’impossibilité de démarrer des pods parce qu’une image ne peut pas être téléchargée.

Les causes sont multiples :

  • Registry indisponible : Docker Hub en maintenance, panne réseau
  • Rate limiting : quotas Docker Hub atteints (100 pulls/6h pour les anonymes)
  • Image supprimée : politique de rétention, suppression accidentelle
  • Réseau instable : clusters edge avec connexion intermittente

kuik intercepte les créations de pods via un mutating webhook et peut :

  1. Router les images vers un miroir local quand le registry source est indisponible
  2. Répliquer les images entre plusieurs registries pour créer une haute disponibilité virtuelle

kuik v2 s’articule autour de trois concepts :

Architecture de kube-image-keeper : webhook mutating, CRDs de routage et vérification de disponibilité

kuik v2 introduit quatre Custom Resource Definitions pour configurer le comportement du système. Les versions “Cluster” s’appliquent à tout le cluster, tandis que les versions sans préfixe sont limitées à un namespace spécifique.

CRDPortéeUsage
ClusterImageSetMirrorClusterDéfinit des miroirs pour router les images
ImageSetMirrorNamespaceIdem, mais limité à un namespace
ClusterReplicatedImageSetClusterConfigure la réplication entre registries
ReplicatedImageSetNamespaceIdem, mais limité à un namespace

La différence entre routage et réplication est importante :

  • Routage (ImageSetMirror) : redirige les pulls vers un miroir existant. Vous devez avoir configuré ce miroir au préalable (ex: Harbor en mode proxy-cache)
  • Réplication (ReplicatedImageSet) : kuik copie lui-même les images d’un registry vers un autre. Plus autonome, mais consomme plus de ressources

kuik utilise un mutating webhook qui intercepte les créations de pods. Ce webhook doit communiquer avec l’API server de façon sécurisée via TLS. Pour gérer automatiquement les certificats, kuik s’appuie sur cert-manager.

Si cert-manager n’est pas déjà installé sur votre cluster :

Fenêtre de terminal
# Installation de cert-manager
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.17.1/cert-manager.yaml
# Attendre que cert-manager soit prêt
kubectl -n cert-manager rollout status deployment cert-manager --timeout=120s
kubectl -n cert-manager rollout status deployment cert-manager-webhook --timeout=120s
  1. Créer le namespace

    Fenêtre de terminal
    kubectl create namespace kuik-system
  2. Installer kuik

    Fenêtre de terminal
    helm upgrade --install \
    --namespace kuik-system \
    kube-image-keeper \
    oci://quay.io/enix/charts/kube-image-keeper \
    --version 2.0.0 \
    --wait
  3. Vérifier l’installation

    Fenêtre de terminal
    kubectl -n kuik-system get pods

    Résultat attendu :

    NAME READY STATUS RESTARTS AGE
    kube-image-keeper-manager-5c5dff9d7b-w6xcg 1/1 Running 0 31s

Après l’installation, vérifiez que les Custom Resource Definitions ont été créées. Ces CRDs permettent de configurer kuik de façon déclarative :

Fenêtre de terminal
kubectl api-resources | grep kuik

Résultat :

clusterimagesetmirrors cism kuik.enix.io/v1alpha1 false ClusterImageSetMirror
clusterreplicatedimagesets cris kuik.enix.io/v1alpha1 false ClusterReplicatedImageSet
imagesetmirrors ism kuik.enix.io/v1alpha1 true ImageSetMirror
replicatedimagesets ris kuik.enix.io/v1alpha1 true ReplicatedImageSet

Les raccourcis (cism, cris, ism, ris) permettent d’interagir plus rapidement avec kubectl : kubectl get cism au lieu de kubectl get clusterimagesetmirrors.

Le routage est le cas d’usage le plus simple de kuik. Il permet de rediriger automatiquement les pulls d’images vers un miroir quand le registry source est indisponible ou lent.

Cas d’usage typiques :

  • Vous avez un Harbor configuré en proxy-cache de Docker Hub
  • Vous utilisez un registry interne qui synchronise les images critiques
  • Vous êtes sur un cluster edge avec un registry local

Supposons que vous avez un registry miroir Harbor à harbor.example.com:5000. Ce registry est configuré pour mettre en cache les images Docker Hub :

apiVersion: kuik.enix.io/v1alpha1
kind: ClusterImageSetMirror
metadata:
name: dockerhub-mirror
spec:
imageFilter:
include:
- "nginx:.*" # Toutes les versions de nginx
- "redis:[0-9]+\\..*" # redis avec version numérique
exclude:
- ".*:latest" # Exclure les tags latest
mirrors:
- registry: "harbor.example.com:5000"
path: "docker-hub-cache"
Fenêtre de terminal
kubectl apply -f dockerhub-mirror.yaml
# Vérifier
kubectl get clusterimagesetmirrors

Quand un pod est créé avec image: nginx:1.25 :

  1. Le webhook kuik intercepte la création
  2. Il vérifie si l’image correspond à un ClusterImageSetMirror
  3. Il teste la disponibilité du registry source (configurable via activeCheck)
  4. Si le source est indisponible et qu’un miroir est accessible, il réécrit l’image
  5. Sinon, il conserve l’image originale (mode failsafe)
Fenêtre de terminal
# Voir l'image finale dans le pod
kubectl get pod mon-pod -o jsonpath='{.spec.containers[0].image}'

La réplication va plus loin que le routage : kuik copie lui-même les images d’un registry source vers un registry de destination. Cela crée une vraie haute disponibilité sans dépendre d’un proxy-cache externe.

Différences avec le routage :

AspectRoutageRéplication
Infrastructure requiseMiroir existant (Harbor, etc.)Registry destination vide
Qui copie les images ?Le miroir externekuik lui-même
Consommation réseauÀ la demandeProactive (copie à l’avance)
Latence premier pullDépend du miroirQuasi-immédiate si déjà répliquée

Cette configuration demande à kuik de surveiller les images nginx, redis et postgres sur Docker Hub et de les répliquer automatiquement :

apiVersion: kuik.enix.io/v1alpha1
kind: ClusterReplicatedImageSet
metadata:
name: critical-images
spec:
upstreams:
- registry: "docker.io"
path: "library"
imageFilter:
include:
- "nginx:.*"
- "redis:.*"
- "postgres:.*"

Quand un pod utilisant nginx:1.25 est créé, kuik vérifie si l’image a déjà été répliquée. Si oui, il réécrit l’image pour pointer vers la copie locale.

Pour un registry privé nécessitant une authentification :

apiVersion: kuik.enix.io/v1alpha1
kind: ClusterReplicatedImageSet
metadata:
name: private-images
spec:
upstreams:
- registry: "ghcr.io"
path: "myorg"
credentialSecret:
name: ghcr-credentials
namespace: kuik-system
imageFilter:
include:
- "myapp:.*"

Créez d’abord le secret :

Fenêtre de terminal
kubectl -n kuik-system create secret docker-registry ghcr-credentials \
--docker-server=ghcr.io \
--docker-username=myuser \
--docker-password=ghp_xxxx

kuik offre plusieurs options pour adapter son comportement à votre environnement. Les principales personnalisations concernent la haute disponibilité du manager, le comportement du routage et la gestion du cycle de vie des images.

Créez un fichier de values pour personnaliser l’installation. Voici les options les plus utiles :

values-kuik.yaml
manager:
replicas: 2 # HA pour le manager
verbosity: DEBUG # Plus de logs
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"
configuration:
routing:
activeCheck:
enabled: true # Vérifier la disponibilité des registries
timeout: "2s" # Timeout de la vérification
unusedImageTTL: 48 # Heures avant suppression d'une image non utilisée
Fenêtre de terminal
helm upgrade --install \
--namespace kuik-system \
kube-image-keeper \
oci://quay.io/enix/charts/kube-image-keeper \
--version 2.0.0 \
-f values-kuik.yaml

Pour éviter que kuik n’intercepte certains namespaces système :

apiVersion: kuik.enix.io/v1alpha1
kind: ClusterImageSetMirror
metadata:
name: global-mirror
spec:
imageFilter:
include:
- ".*"
exclude:
- "quay.io/enix/kube-image-keeper:.*" # Éviter les boucles

kuik étant un composant critique (il intercepte toutes les créations de pods), il est important de savoir le surveiller et diagnostiquer les problèmes.

Le manager kuik produit des logs structurés qui permettent de comprendre son comportement. Suivez les logs en temps réel :

Fenêtre de terminal
kubectl -n kuik-system logs deployment/kube-image-keeper-manager -f

Les messages clés à surveiller :

  • defaulting for Pod : webhook interceptant une création de pod
  • no alternative image is available : pas de miroir disponible, image originale conservée
  • rerouting image : image réécrite vers un miroir
Fenêtre de terminal
# Détail d'un ClusterImageSetMirror
kubectl get clusterimagesetmirror dockerhub-mirror -o yaml
# Détail d'un ClusterReplicatedImageSet
kubectl get clusterreplicatedimageset critical-images -o yaml
Fenêtre de terminal
# Documentation intégrée
kubectl explain clusterimagesetmirror.spec
kubectl explain clusterimagesetmirror.spec.imageFilter
kubectl explain clusterreplicatedimageset.spec.upstreams

Les problèmes avec kuik se manifestent généralement de deux façons : les pods ne démarrent pas (images introuvables) ou le routage ne s’applique pas (images non réécrites). Voici les causes les plus fréquentes :

SymptômeCause probableSolution
Webhook non déclenchécert-manager non prêtVérifier kubectl -n cert-manager get pods
invalid nested repetition operatorRegex invalide (** au lieu de .*)Corriger la syntaxe regex
Image non réécriteMiroir inaccessibleVérifier la connectivité au registry miroir
no alternative image availableAucune règle ne matcheVérifier les filtres include/exclude
Pods kuik en CrashLoopCertificats invalidesRecréer le namespace kuik-system

Si kuik indique qu’aucun miroir n’est disponible, vérifiez que les pods peuvent réellement atteindre votre registry miroir. Cette commande crée un pod temporaire pour tester la connectivité :

Fenêtre de terminal
# Depuis un pod de debug
kubectl run test-registry --rm -it --image=curlimages/curl -- \
curl -s https://harbor.example.com:5000/v2/

Une réponse {} ou {"repositories":[]} indique que le registry est accessible. Une erreur de connexion ou un timeout signifie un problème réseau (firewall, DNS, etc.).

Pour désinstaller proprement :

Fenêtre de terminal
# Supprimer kuik
helm uninstall kube-image-keeper -n kuik-system
# Supprimer les CRDs (attention : supprime toutes les règles)
kubectl delete crd clusterimagesetmirrors.kuik.enix.io
kubectl delete crd clusterreplicatedimagesets.kuik.enix.io
kubectl delete crd imagesetmirrors.kuik.enix.io
kubectl delete crd replicatedimagesets.kuik.enix.io
# Supprimer le namespace
kubectl delete namespace kuik-system
  • kuik résout les problèmes de disponibilité des images (registry down, rate limits, images supprimées)
  • kuik v2 utilise deux CRDs principaux : ClusterImageSetMirror (routage) et ClusterReplicatedImageSet (réplication)
  • Les filtres utilisent des regex Go, pas des globs
  • kuik est failsafe : si aucun miroir n’est disponible, l’image originale est conservée
  • cert-manager est un prérequis obligatoire
  • Évitez d’inclure l’image kuik dans vos règles pour prévenir les boucles

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.