An Ingress lets you route external HTTP/HTTPS traffic to multiple services within your cluster using host-based or path-based rules — similar in concept to an Nginx reverse proxy, but managed declaratively within Kubernetes itself.
Why Use Ingress Instead of Multiple NodePort Services
NodePort services each need a distinct port, which becomes unwieldy with many services. Ingress lets you route based on domain name or URL path through a single entry point, much closer to how you'd typically want to expose a real production application.
Step 1 — Install the Nginx Ingress Controller
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/baremetal/deploy.yaml
The "baremetal" provider variant is appropriate for a self-managed VPS cluster, as opposed to cloud-specific variants that expect a cloud load balancer.
Step 2 — Verify the Ingress Controller Is Running
kubectl get pods -n ingress-nginx
Step 3 — Find the Ingress Controller's Exposed Port
kubectl get svc -n ingress-nginx
On a bare-metal/VPS setup, this typically exposes via NodePort — note the ports shown for HTTP (80) and HTTPS (443).
Step 4 — Create an Ingress Resource
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app-service
port:
number: 80
kubectl apply -f ingress.yaml
Step 5 — Point DNS to Your Node's IP
Add an A record for myapp.example.com pointing to your VPS's public IP — see How to Point a Domain to Your VPS (A/AAAA Records).
Step 6 — Route the Firewall to the Ingress Ports
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
If the Ingress controller uses non-standard NodePort values instead of 80/443 directly, forward those specific ports, or configure the service to use hostNetwork for direct binding (more advanced).
Adding TLS/HTTPS to an Ingress
spec:
tls:
- hosts:
- myapp.example.com
secretName: myapp-tls
rules:
- host: myapp.example.com
...
The referenced secretName must contain a valid TLS certificate and key, stored as a Kubernetes Secret — commonly automated with cert-manager for Let's Encrypt integration.
Routing Multiple Services by Path
rules:
- host: myapp.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80
Common Errors
404 from the Ingress controller itself (not your app) — verify the host field exactly matches the domain you're testing with, and that ingressClassName is correctly set.
Ingress applied but traffic doesn't reach the service — verify the backend service name and port in the Ingress spec exactly match an existing Service.
FAQ
Can one Ingress controller handle multiple domains?
Yes — define multiple host rules within one or more Ingress resources; a single controller can route for many different domains simultaneously.
Continue Reading
- Kubernetes Pods, Deployments & Services Explained
- How to Deploy a Stateless Web App to Kubernetes (Step-by-Step)
- How to Point a Domain to Your VPS (A/AAAA Records)
Browse more articles in Kubernetes & Container Orchestration.