[{"data":1,"prerenderedAt":544},["ShallowReactive",2],{"blog-en-k3s-traefik-servicelb-ingress-nginx-port-conflict":3,"blog-related-en-k3s-traefik-servicelb-ingress-nginx-port-conflict":488,"blog-en-k3s-traefik-servicelb-ingress-nginx-port-conflict-alt":476},{"id":4,"title":5,"author":6,"body":7,"date":471,"description":472,"extension":473,"image":17,"locale":474,"meta":475,"navigation":476,"path":477,"seo":478,"stem":479,"tags":480,"__hash__":487},"blog\u002Fblog\u002Fen\u002Fk3s-traefik-servicelb-ingress-nginx-port-conflict.md","You Disabled Traefik on K3s, But ingress-nginx Still Can't Grab Port 443. Meet ServiceLB, the Roommate You Forgot About","Kubo Team",{"type":8,"value":9,"toc":462},"minimark",[10,18,21,26,38,61,70,76,80,91,106,125,152,158,162,165,204,216,230,236,243,247,250,260,294,309,318,356,361,370,378,384,400,404,410,449,458],[11,12,13],"p",{},[14,15],"img",{"alt":16,"src":17},"title","https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fen\u002Fk3s-traefik-servicelb-ingress-nginx-port-conflict\u002Ftitle.webp",[11,19,20],{},"You ran the flag to disable Traefik on K3s, installed ingress-nginx instead, and port 443 still won't respond. If that sounds familiar, Traefik isn't the culprit — it's another default component K3s quietly runs in the background.",[22,23,25],"h2",{"id":24},"_1-you-disabled-traefik-but-ingress-nginx-still-cant-grab-port-443","1. You disabled Traefik, but ingress-nginx still can't grab port 443",[11,27,28,29,33,34,37],{},"You ran ",[30,31,32],"code",{},"--disable=traefik",", confirmed with ",[30,35,36],{},"kubectl get pods -n kube-system"," that the Traefik-related pods were gone, and then installed ingress-nginx as a LoadBalancer service. An external IP gets assigned, but requests to port 443 time out — or worse, land on the wrong pod entirely.",[11,39,40,41,48,49,54,55,60],{},"This isn't as rare as it sounds. According to the official K3s documentation, K3s automatically deploys two independent networking components at startup (",[42,43,47],"a",{"href":44,"rel":45},"https:\u002F\u002Fdocs.k3s.io\u002Fnetworking\u002Fnetworking-services",[46],"nofollow","K3s official docs: Networking Services","). The first is Traefik (the Ingress Controller), which has been K3s's default Ingress Controller for years (",[42,50,53],{"href":51,"rel":52},"https:\u002F\u002Ftraefik.io\u002Fblog\u002Feasy-ingress-management-on-the-edge-with-k3s-lightweight-kubernetes-and-traefik-9d51c4ecacce",[46],"Traefik Labs official blog: Easy Ingress Management on the Edge with K3s and Traefik","). The second is ServiceLB (formerly known as Klipper LoadBalancer). Both NGINX and Traefik want ports 80\u002F443, so if either one is still running, a conflict is guaranteed (",[42,56,59],{"href":57,"rel":58},"https:\u002F\u002Fgithub.com\u002Fk3s-io\u002Fk3s\u002Fissues\u002F2403",[46],"k3s-io\u002Fk3s Issue #2403"," documents a case where nginx stopped responding on port 80 for IPv4 right after installing k3s).",[11,62,63,64,69],{},"This kind of \"invisible default dependency\" is something every K3s cluster admin runs into sooner or later. In an environment where cluster configuration is actually visible, like ",[42,65,68],{"href":66,"rel":67},"https:\u002F\u002Fkubo.hexabase.io\u002F",[46],"Kubo",", you'd catch this kind of oversight much earlier.",[11,71,72],{},[14,73],{"alt":74,"src":75},"section01","https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fen\u002Fk3s-traefik-servicelb-ingress-nginx-port-conflict\u002Fsection01.webp",[22,77,79],{"id":78},"_2-traefik-isnt-the-culprit-k3s-was-quietly-running-servicelb-the-whole-time","2. Traefik isn't the culprit. K3s was quietly running \"ServiceLB\" the whole time",[11,81,82,83,87,88,90],{},"What most engineers miss is that Traefik and ServiceLB are ",[84,85,86],"strong",{},"independent components managed by separate flags",". ",[30,89,32],{}," only stops Traefik. ServiceLB keeps running unless you disable it explicitly.",[11,92,93,94,97,98,101,102,105],{},"ServiceLB runs as a DaemonSet, placing pods prefixed with ",[30,95,96],{},"svclb-"," on nodes across the cluster, and assigns ports to LoadBalancer services using hostPort (",[42,99,47],{"href":44,"rel":100},[46],"). In other words, even after Traefik's LoadBalancer service disappears, ServiceLB keeps trying to assign ports to ",[84,103,104],{},"any other LoadBalancer service, including ingress-nginx",", using the exact same mechanism. That's the direct cause of port 443 staying unreachable after disabling Traefik.",[11,107,108,109,112,113,118,119,124],{},"What ServiceLB actually does is explained by the K3s developers themselves in an official repository discussion. ServiceLB's job is simply to set up DNAT iptables rules on the node — the DaemonSet pods themselves don't handle traffic. Without ServiceLB, any ",[30,110,111],{},"type: LoadBalancer"," Service would stay pending forever; that's the entire reason it exists (",[42,114,117],{"href":115,"rel":116},"https:\u002F\u002Fgithub.com\u002Fk3s-io\u002Fk3s\u002Fdiscussions\u002F9927",[46],"k3s-io\u002Fk3s Discussion #9927: What does ServiceLB (Klipper LB) actually do?","). Mechanically, it assigns one hostPort per service and forwards traffic to the cluster IP via iptables (",[42,120,123],{"href":121,"rel":122},"https:\u002F\u002Fgithub.com\u002Fk3s-io\u002Fklipper-lb",[46],"k3s-io\u002Fklipper-lb",").",[11,126,127,128,131,132,137,138,141,142,147,148,151],{},"As for why Traefik ships bundled with K3s in the first place, a K3s maintainer explains the reasoning directly in an official discussion: the design goal is to provide \"a fully functional cluster out of the box, a step beyond vanilla Kubernetes,\" and disabling it via the ",[30,129,130],{},"--disable traefik"," flag is explicitly supported (",[42,133,136],{"href":134,"rel":135},"https:\u002F\u002Fgithub.com\u002Fk3s-io\u002Fk3s\u002Fdiscussions\u002F6215",[46],"k3s-io\u002Fk3s Discussion #6215: Consider dropping Traefik as a bundled component","). In practice, though, there are reports of Traefik pods restarting even after ",[30,139,140],{},"--no-deploy traefik"," was specified (",[42,143,146],{"href":144,"rel":145},"https:\u002F\u002Fgithub.com\u002Fk3s-io\u002Fk3s\u002Fissues\u002F1160",[46],"Issue #1160",") — often traced back to directly editing ",[30,149,150],{},"\u002Fvar\u002Flib\u002Francher\u002Fk3s\u002Fserver\u002Fmanifests\u002Ftraefik.yaml",", which K3s's startup process simply regenerates on restart.",[11,153,154],{},[14,155],{"alt":156,"src":157},"section02","https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fen\u002Fk3s-traefik-servicelb-ingress-nginx-port-conflict\u002Fsection02.webp",[22,159,161],{"id":160},"_3-confirm-the-invisible-roommate-with-one-diagnostic-command","3. Confirm the \"invisible roommate\" with one diagnostic command",[11,163,164],{},"You can check whether ServiceLB is still running with a single command:",[166,167,172],"pre",{"className":168,"code":169,"language":170,"meta":171,"style":171},"language-bash shiki shiki-themes tokyo-night","kubectl get pods -A | grep svclb\n","bash","",[30,173,174],{"__ignoreMap":171},[175,176,179,183,187,190,194,198,201],"span",{"class":177,"line":178},"line",1,[175,180,182],{"class":181},"sE3pS","kubectl",[175,184,186],{"class":185},"sPY7s"," get",[175,188,189],{"class":185}," pods",[175,191,193],{"class":192},"sT800"," -A",[175,195,197],{"class":196},"sAklC"," |",[175,199,200],{"class":181}," grep",[175,202,203],{"class":185}," svclb\n",[11,205,206,207,209,210,215],{},"If any pod with the ",[30,208,96],{}," prefix shows up, ServiceLB is still active. As the official Kubernetes documentation explains, Ingress Controllers aren't built into Kubernetes core at all — every cluster is expected to run its own controller as a separate component (",[42,211,214],{"href":212,"rel":213},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fconcepts\u002Fservices-networking\u002Fingress-controllers\u002F",[46],"Kubernetes official docs: Ingress Controllers","). K3s bundling Traefik by default is convenient, but it's also the root cause of the \"install an alternative Ingress Controller and immediately hit a port conflict\" problem — and simply stopping Traefik isn't always enough.",[11,217,218,219,222,223,226,227,124],{},"You also shouldn't edit manifests under ",[30,220,221],{},"\u002Fvar\u002Flib\u002Francher\u002Fk3s\u002Fserver\u002Fmanifests\u002F"," directly. K3s's startup process detects the diff and reverts it back to the original state. If you need to customize behavior, the correct approach is to place an additional ",[30,224,225],{},"HelmChartConfig"," resource in the same directory, as the official docs explain (",[42,228,47],{"href":44,"rel":229},[46],[11,231,232],{},[14,233],{"alt":234,"src":235},"section03","https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fen\u002Fk3s-traefik-servicelb-ingress-nginx-port-conflict\u002Fsection03.webp",[11,237,238,239,242],{},"This is exactly the kind of area where a visualized management console eliminates the need for CLI checks altogether. ",[42,240,68],{"href":66,"rel":241},[46],"'s Captain UI visualizes your cluster's Ingress\u002FLoadBalancer configuration, reducing the risk of shipping to production without noticing a \"default component that's still running.\"",[22,244,246],{"id":245},"_4-the-correct-way-to-disable-both-and-what-changes-with-metallb","4. The correct way to disable both, and what changes with MetalLB",[11,248,249],{},"If you want to disable both Traefik and ServiceLB on an existing cluster, follow these steps.",[251,252,253],"ol",{},[254,255,256,257],"li",{},"On every server node, add the following to ",[30,258,259],{},"\u002Fetc\u002Francher\u002Fk3s\u002Fconfig.yaml",[166,261,265],{"className":262,"code":263,"language":264,"meta":171,"style":171},"language-yaml shiki shiki-themes tokyo-night","disable:\n  - traefik\n  - servicelb\n","yaml",[30,266,267,276,286],{"__ignoreMap":171},[175,268,269,273],{"class":177,"line":178},[175,270,272],{"class":271},"s0U2E","disable",[175,274,275],{"class":196},":\n",[175,277,279,283],{"class":177,"line":278},2,[175,280,282],{"class":281},"sgJMe","  -",[175,284,285],{"class":185}," traefik\n",[175,287,289,291],{"class":177,"line":288},3,[175,290,282],{"class":281},[175,292,293],{"class":185}," servicelb\n",[251,295,296,302],{"start":278},[254,297,298,299],{},"Restart K3s with ",[30,300,301],{},"sudo systemctl restart k3s",[254,303,304,305,308],{},"Re-run ",[30,306,307],{},"kubectl get pods -A | grep svclb"," and confirm there's no output",[11,310,311,312,317],{},"For a fresh install, just specify both flags at install time (",[42,313,316],{"href":314,"rel":315},"https:\u002F\u002Foneuptime.com\u002Fblog\u002Fpost\u002F2026-02-20-metallb-k3s-servicelb-conflicts\u002Fview",[46],"oneuptime.com's MetalLB setup guide","):",[166,319,321],{"className":168,"code":320,"language":170,"meta":171,"style":171},"curl -sfL https:\u002F\u002Fget.k3s.io | INSTALL_K3S_EXEC=\"--disable servicelb --disable traefik\" sh -\n",[30,322,323],{"__ignoreMap":171},[175,324,325,328,331,334,336,339,342,345,348,350,353],{"class":177,"line":178},[175,326,327],{"class":181},"curl",[175,329,330],{"class":192}," -sfL",[175,332,333],{"class":185}," https:\u002F\u002Fget.k3s.io",[175,335,197],{"class":196},[175,337,338],{"class":181}," INSTALL_K3S_EXEC",[175,340,341],{"class":196},"=",[175,343,344],{"class":196},"\"",[175,346,347],{"class":185},"--disable servicelb --disable traefik",[175,349,344],{"class":196},[175,351,352],{"class":181}," sh",[175,354,355],{"class":185}," -\n",[357,358,360],"h3",{"id":359},"the-same-problem-happens-with-metallb-too","The same problem happens with MetalLB, too",[11,362,363,364,369],{},"ServiceLB doesn't just conflict with ingress-nginx — it conflicts with MetalLB as well. Both watch for LoadBalancer services and both try to assign external IPs, which leads to services getting stuck pending or receiving the wrong IP entirely — an \"unpredictable behavior\" pattern (",[42,365,368],{"href":366,"rel":367},"https:\u002F\u002Fgithub.com\u002Fk3s-io\u002Fk3s\u002Fissues\u002F2323",[46],"k3s-io\u002Fk3s Issue #2323"," describes a case where BGP routes kept flapping in MetalLB even after the user believed ServiceLB was disabled).",[11,371,372,373,377],{},"klipper-lb (ServiceLB) and MetalLB are built on fundamentally different design philosophies. ServiceLB is a lightweight mechanism that runs entirely on node-local iptables rules and never advertises IPs to the outside network. MetalLB, on the other hand, supports both L2 (ARP) and BGP modes and can genuinely advertise IPs to the external network, which is why it's the better fit for production bare-metal clusters (",[42,374,376],{"href":115,"rel":375},[46],"k3s-io\u002Fk3s Discussion #9927","). If you're running MetalLB in production, disabling ServiceLB isn't optional — it's a prerequisite you can't skip.",[11,379,380],{},[14,381],{"alt":382,"src":383},"section04","https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fen\u002Fk3s-traefik-servicelb-ingress-nginx-port-conflict\u002Fsection04.webp",[11,385,386,387,390,391,393,394,399],{},"With a managed K8s built on K3s like ",[42,388,68],{"href":66,"rel":389},[46],", AI-Driven Deployment detects this kind of Ingress\u002FLoadBalancer configuration drift, which reduces the risk of a missed ",[30,392,272],{}," flag causing a production incident you never saw coming. If you need the same kind of configuration management on-premises, ",[42,395,398],{"href":396,"rel":397},"https:\u002F\u002Fwww.hexabase.com\u002Fproduct\u002Fkubo\u002Fon-premise",[46],"Kubo On-Premise"," offers a management console built on the same philosophy.",[22,401,403],{"id":402},"_5-summary","5. Summary",[11,405,406,407,409],{},"Disabling Traefik on K3s doesn't end with running ",[30,408,32],{},". K3s bundles two independent components by default — Traefik (Ingress) and ServiceLB (LoadBalancer, formerly Klipper) — and each one needs to be disabled with its own separate flag.",[411,412,413,419,425,433,443],"ul",{},[254,414,415,418],{},[84,416,417],{},"Symptom",": Traefik is disabled, but ingress-nginx still can't grab port 443",[254,420,421,424],{},[84,422,423],{},"Cause",": ServiceLB keeps assigning hostPorts to other LoadBalancer services",[254,426,427,430,431],{},[84,428,429],{},"Diagnosis",": ",[30,432,307],{},[254,434,435,438,439,442],{},[84,436,437],{},"Fix",": add ",[30,440,441],{},"disable: [traefik, servicelb]"," to config.yaml and restart",[254,444,445,448],{},[84,446,447],{},"Also applies to",": MetalLB, where disabling ServiceLB is a prerequisite, not an option",[11,450,451,452,457],{},"Don't let \"it's just the default\" slide past you — knowing exactly which two networking components K3s bundles, and independently verifying both, should be the last checkpoint before anything goes to production. If you'd rather hand that visualization off entirely, ",[42,453,456],{"href":454,"rel":455},"https:\u002F\u002Fwww.hexabase.com\u002Fcontact-us\u002F",[46],"get in touch"," with the Kubo team.",[459,460,461],"style",{},"html pre.shiki code .sE3pS, html code.shiki .sE3pS{--shiki-default:#C0CAF5}html pre.shiki code .sPY7s, html code.shiki .sPY7s{--shiki-default:#9ECE6A}html pre.shiki code .sT800, html code.shiki .sT800{--shiki-default:#E0AF68}html pre.shiki code .sAklC, html code.shiki .sAklC{--shiki-default:#89DDFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .s0U2E, html code.shiki .s0U2E{--shiki-default:#F7768E}html pre.shiki code .sgJMe, html code.shiki .sgJMe{--shiki-default:#9ABDF5}",{"title":171,"searchDepth":278,"depth":278,"links":463},[464,465,466,467,470],{"id":24,"depth":278,"text":25},{"id":78,"depth":278,"text":79},{"id":160,"depth":278,"text":161},{"id":245,"depth":278,"text":246,"children":468},[469],{"id":359,"depth":288,"text":360},{"id":402,"depth":278,"text":403},"2026-09-19","You ran the K3s disable-traefik flag but ingress-nginx still can't bind port 443. The culprit is ServiceLB (klipper-lb), another default K3s component. Here's how to diagnose it, disable it correctly, and what changes if you're running MetalLB.","md","en",{},true,"\u002Fblog\u002Fen\u002Fk3s-traefik-servicelb-ingress-nginx-port-conflict",{"title":5,"description":472},"blog\u002Fen\u002Fk3s-traefik-servicelb-ingress-nginx-port-conflict",[481,482,483,484,485,486],"k3s","kubernetes","traefik","servicelb","ingress-nginx","load-balancer","Opw1MYa8KzAoF5mKp3QB_yjmgBVIcK5WtkuF4tVM240",[489,498,507,516,525,534],{"path":490,"title":491,"description":492,"date":493,"tags":494},"\u002Fblog\u002Fen\u002Fk3s-pod-security-admission-restricted-servicelb-outage","We Enabled Restricted and ServiceLB Died: The K3s Pod Security Admission Gap No Generic Guide Mentions","Enabling the restricted Pod Security Admission profile on K3s following standard Kubernetes guides can silently kill ServiceLB. Here's why, backed by K3s's own CIS hardening guide, and how to roll it out safely.","2026-10-16",[481,482,495,496,484,497],"pod-security-admission","pod-security-standards","security",{"path":499,"title":500,"description":501,"date":502,"tags":503},"\u002Fblog\u002Fen\u002Fk3s-ingress-gateway-api-migration-traefik-gap","Ingress Is Ending. We Migrated to Gateway API, and K3s's Traefik Only Got Us Halfway","Migrating to Gateway API on K3s sounds simple since Traefik ships by default, but it still requires installing CRDs, rebuilding canary configs, and re-checking cert-manager wiring. A practical guide grounded in the 2026 Ingress-nginx retirement and Kubernetes 1.36.","2026-10-10",[481,482,504,483,505,506],"gateway-api","ingress","networking",{"path":508,"title":509,"description":510,"date":511,"tags":512},"\u002Fblog\u002Fen\u002Fk3s-cert-manager-servicelb-http01-challenge-renewal-failure","K3s Wouldn't Renew Its cert-manager Certificate. ServiceLB Was Stealing the HTTP-01 Challenge","cert-manager certificates on K3s stopped renewing, and neither Traefik nor cert-manager itself was the cause — ServiceLB was occupying ports 80\u002F443. Here's how the HTTP-01 challenge silently fails, and how to fix it for good.","2026-09-25",[481,482,513,484,514,515],"cert-manager","tls","lets-encrypt",{"path":517,"title":518,"description":519,"date":520,"tags":521},"\u002Fblog\u002Fen\u002Fk3s-networkpolicy-dual-stack-kube-router-ipv6-gap","\"K3s Ignores NetworkPolicy\" Was a Myth. Traffic Still Leaked Through — the ServiceLB Blind Spot","K3s enforces NetworkPolicy by default via its built-in kube-router controller. Yet traffic via LoadBalancer still leaked through — the cause was ServiceLB's implementation combined with a permanent limitation of the NetworkPolicy API. Here's how to detect and fix it.","2026-09-24",[481,482,522,484,523,524],"networkpolicy","kube-router","network-security",{"path":526,"title":527,"description":528,"date":529,"tags":530},"\u002Fblog\u002Fen\u002Fk3s-baremetal-loadbalancer-bgp-metallb-cilium","Bare-Metal K3s LoadBalancer: When ARP Hits Its Limit, Design for BGP","When you can't rely on a cloud load balancer for on-prem or edge K3s clusters, why does Layer2 (ARP) load balancing eventually hit a wall? A practical look at MetalLB's BGP mode vs. Cilium's BGP Control Plane, and how to decide when to migrate.","2026-08-26",[481,482,531,532,486,533],"metallb","bgp","edge-computing",{"path":535,"title":536,"description":537,"date":538,"tags":539},"\u002Fblog\u002Fen\u002Fk3s-hpa-containerresource-sidecar-utilization-dilution","HPA Was Scaling on the Sidecar's Share Too. The ContainerResource Blind Spot in Kubernetes","Kubernetes HPA sums resource usage across every container in a Pod, so Istio sidecars and logging agents dilute the scaling decision. Here's how the ContainerResource metric fixes it, in a K3s\u002FKubo context.","2026-10-21",[481,482,540,541,542,543],"hpa","containerresource","autoscaling","service-mesh",1792592640341]