Migrating from ingress-nginx to traefik
As anybody using self hosted k8s knows the ingress-nginx Ingress got retired March 2026, and with the recent RCE found in nginx , it means by using ingress-nginx you are using vulnerable version that will receive no security updates.
What are the options
Replacing the ingress-nginx especially if you rely on it's specific annotation ( which made it so useful in the first place) can be quite a lot of work. Fortunately Traefik steeped in and started offering a compatible implementation that makes the migration (kind of) easy. They have a good page on how to check whether you can switch w/o issues , but unfortunately there is no good single source of how to configure it, besides snippets of configs, which when you are not familiar with traefik don't mean much, even with LLM.
Current setup
The cluster I am migrating this on , is a small few nodes cluster, with ingress-nginx running as a DaemonSet with hostNetwork, ingress-nginx installed with following helm values:
controller:
hostNetwork: true
allowSnippetAnnotations: true
config:
annotations-risk-level: Critical
ingressClassResource:
default: true
Traefik helm config
# values.yaml
ports:
# on my setup traefik port 8080 conflicts with k8s services so it had to be changed
traefik:
port: 9090
hostPort: 9090
# the api/dashboard should not be accessible directly to the world
hostIP: 127.0.0.1
expose:
default: false
# Defines the HTTP entry point named 'web'
web:
port: 80
hostPort: 80
# Instructs this entry point to redirect all traffic to the 'websecure' entry point
http:
redirections:
entryPoint:
to: websecure
scheme: https
permanent: true
allowACMEByPass: true # ←this is needed for cert manager
# Defines the HTTPS entry point named 'websecure'
websecure:
port: 443
hostPort: 443
metrics:
port: 9100
hostPort: 9100
exposedPort: 9100
# the metrics endpoint should not be accessible directly to the world
hostIP: 127.0.0.1
# Enables the dashboard in Secure Mode
api:
dashboard: true
insecure: false
ingressRoute:
# Expose dashboard under a subdomain, thi
dashboard:
enabled: true
matchRule: Host(`dashboard.my-domain.com`)
entryPoints:
- websecure
middlewares:
- name: dashboard-auth
namespace: ingress-nginx
tls:
secretName: traefik-dashboard-tls
# Creates a BasicAuth Middleware and Secret for the Dashboard Security
extraObjects:
- apiVersion: v1
kind: Secret
metadata:
name: dashboard-auth-secret
type: kubernetes.io/basic-auth
stringData:
username: root
password: "very-secret-password" # Replace with an Actual Password
- apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: dashboard-auth
spec:
basicAuth:
secret: dashboard-auth-secret
- apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: traefik-dashboard-tls
spec:
secretName: traefik-dashboard-tls
dnsNames:
- dashboard.my-domain.com
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
providers:
kubernetesIngress:
enabled: false # Traefik doc explicitly says it can cause problems
kubernetesIngressNGINX:
# -- Enable Kubernetes Ingress NGINX provider
enabled: true
allowSnippetAnnotations: true
ingressClassByName: true
ingressClass: "nginx"
deployment:
kind: DaemonSet
initContainers:
- name: set-unprivileged-port
image: busybox
command:
- sh
- -c
- sysctl -w net.ipv4.ip_unprivileged_port_start=80
securityContext:
privileged: true
allowPrivilegeEscalation: true
runAsUser: 0
runAsNonRoot: false
hostNetwork: true
# this allows access to the dashboard via kube port-forward
service:
enabled: true
spec:
type: ClusterIP # or disable entirely
# Needed for DaemonSet
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 0Migrate
- Uninstall ingress-nginx
- Install traefik with the values provided above values
helm repo add traefik https://traefik.github.io/charts
helm repo update
helm install traefik traefik/traefik -f values.yaml - You need to also manually create a nginx ingress class
# ingress-class.yaml
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: nginx
spec:
controller: k8s.io/ingress-nginx
kubectl apply -f ingress-class.yaml
- At this point, everything should work as it was with the ingress-nginx, including cert-manager.