Kubernetes Ingress Traffic Flow, Visualized

A Kubernetes ingress diagram, hop by hop: DNS, load balancer, controller, Ingress rules, Service, EndpointSlices, Pods and TLS, with a free template.

10/16/2026

Kubernetes Ingress Traffic Flow, Visualized

Most architecture docs have one: a box labeled "Ingress" with an arrow pointing straight at a row of Pods. It looks fine until someone debugging a 502 asks where TLS ends, which proxy holds the connection, or why a NetworkPolicy blocks traffic that "goes through the Ingress". A good Kubernetes ingress diagram answers those questions before anyone has to ask. This post walks the request path hop by hop, maps a minimal Ingress manifest onto boxes and arrows, lists the mistakes that come up most in review, and shows how to build the same diagram in Archboard.

The request path, hop by hop

Follow https://shop.example.com/api/orders from the client down to a container:

  1. Client → DNS. The client resolves shop.example.com. The record (A/AAAA, CNAME or a provider alias) points at the cloud load balancer, not at a node.
  2. DNS → cloud load balancer. The client connects to the load balancer. In most clusters it exists because the ingress controller is exposed through a Service of type: LoadBalancer, and the cloud integration provisions it to forward to node ports or directly to the controller Pods.
  3. Load balancer → ingress controller. The controller is an ordinary workload (a Deployment or DaemonSet) running a reverse proxy such as NGINX, Envoy, HAProxy or Traefik. This is the component that accepts connections and proxies requests.
  4. Ingress rules (host/path). The controller watches Ingress objects of its class and turns them into proxy configuration. The Ingress object itself never touches a packet. It is configuration.
  5. Service (ClusterIP). Each rule points at a Service name and port. The Service gives a stable name and selects Pods by label.
  6. EndpointSlices. The control plane records the Pod IPs behind each Service, with a ready condition for each, in EndpointSlice objects. Many controllers, ingress-nginx included, read EndpointSlices and send traffic straight to Pod IPs instead of the ClusterIP. The Service still has to exist: it is how the controller finds those endpoints.
  7. Pods. The request lands on a container port in one of the ready Pods.

A note on ingress-nginx: the community ingress-nginx controller was retired in March 2026 and no longer gets releases, bug fixes or security patches. It is still the most familiar example; for a new cluster, pick a maintained controller or Gateway API.

TLS termination: pick a boundary and draw it

There are three common places for HTTPS to end:

Where TLS ends Who holds the certificate What to draw
Cloud load balancer The provider's certificate service Boundary ends at the LB; label LB → controller as HTTP or re-encrypted HTTPS
Ingress controller A Secret of type kubernetes.io/tls, referenced in spec.tls Secret attached to the Ingress; boundary ends at the controller
Pod (passthrough) The application Controller forwards raw TLS by SNI; boundary ends in the Pod. A controller-specific feature, not part of the Ingress spec

The Secret must live in the same namespace as the Ingress that references it. If you terminate at the load balancer and re-encrypt to the controller, draw two TLS segments, not one.

Host routing vs path routing

  • Host routing sends different hostnames to different backends (shop.example.com vs admin.example.com). Draw one group of edges per host.
  • Path routing splits one host by URL path. With pathType: Prefix, matching works on path elements split by /, so /api matches /api/orders but not /apiv2. Exact matches only that path; ImplementationSpecific is up to the controller.
  • When several paths match, the longest one wins. Most real Ingresses combine host and path rules.

Where NetworkPolicy applies

NetworkPolicy filters Pod traffic at L3/L4, and only when the cluster's network plugin enforces it. It knows nothing about hosts or paths and does not attach to the Ingress object. On the diagram, the hop it governs is controller Pods → application Pods. If the app namespace has a default-deny ingress policy, add one that allows traffic from the controller's namespace, for example with a namespaceSelector on kubernetes.io/metadata.name: ingress-nginx. The load balancer → controller hop is governed by cloud firewall rules plus any policy in the controller namespace.

Multiple ingress classes

Clusters often run more than one controller: public and internal, or old and new during a migration. Each controller claims an IngressClass, and each Ingress picks one with spec.ingressClassName. One class can be marked default with the annotation ingressclass.kubernetes.io/is-default-class: "true". Give each controller its own path from its own load balancer and label every Ingress with its class; otherwise readers assume one proxy handles everything.

Gateway API, briefly

Gateway API (gateway.networking.k8s.io) is the newer, role-oriented alternative: a GatewayClass describes the implementation, a Gateway defines listeners and TLS (usually owned by the platform team), and HTTPRoutes carry routing rules (usually owned by app teams). Its core HTTP routing has been GA since v1.0 in 2023. The Ingress API is still GA and supported, but frozen: it gets no new features. The diagram barely changes: the Gateway takes the place of the controller's listener, and HTTPRoutes take the place of Ingress rules.

A minimal Ingress, mapped to the Kubernetes ingress diagram

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: shop
  namespace: shop
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - shop.example.com
      secretName: shop-example-com-tls
  rules:
    - host: shop.example.com
      http:
        paths:
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: orders-api
                port:
                  number: 8080
          - path: /
            pathType: Prefix
            backend:
              service:
                name: storefront
                port:
                  number: 80
Field Box or arrow on the diagram
metadata.namespace: shop Namespace frame around the Ingress, Secret, Services and Deployments
spec.ingressClassName: nginx Which controller picks it up: a dashed "watches" edge from that controller to the Ingress
spec.tls[].hosts + secretName Secret node attached to the Ingress; TLS boundary ending at the controller
rules[].host The DNS record label and the entry edge from the load balancer
paths[0]: /api → orders-api:8080 Edge from controller to the orders-api Service, labeled /api
paths[1]: / → storefront:80 Edge from controller to the storefront Service, labeled /
backend.service.port.number Port label on each controller → Service edge

/api/orders matches both paths; /api is longer, so it goes to orders-api.

Common mistakes

  • Drawing the Ingress as the proxy. LB → Ingress → Pods reads as if the Ingress were a Pod. The controller is the proxy; the Ingress is configuration it reads. Put the controller in the data path and hang the Ingress off it with a dashed edge.
  • Omitting the Service. Ingress backends reference Services, not Pods. Even when traffic goes straight to Pod IPs, the Service selector is what breaks when labels drift, so keep it on the diagram.
  • No TLS boundary. If the diagram does not show where HTTPS ends, nobody can tell whether traffic inside the VPC is plaintext.
  • A floating NetworkPolicy. A policy with no edge to the hop it governs explains nothing.

Building it in Archboard

Archboard's Kubernetes pack has first-class nodes with ports for the objects above, including IngressClass, Gateway and Route, and the Network pack covers DNS and the load balancer. The finished version is the diagram below, and Open in Archboard copies it into your workspace; /examples/kubernetes-ingress-flow is a smaller Ingress → Service → Pods sketch. To build it yourself:

  1. Create a diagram and place a client (a Core Box or Icon, or a C4 Person), then a DNS node and a load balancer node from the Network pack.
  2. Add a Namespace frame named ingress-nginx with a Deployment and a Pod for the controller. The load balancer edge goes to this Pod, because it is the proxy.
  3. Add a second Namespace frame named shop. Inside it, place the Ingress, a Secret (shop-example-com-tls) and two Service nodes, orders-api and storefront, each connected to a Deployment and a Pod.
  4. Connect ports along the data path: client → DNS → load balancer → controller Pod → each Service (label the edges /api and /) → Pods. Label the Service → Pod edges "EndpointSlices" so readers can see how traffic reaches the Pods.
  5. Connect the controller to the Ingress with a dashed "watches" edge, and the Secret to the Ingress.
  6. Add a NetworkPolicy node in the shop frame and connect it to the controller → application hop it allows.
  7. Mark the TLS boundary with a Core Frame or Box around the encrypted segment, labeled with where it terminates.
  8. Paste the Ingress YAML into a Markdown block on the canvas, next to the boxes it describes.
Kubernetes Ingress diagram: clients resolve DNS and connect through a cloud load balancer to the ingress-nginx controller, which routes /api and / to the api and web Services and their Pods; a NetworkPolicy allows traffic from the controller.

14 components · 10 connections

Open in Archboard
Diagram contents
  • Kubernetes cluster
  • ingress-nginx
  • shop
  • Clients
  • DNS · shop.example.com
  • Cloud load balancer
  • ingress-nginx-controller
  • shop-example-com-tls
  • orders-api
  • storefront
  • allow-from-ingress
  • DNS lookup
  • HTTPS :443
  • TCP :443
  • /api
  • /
  • EndpointSlices
  • allows ingress-nginx → :8080
  • watches
  • TLS certificate
Ingress traffic end to end: DNS, cloud load balancer, the ingress-nginx controller with its routing rules and TLS secret, Services, EndpointSlices and Pods.

The Free plan allows 15 diagram nodes per diagram, plus 150 notes and text. The full build above uses 18, so drop the three Deployment nodes, the controller's included, and connect Services directly to Pods; the traffic path stays intact. Export as SVG or PNG (watermarked on Free), or as structured JSON to keep next to your manifests. For the wider cluster view, see /examples/kubernetes-microservices and Archboard for Kubernetes. The upstream reference is the Kubernetes Ingress documentation.

FAQ

Should the Ingress sit inside the application namespace? Yes. Ingress is namespaced and can only reference Services and TLS Secrets in its own namespace. The controller usually runs in a namespace of its own.

Does traffic pass through the Service's ClusterIP? It depends on the controller. Many proxy directly to Pod IPs from EndpointSlices. Draw the Service anyway and label the edge.

Ingress or Gateway API for a new cluster? If your controller supports it, Gateway API: the Ingress API is frozen. The diagram method is the same.

Start free — one seat, no credit card

Related posts

← Back to blog

Open a canvas in a minute

Sign in with Google or GitHub. Free for a single seat. Upgrade when the team joins.