Intro
Ingress exposes HTTP and HTTPS routes from outside the cluster to internal Services. This guide gives you the most useful kubectl Ingress commands, explains what each does, when to use it, and provides copy-ready examples. You will create and verify a minimal HTTP Ingress, add TLS, and troubleshoot safely without disrupting production.
What you will do:
- Confirm your Ingress controller and class
- Create a minimal HTTP Ingress
- Test routing locally using port-forward + curl
- Add TLS for HTTPS
- Troubleshoot with events and logs
Safety first:
- Work in a dedicated namespace
- Use dry-run and diff before apply
- Change one thing at a time and verify
Workflow Overview
- Verify prerequisites
- An Ingress controller is installed (example: NGINX Ingress).
- You have kubectl access to the cluster.
- Prepare a demo Service
- Create a minimal Ingress
- Verify with get/describe
- Test locally via port-forward and curl
- Add TLS and retest
- Troubleshoot with events/logs if needed
Basic commands you will use daily
General inspection:
- List all Ingresses in all namespaces:
kubectl get ingress -A
- List available Ingress classes:
kubectl get ingressclass
- Describe a specific Ingress to see rules, backends, and events:
kubectl describe ingress demo -n ingress-demo
Change management:
- Preview changes without applying them:
kubectl diff -f ingress.yaml
- Apply changes from a file:
kubectl apply -f ingress.yaml
- Annotate or label an Ingress (overwrite if it already exists):
kubectl annotate ingress demo nginx.ingress.kubernetes.io/rewrite-target=/ --overwrite -n ingress-demo
kubectl label ingress demo app=demo --overwrite -n ingress-demo
- Edit in place (use sparingly):
kubectl edit ingress demo -n ingress-demo
- Patch with a small, targeted change:
kubectl patch ingress demo -n ingress-demo \
--type merge -p '{"metadata":{"annotations":{"nginx.ingress.kubernetes.io/ssl-redirect":"true"}}}'
- Delete if you need to remove the route:
kubectl delete ingress demo -n ingress-demo
Controller and system checks:
- Check controller logs (example name for NGINX Ingress):
kubectl -n ingress-nginx logs deploy/ingress-nginx-controller
- Watch namespace events in time order:
kubectl -n ingress-demo get events --sort-by=.lastTimestamp
- Port-forward the controller service to test locally (HTTP and HTTPS):
kubectl -n ingress-nginx port-forward svc/ingress-nginx-controller 8080:80 8443:443
Practical example: minimal HTTP Ingress
Create a dedicated namespace and a tiny echo app so you can see headers and paths coming through the Ingress.
- Create namespace:
kubectl create namespace ingress-demo
- Deploy a simple echo app and Service:
# demo-app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo
namespace: ingress-demo
spec:
replicas: 1
selector:
matchLabels:
app: demo
template:
metadata:
labels:
app: demo
spec:
containers:
- name: http-echo
image: hashicorp/http-echo:1.0.0
args: ["-text=hello from demo"]
ports:
- containerPort: 5678
---
apiVersion: v1
kind: Service
metadata:
name: demo-svc
namespace: ingress-demo
spec:
selector:
app: demo
ports:
- name: http
port: 80
targetPort: 5678
Apply it:
kubectl apply -f demo-app.yaml
- Create a minimal Ingress:
# demo-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo
namespace: ingress-demo
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: app.example.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: demo-svc
port:
number: 80
Apply and verify:
kubectl apply -f demo-ingress.yaml
kubectl -n ingress-demo get ingress demo
kubectl -n ingress-demo describe ingress demo
- Test locally by port-forwarding the controller service:
# In one terminal
kubectl -n ingress-nginx port-forward svc/ingress-nginx-controller 8080:80
# In another terminal
curl -H "Host: app.example.local" http://127.0.0.1:8080/
Expected: you should see the echo text or an HTTP 200 response.
Practical example: add TLS
For a quick local test, use a self-signed certificate. This is for non-production testing only.
- Create a test TLS key and cert:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt -subj "/CN=app.example.local/O=demo"
- Create a Kubernetes TLS secret in the same namespace as the Ingress:
kubectl -n ingress-demo create secret tls demo-tls --cert=tls.crt --key=tls.key
- Add TLS to the Ingress spec:
# demo-ingress-tls.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo
namespace: ingress-demo
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- app.example.local
secretName: demo-tls
rules:
- host: app.example.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: demo-svc
port:
number: 80
Apply and verify:
kubectl apply -f demo-ingress-tls.yaml
kubectl -n ingress-demo describe ingress demo
- Test HTTPS locally (port-forward 443):
# In one terminal
kubectl -n ingress-nginx port-forward svc/ingress-nginx-controller 8443:443
# In another terminal (-k to ignore self-signed cert warnings)
curl -k -H "Host: app.example.local" https://127.0.0.1:8443/
Expected: HTTP 200 over HTTPS. In production, use a valid certificate and do not use -k.
Troubleshooting and safe operations
Quick checks:
- Confirm the Ingress and its class:
kubectl get ingress -A
kubectl get ingressclass
- Look for errors and reasons in the Ingress description and events:
kubectl -n ingress-demo describe ingress demo
kubectl -n ingress-demo get events --sort-by=.lastTimestamp | tail -n 40
- Ensure endpoints exist for the Service:
kubectl -n ingress-demo get endpoints demo-svc -o wide
- Review controller logs for routing or TLS errors:
kubectl -n ingress-nginx logs deploy/ingress-nginx-controller | tail -n 100
Safer changes:
- Preview before applying:
kubectl diff -f demo-ingress.yaml
- Make targeted updates:
kubectl patch ingress demo -n ingress-demo \
--type merge -p '{"metadata":{"annotations":{"nginx.ingress.kubernetes.io/proxy-body-size":"8m"}}}'
- Revert by re-applying a known-good manifest or removing one change at a time.
Common issues:
- 404 from controller: check host header in curl, Ingress host, and path match.
- 502/504: confirm Service targetPort and Pod containerPort match; check Pod readiness.
- TLS warnings: verify secret type is kubernetes.io/tls and hosts match the cert CN/SAN.
Local Pilot Plan
Goal: Route a single host and single path to one Service, tested locally, with clear pass/fail.
Scope and setup:
- Namespace: ingress-demo
- Host: app.example.local
- Paths: /
- Backends: one Service (demo-svc)
- Success criteria: HTTP 200 for HTTP and HTTPS tests
Steps:
- Deploy echo app and Service (demo-app.yaml)
- Apply minimal Ingress (demo-ingress.yaml)
- Port-forward controller service and curl with Host header
- Add TLS secret and update Ingress (demo-ingress-tls.yaml)
- Re-test with HTTPS using -k for self-signed
- Document commands and outputs for team reuse
Exit conditions:
- Verified 200 responses over HTTP and HTTPS
- No error events in the namespace
- Controller logs free of repeating errors
Conclusion
You now have a repeatable way to create, verify, test, secure, and troubleshoot Kubernetes Ingress using a small set of reliable commands. Start with the local pilot to de-risk changes, then expand to multiple hosts and paths. Keep using diff, targeted patches, and clear tests to avoid regressions. When ready, standardize these manifests and commands in your team runbooks so new routes are quick, consistent, and safe.