After years of managing Kubernetes clusters in enterprise environments, I identified a recurring problem: Docker registry management. Between bandwidth limitations, public registry quotas, and enterprise security policies, it quickly became a nightmare. That's why I developed Mutating Registry Webhook.
In a modern Kubernetes environment, each deployment can reference dozens of Docker images from various sources: Docker Hub, Google Container Registry, Quay.io, GitHub Container Registry... This diversity poses several problems:
Classic approaches are laborious and fragile:
I created Mutating Registry Webhook to completely automate this process. It's a Kubernetes admission webhook that intercepts Pod creation and modification to automatically rewrite image URLs according to your rules.
The system relies on four key components:
Imagine you want to redirect all Docker Hub images to your internal registry. You simply create this rule:
apiVersion: dev.flemzord.fr/v1alpha1
kind: RegistryRewriteRule
metadata:
name: docker-hub-to-ecr
spec:
rules:
# Redirect Docker Hub images to ECR pull-through cache
- match: '^docker\.io/(.*)'
replace: 'internal-registry.company.com/dockerhub/$1'
# Handle images without explicit registry (defaults to docker.io)
- match: '^([^/]+/[^/]+)$'
replace: 'internal-registry.company.com/dockerhub/$1'
Now, any image like docker.io/nginx:latest will be automatically rewritten as internal-registry.company.com/docker-hub/nginx:latest. Your developers continue using original URLs, the webhook handles the rest.
The rule system is designed to be extremely flexible:
Advanced example with multiple registries:
apiVersion: dev.flemzord.fr/v1alpha1
kind: RegistryRewriteRule
metadata:
name: multi-registry-routing
spec:
rules:
- match: '^(gcr\\.io|quay\\.io|ghcr\\.io)/(.*)$'
replace: 'cache.internal.com/$1/$2'
One critical aspect was performance. The webhook must process every Pod created in the cluster without introducing noticeable latency:
Security is ensured through native cert-manager integration. TLS certificates are automatically managed and renewed, guaranteeing secure communications between Kubernetes and the webhook.
Installation is simple and fast:
# Install cert-manager (if not already present)
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml
# Install Mutating Registry Webhook
kubectl apply -f https://raw.githubusercontent.com/flemzord/mutating-registry-webhook/main/dist/install.yaml
Drastically reduce your bandwidth by redirecting all external images to your internal cache:
apiVersion: dev.flemzord.fr/v1alpha1
kind: RegistryRewriteRule
metadata:
name: enterprise-cache
spec:
rules:
- match: '^(?!internal-registry\\.)(.*)$'
replace: 'internal-registry.company.com/cache/$1'
Progressively migrate from one registry to another without touching code:
apiVersion: dev.flemzord.fr/v1alpha1
kind: RegistryRewriteRule
metadata:
name: gradual-migration
spec:
rules:
- match: '^old-registry\\.company\\.com/(.*)$'
replace: 'new-registry.company.com/$1'
conditions:
namespaces: ['canary', 'staging']
Create completely isolated environments with their own registries:
apiVersion: dev.flemzord.fr/v1alpha1
kind: RegistryRewriteRule
metadata:
name: isolated-dev
spec:
rules:
- match: '^(.*)$'
replace: 'dev-registry.local/$1'
The webhook exposes Prometheus metrics for complete monitoring:
These metrics allow tracking usage and quickly identifying any issues.
Mutating Registry Webhook transforms a complex problem into a simple and elegant solution. No more manually modifying image references in Helm charts, Kustomize manifests, or Operators, maintaining fragile scripts, or training developers to use specific URLs.
The project is open source and actively maintained. I welcome contributions, suggestions, and experience feedback. If you manage Kubernetes clusters in enterprise and are tired of juggling registries, try Mutating Registry Webhook.
Find the project on GitHub: github.com/flemzord/mutating-registry-webhook