Kubernetes Services of type ClusterIP expose applications only within the cluster — external traffic cannot reach them directly. An Ingress resource solves this by providing HTTP/HTTPS routing from outside the cluster to internal services based on hostnames and URL paths. The Nginx Ingress Controller is the most widely deployed ingress controller, running as a pod inside the cluster that watches for Ingress resource changes and dynamically updates Nginx configuration to route traffic accordingly. It supports SSL termination (handling TLS at the ingress layer so backend services receive plain HTTP), path-based routing (different paths to different services), virtual hosting (different hostnames to different services), and rate limiting. This guide covers installing the Nginx Ingress Controller on RHEL 9 and configuring Ingress rules for TLS termination and path-based routing.
Prerequisites
- Kubernetes cluster running on RHEL 9
- Helm installed
Step 1 — Install Nginx Ingress Controller
# Install via Helm
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm install nginx-ingress ingress-nginx/ingress-nginx
--namespace ingress-nginx
--create-namespace
--set controller.service.type=NodePort
--set controller.service.nodePorts.http=30080
--set controller.service.nodePorts.https=30443
# Verify the ingress controller is running
kubectl get pods -n ingress-nginx
kubectl get service -n ingress-nginx
Step 2 — Create a TLS Secret
# Generate a self-signed certificate for testing
openssl req -x509 -nodes -days 365 -newkey rsa:2048
-keyout /tmp/tls.key
-out /tmp/tls.crt
-subj "/CN=myapp.example.com"
# Create a Kubernetes TLS Secret
kubectl create secret tls myapp-tls
--cert=/tmp/tls.crt
--key=/tmp/tls.key
--namespace myapp
Step 3 — Create Ingress Resources
# /tmp/myapp-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ingress
namespace: myapp
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/use-regex: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- myapp.example.com
secretName: myapp-tls
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
kubectl apply -f /tmp/myapp-ingress.yaml
kubectl get ingress -n myapp
kubectl describe ingress myapp-ingress -n myapp
Step 4 — Rate Limiting and Auth Annotations
# Add rate limiting and auth to an Ingress via annotations:
annotations:
# Rate limit: 100 requests per minute per IP
nginx.ingress.kubernetes.io/limit-rps: "100"
# Basic authentication (using a htpasswd secret)
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-auth
nginx.ingress.kubernetes.io/auth-realm: "Authentication Required"
Conclusion
The Nginx Ingress Controller on RHEL 9 provides a production-ready HTTP/HTTPS gateway for Kubernetes workloads with TLS termination, path routing, virtual hosting, and rate limiting through annotation-based configuration. For bare-metal deployments, using NodePort service type (as configured above) exposes the ingress on specific node ports — for a more production-like external IP, install MetalLB (a load balancer for bare-metal Kubernetes) alongside the ingress controller to assign external IPs from your network range via LoadBalancer type services.
Next steps: How to Deploy Applications to Kubernetes on RHEL 9, How to Configure Kubernetes RBAC on RHEL 9, and How to Install ArgoCD on RHEL 9.