Kubernetes Ingress resources give you a single entry point for routing external HTTP and HTTPS traffic to services inside your cluster. On RHEL 8, the Nginx Ingress Controller is a popular choice because it integrates cleanly with bare-metal deployments and supports TLS termination, name-based virtual hosting, and path-based routing out of the box. This tutorial walks you through installing the Nginx Ingress Controller, defining Ingress rules, opening the required firewall ports, and testing your configuration end to end. By the end you will be routing real traffic to cluster services through a single NodePort.
Prerequisites
- A running Kubernetes cluster on RHEL 8 (single-node or multi-node)
kubectlconfigured with cluster-admin privilegesfirewall-cmdavailable and the firewalld service active- DNS or
/etc/hostsentries pointing your test hostname to the node IP - Optional: a TLS certificate/key pair for the HTTPS section
Step 1 — Install the Nginx Ingress Controller
Apply the official bare-metal manifest from the Kubernetes ingress-nginx project. The bare-metal variant uses a NodePort Service instead of a cloud load balancer, which is appropriate for on-premises RHEL 8 nodes.
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.10.1/deploy/static/provider/baremetal/deploy.yaml
Watch the controller pod reach the Running state before proceeding:
kubectl get pods -n ingress-nginx -w
Once the ingress-nginx-controller pod shows Running, note the NodePort assigned to port 80 and 443:
kubectl get svc -n ingress-nginx ingress-nginx-controller
Step 2 — Open Firewall Ports
By default the bare-metal manifest exposes the controller on NodePorts 30080 (HTTP) and 30443 (HTTPS). Open those ports on the RHEL 8 firewall so external clients can reach the cluster.
sudo firewall-cmd --permanent --add-port=30080/tcp
sudo firewall-cmd --permanent --add-port=30443/tcp
sudo firewall-cmd --reload
sudo firewall-cmd --list-ports
If the controller was assigned different NodePort values in your cluster, substitute those numbers instead.
Step 3 — Deploy a Sample Application
Create a simple deployment and ClusterIP service to act as the backend for the Ingress rule.
kubectl create deployment demo-app --image=nginxdemos/hello --port=80
kubectl expose deployment demo-app --port=80 --target-port=80 --name=demo-app-svc
Verify the service is available:
kubectl get svc demo-app-svc
Step 4 — Create an Ingress Resource
Save the following YAML as demo-ingress.yaml. It routes all requests for demo.example.com to the demo-app-svc service on port 80.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: demo.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: demo-app-svc
port:
number: 80
kubectl apply -f demo-ingress.yaml
kubectl get ingress demo-ingress
Step 5 — Add TLS with a Kubernetes Secret
For HTTPS, create a Secret containing your certificate and private key, then reference it in the Ingress spec.
kubectl create secret tls demo-tls-secret
--cert=demo.example.com.crt
--key=demo.example.com.key
Add a tls block to your Ingress YAML and reapply:
spec:
ingressClassName: nginx
tls:
- hosts:
- demo.example.com
secretName: demo-tls-secret
rules:
- host: demo.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: demo-app-svc
port:
number: 80
kubectl apply -f demo-ingress.yaml
Step 6 — Test the Ingress
Send a request using curl with a Host header to simulate name-based routing. Replace NODE_IP with your RHEL 8 node’s IP address.
# HTTP via NodePort
curl -v -H 'Host: demo.example.com' http://NODE_IP:30080/
# HTTPS via NodePort (skip cert verification for self-signed certs)
curl -v -k -H 'Host: demo.example.com' https://NODE_IP:30443/
A successful response displays the Nginx demo page HTML, confirming the Ingress controller is routing traffic correctly.
Conclusion
You have installed the Nginx Ingress Controller on a bare-metal RHEL 8 Kubernetes cluster, defined an Ingress resource with host and path routing rules, opened the required firewall NodePorts, secured traffic with a TLS Secret, and verified routing with curl. The Ingress layer consolidates all external HTTP traffic through a single controller, making it far easier to manage multiple services behind a single IP address.
Next steps: Configure cert-manager for automatic TLS certificate issuance, Set up rate limiting and authentication annotations on Nginx Ingress, and Deploy multiple services under different path prefixes on the same hostname.