Set up a Nginx Ingress on k8s
Hello everyone, it’s me again. Today is the first day of the Year of the Snake 2025, according to Eastern tradition. I wish you a new year full of health and energy for the challenges and opportunities ahead. In the previous article, we set up a Kubernetes cluster using k0s. Now, let’s talk about how to expose services running inside the cluster to the outside world using Ingress
.
Kubernetes Ingress
is a powerful API object that manages external access to services, typically HTTP and HTTPS traffic. Instead of exposing each service with a separate LoadBalancer or NodePort, Ingress provides a more flexible and cost-effective way to route traffic using a single entry point.
Prerequisites
- A working Kubernetes cluster set up using k0s (refer to Part 1 of this blog series).
- At least one Worker Node.
kubectl
configured to access your cluster.- A domain name (optional but recommended for practical Ingress usage).
Deploying a Load Balancer with MetalLB
Since k0s does not come with an in-built load balancer, we need to deploy MetalLB to provide external IP addresses to services of type LoadBalancer
.
Step 1: Install MetalLB
1
2
3
4
# Apply the MetalLB manifests
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/main/config/manifests/metallb-native.yaml
# Wait for the MetalLB pods to be in Running state
kubectl get pods -n metallb-system
Step 2: Configure an IP Address Pool
Create a configuration file for MetalLB:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
---
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: first-pool
namespace: metallb-system
spec:
addresses:
- <ip-address-range-start>-<ip-address-range-stop>
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: example
namespace: metallb-system
Apply the configuration:
1
kubectl apply -f metallb-config.yaml
Now, MetalLB will assign external IPs to LoadBalancer services in the cluster.
Install an Ingress Controller
Kubernetes itself does not provide an Ingress Controller by default. We need to install one. For this guide, we’ll use Nginx Ingress Controller.
First, apply the official Nginx Ingress Controller YAML manifest:
1
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml
Wait for the Ingress Controller pods to be in Running state:
1
kubectl get pods -n ingress-nginx
Expected output:
1
2
NAME READY STATUS RESTARTS AGE
ingress-nginx-controller-xxxxxxxxxx-xxxxx 1/1 Running 0 1m
Deploy a Sample Application
Now, let’s deploy a simple application inside the cluster to test Ingress.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-world
labels:
app: hello-world
spec:
replicas: 2
selector:
matchLabels:
app: hello-world
template:
metadata:
labels:
app: hello-world
spec:
containers:
- name: hello-world
image: ealen/echo-server
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: hello-world-service
spec:
selector:
app: hello-world
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
Apply this configuration:
1
kubectl apply -f hello-world.yaml
Configure Ingress
Now, let’s create an Ingress resource to route external traffic to our service.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hello-world-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: hello-world.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: hello-world-service
port:
number: 80
Apply the Ingress resource:
1
kubectl apply -f ingress.yaml
Test the Ingress
If you are using a domain, configure your DNS to point to the cluster’s external IP. If not, you can test using /etc/hosts:
1
2
echo "<INGRESS_IP> hello-world.local" | sudo tee -a /etc/hosts
curl http://hello-world.local
Expected reponse:
1
2
3
4
5
{
"host": "hello-world-service",
"headers": { ... },
"method": "GET"
}
Conclusion
Using Kubernetes Ingress, you can efficiently expose services without relying on multiple LoadBalancers. With the Nginx Ingress Controller, routing HTTP traffic becomes easy and manageable. Try adding more rules to handle different paths or subdomains!
References
Here are couple other articles that you can follow: