Exposing a Cluster Externally with Kubernetes Ingress

What is Ingress? It is an L7 load balancer that exposes Pods inside and outside the cluster and can route based on HTTP. From outside the cluster, services can be routed by the host and path in the URL. External access is performed using public DNS.

Enabling the Ingress Add-on

Let’s look at how to use it. Enable the Ingress add-on in minikube with the following command.

minikube addons enable ingress

Result:

% minikube addons enable ingress
💡  ingress is an addon maintained by Kubernetes. For any concerns contact minikube on GitHub.
You can view the list of minikube maintainers at: https://github.com/kubernetes/minikube/blob/master/OWNERS
💡  After the addon is enabled, please run "minikube tunnel" and your ingress resources would be available at "127.0.0.1"
    ▪ Using image k8s.gcr.io/ingress-nginx/controller:v1.2.1
    ▪ Using image k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1
    ▪ Using image k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1
🔎  Verifying ingress addon...
🌟  The 'ingress' addon is enabled

Then run the command below to display the minikube add-on list and check whether ingress is enabled.

minikube addons list

Result:

% minikube addons list
|-----------------------------|----------|--------------|--------------------------------|
|         ADDON NAME          | PROFILE  |    STATUS    |           MAINTAINER           |
|-----------------------------|----------|--------------|--------------------------------|
| ambassador                  | minikube | disabled     | 3rd party (Ambassador)         |

... omitted ...

| inaccel                     | minikube | disabled     | 3rd party (InAccel             |
|                             |          |              | [info@inaccel.com])            |
| ingress                     | minikube | enabled ✅   | Kubernetes                     | <<< enabled
| ingress-dns                 | minikube | disabled     | Google                         |

... omitted ...

| volumesnapshots             | minikube | disabled     | Kubernetes                     |
|-----------------------------|----------|--------------|--------------------------------|

Then run the command below to check whether the Ingress controller Pod was created.

kubectl get pods -n ingress-nginx
% kubectl get pods -n ingress-nginx
NAME                                        READY   STATUS      RESTARTS   AGE
ingress-nginx-admission-create-sqvcp        0/1     Completed   0          8m9s
ingress-nginx-admission-patch-t6cj5         0/1     Completed   1          8m9s
ingress-nginx-controller-755dfbfc65-cf8ww   1/1     Running     0          8m9

In minikube, you can create an Ingress controller by enabling the add-on this way, but in cloud environments you need to install an Ingress controller.

Running Ingress with a YAML File

Next, define the allowed access path in YAML. This time, expose the hello-world Pod on every path /. To do that, create the following YAML file.

ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: helloworld
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: helloworld-nodeport
                port:
                  number: 8080

This YAML file sets the Ingress name to helloworld and describes path-related rules under http. It also defines which Service should be connected when the path is / by writing it in the backend section. Here it defines that traffic should connect to helloworld-nodeport on port 8080.

Create the manifest using this file. Manifests will be explained later, but here you can think of it as applying the settings. Run the following command.

kubectl apply -f ingress.yaml

Result:

% kubectl apply -f ingress.yaml
ingress.networking.k8s.io/helloworld created

To display the Ingress list and check whether the helloworld Ingress created above was created, run the following command.

kubectl get ingress

Result:

% kubectl get ingress
NAME         CLASS   HOSTS   ADDRESS        PORTS   AGE
helloworld   nginx   *       192.168.49.2   80      69s

To view details about the Ingress resource, run the following command.

kubectl describe ingress [Ingress name]

For helloworld, run it as follows.

% kubectl describe ingress helloworld
Name:             helloworld
Labels:           <none>
Namespace:        default
Address:          192.168.49.2
Ingress Class:    nginx
Default backend:  <default>
Rules:
  Host        Path  Backends
  ----        ----  --------
  *
              /   helloworld-nodeport:8080 (172.17.0.3:8080)
Annotations:  nginx.ingress.kubernetes.io/rewrite-target: /$1
Events:
  Type    Reason  Age                From                      Message
  ----    ------  ----               ----                      -------
  Normal  Sync    40s (x2 over 80s)  nginx-ingress-controller  Scheduled for sync

You can also get the IP of the Ingress controller with the following command and use it to access the helloworld-nodeport Service through Ingress.

% kubectl get ingress | awk '{ print $4 }'|tail -1
192.168.49.2

Try accessing it through Ingress.

% kubectl run --image curlimages/curl:7.68.0 -it --restart Never --rm curl sh
If you don't see a command prompt, try pressing enter.
/ $ curl 192.168.49.2
Hello, world!
Version: 1.0.0
Hostname: helloworld
/ $

This confirms that you can safely access the helloworld-nodeport Service through Ingress and connect to the helloworld Pod.