2022-06-19

Kubernetes Ingress

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.

bash
$ 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:

bash
$ 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.

bash
$ 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.

bash
$ 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:

ingress.yaml
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:

bash
$ kubectl apply -f ingress.yaml

Listing Ingress Resources

Use the following command to see all the ingress resources:

bash
$ 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:

bash
$ 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:

bash
$ 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:

ingress_path.yaml
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:

bash
# 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.

bash
$ 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:

bash
/ $ 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:

bash
/ $ 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:

bash
$ 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

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!