Back

Kubernetes

Kubernetes Ingress Cleanup: Remove Routes With No Traffic

Kubernetes ingress cleanup starts when a hostname looks abandoned but nobody is sure whether it is safe to remove. The route may have no visible traffic, point at a service that was replaced months ago, or still exist only because an environment was cloned and never fully retired. It can also be the path for a low-volume customer, a payment callback, a health probe, a partner allowlist, or an emergency-only admin workflow.

The goal is not to delete every quiet route. The goal is to prove which Ingress objects, host rules, TLS secrets, DNS records, and backend services still have a current reason to exist. A good cleanup review leaves a small decision record: what hostnames were checked, which backends they route to, what traffic evidence was used, who approved the change, and what to watch after the reversible step.

This note is for platform engineers, SREs, and application owners who need to reduce stale Kubernetes routes without turning “no traffic” into the first real test of whether a route mattered.

Key Takeaways

  • Review Ingress cleanup at the hostname and path level, not just the object level.
  • Compare controller traffic, DNS records, TLS certificates, backend services, and Git manifests before removing a route.
  • Treat webhooks, partner callbacks, customer-specific hostnames, and incident-only admin paths as quiet-by-design until proven otherwise.
  • Use a reversible first move such as redirecting, removing DNS from a low-risk environment, or disabling a preview route before deleting manifests.
  • Prevent recurrence by requiring expiry metadata and route ownership during environment creation.

Build a Route Inventory

Start with the route users can hit: scheme, hostname, path, ingress class, namespace, service, and port. Kubernetes object names are often misleading because one Ingress can carry several host rules, and one hostname can be split across multiple path rules.

Inventory fieldWhy it matters for ingress cleanup
HostnameDNS, certificates, customer docs, and bookmarks depend on this string
Path ruleA quiet /admin or /webhook path can matter even if / is obsolete
Ingress classDifferent controllers may write metrics and load balancer state differently
Backend service and portThe route may be stale while the service is still used internally
TLS secretCertificate renewal or secret ownership can reveal a still-active owner
Source manifestCleanup should remove the declared route, not only the live object
External dependencyDNS records, partner allowlists, OAuth callbacks, and webhook settings can outlive app traffic

Keep the first pass small. Pick one cluster or one namespace family, export the routes, and group candidates by owner. A route without an owner is not automatically removable, but it is automatically a cleanup candidate because nobody can explain its current purpose.

Evidence That a Route Is Actually Unused

Ingress cleanup needs evidence from both Kubernetes and the edge. The cluster can tell you that a route exists and which service it points to. The ingress controller, load balancer, CDN, DNS provider, and application logs usually tell you whether anyone still reaches it.

Evidence checkStrong cleanup signalFalse positive to watch
Controller request metricsNo requests for the host and path across a full business cycleMetrics labels changed after a controller upgrade
Access logsNo 2xx, 3xx, 4xx, or webhook-style requests for the hostnameLogs are sampled, disabled, or retained for too short a window
DNS recordsHostname no longer resolves or points at an old ingress addressInternal DNS or partner DNS still points to the route
Backend service endpointsService has no endpoints or only obsolete deploymentsService is intentionally scaled to zero outside job windows
Git historyRoute was removed from app docs or replaced by a newer hostnameA rollback branch or release train still references the old host
TLS certificate usageCertificate is expired, unmanaged, or shared only by stale hostsWildcard certificates hide route-specific use

Do not let one signal carry the decision. “No requests” is useful, but it is weak if the route is a monthly report callback. “No endpoints” is useful, but it is weak if the route intentionally wakes a service through a controller, queue, or manual runbook.

Read-Only Kubectl Checks

Use kubectl to map the live route to its backend before you ask an owner to approve cleanup. The commands below are read-only and are meant to create a review list, not a deletion pipeline.

kubectl get ingress --all-namespaces -o wide
kubectl describe ingress -n $NAMESPACE $INGRESS_NAME
kubectl get service -n $NAMESPACE $SERVICE_NAME -o wide
kubectl get endpointslice -n $NAMESPACE -l kubernetes.io/service-name=$SERVICE_NAME
kubectl get secret -n $NAMESPACE $TLS_SECRET -o jsonpath='{.type}{"\n"}'

The output proves which host rules exist, which services receive traffic, whether endpoint slices currently back the service, and what TLS secret type is attached. It does not prove that traffic is absent. Pair it with ingress controller metrics, access logs, DNS checks, and owner confirmation.

If your cluster still relies on classic Endpoints rather than EndpointSlice for a specific workflow, check that object too. The important part is to prove the backend path, not to depend on one resource kind forever.

Hostnames That Need Extra Patience

Some routes are supposed to be quiet. Slow down when the hostname or path looks like any of these:

  • Webhook callbacks from payment processors, identity providers, Git hosting, CI systems, or marketplace integrations.
  • Customer-specific hostnames that only receive traffic during onboarding, audits, renewals, or support incidents.
  • Admin, break-glass, or migration paths that are intentionally absent from normal user journeys.
  • Preview and review-app routes referenced from old pull requests, QA scripts, or external bug reports.
  • Blue-green, canary, or rollback routes that are dormant until a release goes wrong.

The reversible step for these routes is usually not deletion. It may be owner repair, adding route metadata, shortening DNS TTL, documenting a replacement URL, or moving the route behind an explicit approval gate.

Choose the First Reversible Move

Ingress cleanup has several levels. Pick the smallest move that tests the cleanup decision without making recovery depend on memory.

Cleanup moveWhen to use itWhat to watch
Add owner and expiry annotationsThe route may be real, but accountability is missingOwner response and expiry review date
Mark the route deprecated in docsUsers may still discover the old hostnameSupport tickets, redirects, and search traffic
Remove DNS for non-production hostnamesThe app route is clearly obsolete and easy to restoreNXDOMAIN reports, CI failures, QA complaints
Redirect to the replacement routeHuman users may still follow old linksRedirect volume and status codes
Remove one path ruleOnly part of the host appears stale404s, webhook retries, and application errors
Delete the Ingress manifestHost, path, backend, DNS, and owners all agreeController events, load balancer changes, and synthetic checks

Write the rollback before the final removal. For Git-managed clusters, that is usually a revert of the manifest change plus any DNS or certificate restoration steps. For imperative legacy changes, capture the current object YAML before editing so the team knows what state existed at approval time.

Common Ingress Cleanup Mistakes

The easiest mistake is deleting the Kubernetes object while leaving DNS, certificates, or external callbacks behind. That turns a clear route into a confusing failure mode: users still resolve a hostname, but the cluster no longer has a rule for it.

Another mistake is treating all 404s as proof that a route is unused. A webhook endpoint may return 404 for unauthenticated probes and 200 only for signed provider calls. A partner callback may use a path that does not appear in browser traffic. A health checker may hit a route from an internal network that is absent from public logs.

A third mistake is removing an old route without updating the creation workflow that produced it. Preview environments, demo namespaces, and temporary customer migrations should require expiry metadata at creation time. Otherwise every cleanup pass becomes a manual archaeology project.

Prevention Rules for New Routes

Prevention should change how routes are created. Adding an owner label after the fact helps the next review, but it does not stop stale hostnames from appearing.

Require these fields in the Ingress creation path:

Required fieldExampleWhy it prevents stale ingress
Ownerplatform.example.com/owner: checkoutGives cleanup reviewers a team to ask
Route purposeplatform.example.com/purpose: partner-webhookSeparates rare-but-real traffic from clutter
Expiryplatform.example.com/expires: 2026-06-30Forces temporary routes back into review
Replacement URLplatform.example.com/replaced-by: https://app.example.comMakes redirects and docs updates easier
Source ticketplatform.example.com/request: ENG-1234Preserves why the route was created

For temporary environments, make the route expire with the environment rather than asking cleanup reviewers to rediscover the lifecycle later. For production routes, require a service catalog entry, alert owner, and documented rollback path before the route is accepted.

Decision Record

Use a compact record for each removed hostname or high-risk path.

FieldExample entry
Candidateold-api.example.com /v1/webhook in payments-prod
Why it looked staleNo controller requests in 60 days and replacement route exists
Evidence checkedIngress rule, backend service, endpoint slices, DNS, TLS secret, controller metrics, provider callback settings
Owner decisionPayments approved redirect for 14 days before manifest deletion
First moveRedirect old host to replacement route and watch callback retries
Watch signalProvider retry dashboard, ingress 4xx/5xx by host, support tickets
Final actionRemove DNS and Ingress manifest after review window
Prevention ruleTemporary partner routes require expiry and callback owner

This format is short enough to live in a pull request, but detailed enough for the next engineer to understand why the route disappeared.

FAQ

How long should we watch an Ingress route before deleting it?

Use a window long enough to include release cycles, customer schedules, batch callbacks, and incident workflows. Thirty days may be enough for a preview route. Production webhooks, partner routes, and customer-specific hostnames often need a longer window or explicit confirmation from the external system owner.

Is zero traffic enough to remove an Ingress?

No. Zero visible traffic is a candidate signal, not a removal decision. Confirm DNS, controller metrics, access logs, backend services, external callbacks, TLS ownership, and source manifests before deletion.

Should stale routes be redirected or deleted?

Redirect human-facing routes when users may still have bookmarks, docs, or search results. Delete routes when the hostname and path have no current consumer, no replacement journey is needed, and the rollback path is clear. Webhooks usually need provider-side updates rather than simple redirects.

What should the cleanup pull request include?

Include the hostname, path rules, backend service, evidence window, owner approval, DNS or certificate changes, rollback steps, and watch signals. Link to the broader cleanup library when the route cleanup is part of a larger Kubernetes or infrastructure review.