What is Ingress in Kubernetes
Kubernetes Ingress is an API object that manages external access to the Services in a Kubernetes cluster. Ingress acts as a Layer 7 load balancer allowing your pods to be accessed from outside the cluster. It routes the external traffic based on the host and path in the URL.
Usually, you will have an Ingress controller that's responsible for fulfilling the Ingress, often with a load balancer. It listens to the Kubernetes API for Ingress resources and updates the load balancer accordingly.
Exposing Pod Through Ingress
I will show you how to expose a simple helloworld
Pod to external traffic using the Ingress resource. We will be using Minikube to create a local Kubernetes cluster.
Starting Minikube
Start Minikube using the command below.
$ minikube start
Adding Ingress Addon
Minikube supports addons, which are a set of features and integrations enabled by default. For Ingress functionality, we need to enable the Ingress addon:
$ minikube addons enable ingress
You can check if the Ingress controller is running by looking for it among the pods in the ingress-nginx
Namespace.
$ kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
helloworld 1/1 Running 0 12m
ingress-nginx-admission-create-7jxrq 0/1 Completed 0 30m
ingress-nginx-admission-patch-w7m8w 0/1 Completed 1 30m
ingress-nginx-controller-6cc5ccb977-qqbl6 1/1 Running 0 30m
Creating Pod, NodePort and Ingress
Create helloworld
Pod and NodePort in ingress-nginx
Namespace.
$ kubectl run --image=gcr.io/google-samples/hello-app:1.0 --port=8080 --restart=Never helloworld --namespace ingress-nginx
$ kubectl expose pod helloworld --type NodePort --port 8080 --name helloworld-nodeport --namespace ingress-nginx
Now, let's create an Ingress resource that will expose the helloworld-nodeport
Service on all paths /
.
The file ingress.yaml
will look something like this:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: helloworld
namespace: ingress-nginx
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: helloworld-nodeport
port:
number: 8080
Apply the configuration:
$ kubectl apply -f ingress.yaml
Listing Ingress Resources
Use the following command to see all the ingress resources:
$ kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
helloworld nginx * 192.168.49.2 80 45s
Retrieving the IP of the Ingress Controller
You can retrieve the IP assigned to your Ingress controller by running:
$ kubectl get ingress | awk '{ print $4 }' | tail -1
This IP is what you will use to access your Service.
Accessing the helloworld-nodeport Through Ingress
Now, let's access the helloworld-nodeport
Service through Ingress:
$ curl $(kubectl get ingress -n ingress-nginx | awk '{ print $4 }' | tail -1)
192.168.49.2
This command retrieves the IP address of the Ingress controller and sends a curl
request to it. If everything is set up correctly, you should see the output from the helloworld-nodeport
Service.
Creating New Ingress Resource
We can also create a second version of our Service, helloworld_v2
, and expose it through the Ingress using a different path.
First, let's create a new Pod for helloworld_v2
, expose it as a Service with NodePort, and create an Ingress resource for it.
The file ingress_path.yaml
should look like this:
kind: Ingress
metadata:
name: helloworld-v2
namespace: ingress-nginx
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- http:
paths:
- path: /helloworld-v2
pathType: Prefix
backend:
service:
name: helloworld-v2-nodeport
port:
number: 8080
Now, run the following commands to create the Pod, Service, and Ingress resource:
# Create the helloworld-v2 pod
$ kubectl run --image=gcr.io/google-samples/hello-app:2.0 --port=8080 --restart=Never helloworld-v2 --namespace ingress-nginx
# Expose the pod as a service
$ kubectl expose pod helloworld-v2 --type=NodePort --port=8080 --name=helloworld-v2-nodeport --namespace ingress-nginx
# Create the Ingress resource
$ kubectl apply -f ingress_path.yaml
Testing Access to the helloworld-v2 Pod from Within the Cluster
Let's create a temporary Pod with curl installed to test access to the helloworld-v2
Pod from within the cluster.
$ kubectl run --namespace ingress-nginx --restart=Never --image=curlimages/curl:7.68.0 -it --rm curl sh
Now, use curl
to make a request to the helloworld-v2
Pod:
/ $ curl 10.244.0.8:8080 # 10.244.0.8 is obtained from `kubectl get pod,svc -o wide -n ingress-nginx`
Hello, world!
Version: 2.0.0
Hostname: helloworld-v2
Testing Access to helloworld-v2-nodeport from Within the Cluster
Now, from the same temporary Pod, let's test access to the helloworld-v2-nodeport
Service:
/ $ curl helloworld-v2-nodeport:8080
Hello, world!
Version: 2.0.0
Hostname: helloworld-v2
Accessing helloworld-v2-nodeport Service Through the Ingress Path /helloworld_v2
Finally, let's access the helloworld-v2-nodeport
Service externally through the Ingress path /helloworld_v2
:
$ curl $(kubectl get ingress helloworld-v2 -n ingress-nginx | awk '{ print $4 }' | tail -1)/helloworld-v2
Hello, world!
Version: 2.0.0
Hostname: helloworld-v2