Ingress NGINX Controller on RKE2: Retirement and the Traefik Default
On this page

RKE2 used to ship the Ingress NGINX Controller as its built-in ingress. That project is now retired, and RKE2 v1.36 deploys Traefik by default on new clusters. This page covers the current known good design for ingress on RKE2 and how to move existing clusters off ingress-nginx.
Status of Ingress NGINX
- Upstream: Kubernetes SIG Network and the Security Response Committee announced on November 11, 2025 that Ingress NGINX would be retired in March 2026. After that there are no further releases, bug fixes, or security patches, and the repositories become read-only (announcement). The Steering and Security Response Committees repeated the warning on January 29, 2026 (statement). They recommend migrating to Gateway API or another Ingress controller.
- RKE2: According to the RKE2 networking services docs:
- Starting with v1.36, Traefik is the default ingress controller for new clusters.
- v1.36 still ships ingress-nginx as deprecated. You must opt in with
ingress-controller: ingress-nginx. - In v1.37, ingress-nginx is removed and unavailable for new clusters.
- The RKE2 docs note that SUSE Rancher Prime LTS customers get extended Ingress NGINX support through December 2027 (migration guide). Everyone else should migrate.
Choosing the Ingress Controller
RKE2 selects its packaged ingress controller with the ingress-controller key in /etc/rancher/rke2/config.yaml on every server node:
# traefik (default for new clusters on v1.36+), ingress-nginx (deprecated), or none
ingress-controller: traefikSet none if you deploy your own controller or rely only on Gateway API through another implementation.
To see what an existing cluster runs:
kubectl get ingressclass
kubectl -n kube-system get daemonset | grep -E 'traefik|ingress-nginx'How RKE2 Deploys Traefik
RKE2 manages Traefik as the rke2-traefik HelmChart in kube-system, upgraded together with RKE2 itself. The RKE2 packaging of the upstream Traefik chart changes several defaults (see the rke2-traefik chart patch):
| Setting | Upstream Traefik chart | RKE2 rke2-traefik |
|---|---|---|
| Workload kind | Deployment | DaemonSet |
| Host ports | none | 80 and 443 on every node |
| Service type | LoadBalancer | ClusterIP |
| IngressClass | default class, unnamed | traefik, not marked default |
Because Traefik binds host ports 80 and 443 on every node, you can put any layer 4 load balancer (hardware, cloud, kube-vip, or DNS round robin) in front of the nodes on those ports. Ports 80 and 443 on the nodes are then not available for other HostPort or NodePort services.
Set ingressClassName: traefik explicitly on your Ingress objects so they do not depend on a cluster default class.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example
namespace: default
spec:
ingressClassName: traefik
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: example
port:
number: 80Customizing Traefik on RKE2
Do not edit the HelmChart object directly; RKE2 overwrites it. Use a HelmChartConfig named rke2-traefik in kube-system, either applied with kubectl or dropped into /var/lib/rancher/rke2/server/manifests/ on a server node:
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
name: rke2-traefik
namespace: kube-system
spec:
valuesContent: |-
logs:
general:
level: INFO
ports:
websecure:
transport:
respondingTimeouts:
readTimeout: 600sThe valuesContent keys are values of the upstream Traefik Helm chart. RKE2’s own example in the networking docs sets the log level the same way.
Gateway API
The RKE2 docs state that Gateway API on RKE2 requires Traefik. Enable Traefik’s Gateway provider in the same HelmChartConfig:
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
name: rke2-traefik
namespace: kube-system
spec:
valuesContent: |-
providers:
kubernetesGateway:
enabled: trueThe RKE2 docs list Traefik v3.7.x with Gateway API v1.5. From v1.37, the Gateway API CRDs ship in a standalone chart instead of with Traefik. Before the April 2026 RKE2 releases, disabling Traefik after enabling it removed the Gateway API CRDs (and every Gateway and HTTPRoute with them), so do not toggle Traefik off on clusters that use Gateway API.
After enabling, check the class name before writing Gateways:
kubectl get gatewayclassMigrating an Existing ingress-nginx Cluster
Upgrading an existing cluster does not by itself move your Ingress objects. Follow the RKE2 ingress migration guide; in short:
- Set
ingressClassName: nginxexplicitly on every existing Ingress. - On each server, set
ingress-controllerto both controllers (ingress-nginxandtraefik) and add arke2-traefikHelmChartConfig that moves Traefik to ports 8000 and 8443 and enables Traefik’s Ingress NGINX compatibility provider (kubernetesIngressNGINX). - Restart
rke2-serveron the control plane nodes and confirm both therke2-ingress-nginx-controllerandrke2-traefikDaemonSets are running. - Create copies of your Ingresses with the migration IngressClass
rke2-ingress-nginx-migrationand test them through ports 8000 and 8443. Load balancer health checks differ:/healthzfor NGINX,/pingfor Traefik. - Set
ingress-controllerto onlytraefik, remove the temporary ports from the HelmChartConfig, and restart. - Delete the old
nginxIngress objects.
Traefik’s compatibility provider does not support every NGINX annotation. Check the Traefik Ingress NGINX provider docs for your annotations, especially configuration-snippet and other snippet annotations, before migrating. The RKE2 guide notes the provider name in the HelmChartConfig changed from kubernetesIngressNginx to kubernetesIngressNGINX in the June 2026 RKE2 releases.
Rancher-provisioned downstream RKE2 clusters have their own migration guide in the Rancher documentation, linked from the RKE2 for Rancher page.

The diagram above shows the legacy ingress-nginx layout. Traefik on RKE2 follows the same pattern: one controller pod per node, bound to host ports 80 and 443, with an external layer 4 load balancer in front of the nodes.