fix: replace registry Ingress+Buffering with IngressRoute for streaming

The Buffering middleware was causing 413 on large Docker layer pushes
by spooling entire request bodies to disk before forwarding. Docker's
chunked blob upload protocol (PATCH/PUT with Content-Range) requires
streaming, not buffering.

Replace with IngressRoute CRDs + Certificate resources for direct
streaming passthrough. responseForwarding.flushInterval=100ms ensures
prompt chunk delivery to the registry backend.
This commit is contained in:
Will Anderson
2026-03-26 11:13:25 -05:00
parent 206873e83b
commit d163a92ec6
+52 -54
View File
@@ -1,71 +1,69 @@
--- ---
# Middleware: allow unlimited body size for Docker image layer uploads # Certificate for Docker registry (cert-manager — required for IngressRoute)
apiVersion: traefik.io/v1alpha1 apiVersion: cert-manager.io/v1
kind: Middleware kind: Certificate
metadata: metadata:
name: registry-chunked name: registry-tls
namespace: registry namespace: registry
spec: spec:
buffering: secretName: registry-tls
maxRequestBodyBytes: 0 issuerRef:
maxResponseBodyBytes: 0 name: letsencrypt-prod
memRequestBodyBytes: 0 kind: ClusterIssuer
retryExpression: "" dnsNames:
- registry.neuralplatform.ai
--- ---
# Docker registry ingress with chunked upload middleware # Docker registry — IngressRoute with no buffering middleware.
apiVersion: networking.k8s.io/v1 # Traefik streams blob data directly to the registry backend.
kind: Ingress # The Buffering middleware was causing 413s on large layer pushes by
# spooling the entire body to disk before forwarding.
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata: metadata:
name: registry name: registry
namespace: registry namespace: registry
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
cert-manager.io/cluster-issuer: letsencrypt-prod
traefik.ingress.kubernetes.io/router.middlewares: registry-chunked@kubernetescrd
nginx.ingress.kubernetes.io/proxy-body-size: "0"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
spec: spec:
ingressClassName: traefik entryPoints:
- websecure
routes:
- match: Host(`registry.neuralplatform.ai`)
kind: Rule
services:
- name: registry
port: 5000
responseForwarding:
flushInterval: "100ms"
tls: tls:
- hosts: secretName: registry-tls
- registry.neuralplatform.ai ---
secretName: registry-tls # Certificate for Docker registry UI
rules: apiVersion: cert-manager.io/v1
- host: registry.neuralplatform.ai kind: Certificate
http: metadata:
paths: name: docker-ui-tls
- path: / namespace: registry
pathType: Prefix spec:
backend: secretName: docker-ui-tls
service: issuerRef:
name: registry name: letsencrypt-prod
port: kind: ClusterIssuer
number: 5000 dnsNames:
- docker.neuralplatform.ai
--- ---
# Docker registry UI # Docker registry UI
apiVersion: networking.k8s.io/v1 apiVersion: traefik.io/v1alpha1
kind: Ingress kind: IngressRoute
metadata: metadata:
name: registry-ui name: registry-ui
namespace: registry namespace: registry
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
cert-manager.io/cluster-issuer: letsencrypt-prod
spec: spec:
ingressClassName: traefik entryPoints:
- websecure
routes:
- match: Host(`docker.neuralplatform.ai`)
kind: Rule
services:
- name: registry-ui
port: 80
tls: tls:
- hosts: secretName: docker-ui-tls
- docker.neuralplatform.ai
secretName: docker-ui-tls
rules:
- host: docker.neuralplatform.ai
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: registry-ui
port:
number: 80