Skip to content

Ingress

Purpose

Route external HTTP(S) traffic to the frontend Service - the single entry point for every environment.

Architecture/context

K3s ships Traefik as its bundled default Ingress controller, running in kube-system. This chart's ingress.yaml creates exactly one Ingress object per release, routing / (everything) to the frontend Service - the frontend's own nginx then proxies /api/* internally to the backend Service (see frontend/nginx.conf). There is deliberately no second Ingress rule splitting /api off to the backend directly - keeping API routing/CORS/header behavior owned by one file (nginx.conf), consistently between Docker Compose and Kubernetes.

Files involved

helm/akshayabazaar/templates/ingress.yaml, helm/akshayabazaar/values.yaml (ingress.className, ingress.host, ingress.tls.*), each values-<env>.yaml overriding ingress.host.

Configuration

Value local staging production
ingress.host staging.akshaya.local staging.akshayathreadworld.in akshayathreadworld.in
ingress.className traefik traefik traefik
ingress.tls.enabled false true true

TLS, when enabled, either references a pre-existing secretName or a cert-manager.io/cluster- issuer annotation (added only when ingress.clusterIssuer is set) - if neither is configured, Traefik falls back to its own self-signed certificate (TLS terminates, but browsers warn).

Commands

kubectl get ingress -n staging
kubectl describe ingress -n staging akshaya-local

Validation / expected result

curl.exe -I http://staging.akshaya.local          # local, port 80
# HTTP/1.1 200 OK

Hostname-based multi-tenancy on one node

Staging and production share one K3s node/public IP (see Architecture → Infrastructure "Single-VM topology") - Traefik routes purely on the incoming Host header, so two Ingress objects in two namespaces (akshayabazaar-staging, akshayabazaar-production) coexist on the same node without conflict, as long as their host values differ (they always do).

Troubleshooting

  • Nothing responds on the expected host/port - check Traefik itself is running (kubectl get pods -n kube-system -l app.kubernetes.io/name=traefik), then check the local cluster's actual load-balancer port mapping (docker port k3d-akshaya-staging-serverlb) - see Kubernetes → Troubleshooting.
  • DNS/hosts resolution - see Local → First-time setup for the local staging.akshaya.local entry; real staging/production hostnames resolve via Cloudflare DNS - see Terraform → Cloudflare.

Rollback / recovery

Reverting ingress.host/TLS config is a normal helm upgrade/helm rollback - see Helm. Nothing here is stateful beyond the Ingress object itself.

Security considerations

  • The backend Service has no Ingress rule routing to it directly - confirmed by ingress.yaml's single rule and reinforced by NetworkPolicy (see Network Policy).
  • This K3s assumption (Traefik, in kube-system) must be verified before applying this chart to any cluster that isn't K3s's own default setup - a different ingress controller or namespace would make the frontend's own allow-ingress NetworkPolicy silently block all inbound traffic (default-deny fails closed). Verify with:
    kubectl get pods -n kube-system -l app.kubernetes.io/name=traefik