Kubernetes Nginx Ingress Controller – Here’s how it works

20 May, 2020

Achim Ledermüller
Achim Ledermüller
Senior Manager Cloud

Der Exil Regensburger kam 2012 zu NETWAYS, nachdem er dort sein Wirtschaftsinformatik Studium beendet hatte. In der Managed Services Abteilung ist er für den Betrieb und die Weiterentwicklung unserer Cloud- Plattform verantwortlich.

by | May 20, 2020

With the first steps with Kubernetes you already know how to start applications in your Kubernetes cluster. Now let’s expose your application online. In the following, I will explain how this works and how you can get started with a Kubernetes Nginx Ingress Controller using an example. To make applications in a Kubernetes cluster accessible from the outside, you can use a load balancer type service. In the NETWAYS Cloud, we start an Openstack Octavia LB with a public IP in the background and forward the incoming traffic to the pods (Bingo). This means that we need a separate load balancer with a public IP for each application. Named-based virtual hosts and server name indication (sni) were invented a long time ago in order to be able to work more resource- and therefore cost-efficiently in a case like this. The well-known NGINX web server supports both and, as a Kubernetes ingress controller, it can make all our http/s applications quickly and easily accessible with just one public IP address. Installing and updating the Ningx Ingress Controller is simplified thanks to a Helm chart. K8s Ingress objects are used to configure the mapping of vHosts, URI paths and TLS certificates to K8s services and thus to our applications. So that the buzzwords don’t prevent you from seeing the essentials, here is a brief overview of how the HTTP requests are forwarded to our applications:

Installation Kubernetes Nginx Ingress Controller

For an easy installation of the Kubernetes Nginx Ingress Controller you should use helmet for easy installation. Helm describes itself as a package manager for Kubernetes applications. In addition to installation, Helm also offers simple updates for its applications. As with kubectl, you only need the K8s config to get started right away:

helm install my-ingress stable/nginx-ingress

With these commands, Helm starts all the necessary components in the default namespace and gives them the label my-ingress. A deployment, a replicaset and a pod are created for the Nginx Ingress Controller. All http/s requests must be forwarded to this pod so that it can sort the requests based on vHosts and URI paths. A service of the type loadbalancer was created for this purpose, which listens for a public IP and forwards the incoming traffic on ports 443 and 80 to our pod. A similar construct is also created for the default backend, but I will not go into this in detail here. So that you don’t lose the overview, you can display all the components involved with kubectl:

kubectl get all -l release=my-ingress  #with default-backend
kubectl get all -l release=my-ingress -l component=controller #without default-backend

NAME                                                             READY    STATUS      RESTARTS
pod/my-ingress-nginx-ingress-controller-5b649cbcd8-6hgz6         1/1      Running     0       
 
NAME                                                             READY    UP-TO-DATE  AVAILABLE
deployment.apps/my-ingress-nginx-ingress-controller              1/1      1           1        
 
NAME                                                             DESIRED  CURRENT     READY
replicaset.apps/my-ingress-nginx-ingress-controller-5b649cbcd8   1        1           1    
 
NAME                                              TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)
service/my-ingress-nginx-ingress-controller       LoadBalancer   10.254.252.54    185.233.188.56   80:32110/TCP,443:31428/TCP

Example applications: Apache and Nginx

Next, we start two simple example applications. In the example, I use Apache and Nginx. The aim is to make both applications available under their own name-based virtual hosts: nginx.nws.netways.de and apache.nws.netways.de. To make the two deployments accessible within the K8s cluster, we need to connect each of them to a service.

K8s Deployments

Nginx Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

Apache Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: apache-deployment
  labels:
    app: apache
spec:
  replicas: 3
  selector:
    matchLabels:
      app: apache
  template:
    metadata:
      labels:
        app: apache
    spec:
      containers:
      - name: apache
        image: httpd:2.4
        ports:
        - containerPort: 80

K8s Service

Nginx Service

apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
    name: http
  selector:
    app: nginx

Apache Service

apiVersion: v1
kind: Service
metadata:
  name: apache-svc
spec:
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
    name: http
  selector:
    app: apache

Virtual hosts without TLS

In order to forward the requests from the Nginx controller to our applications, we need to roll out a suitable Kubernetes Ingress object. In the spec area of the ingress object, we can define different paths and virtual hosts. In the example, we see vHosts for nginx.nws.netways.de and apache.nws.netways.de. For each of the two vHosts, the corresponding service is of course entered in the backend area. The public IP can be found in the service of the Nginx Ingress Controller and kubectl describe shows all important details about the service (see below). For testing, it is best to manipulate its /etc/hosts file and enter the IP of LoadBalancer Ingress there.

K8s Ingress

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: my-ingress
spec:
  rules:
  - host: apache.nws.netways.de
    http:
      paths:
        - backend:
            serviceName: apache-svc
            servicePort: 80
  - host: nginx.nws.netways.de
    http:
      paths:
        - backend:
            serviceName: nginx-svc
            servicePort: 80

kubectl describe service/my-ingress-nginx-ingress-controller
kubectl get service/my-ingress-nginx-ingress-controller -o jsonpath='{.status.loadBalancer.ingress[].ip}’

Virtual hosts with TLS

Of course, applications without encryption are rarely made publicly accessible. Kubernetes has its own tls type within the secret object specifically for TLS certificates. All you need is a TLS certificate and the corresponding key. You can use kubectl to store the pair in Kubernetes:

kubectl create secret tls my-secret –key cert.key –cert cert.crt

The created secret can then be referenced by the specified name my-secret in spec of the Ingress object. To do this, enter our virtual host and the corresponding TLS certificate in the hosts array within tls. An automatic redirect from http to https is activated from the start.

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: my-ingress
spec:
  tls:
    - hosts:
      - apache.nws.netways.de
      - nginx.nws.netways.de
      secretName: my-secret
  rules:
  - host: apache.nws.netways.de
    http:
      paths:
        - backend:
            serviceName: apache-svc
            servicePort: 80
  - host: nginx.nws.netways.de
    http:
      paths:
        - backend:
            serviceName: nginx-svc
            servicePort: 80

Conclusion

With the Nginx Ingress Controller, it is easy to make your web-based applications publicly accessible. The features and configuration options offered should cover the requirements of all applications and can be found in the official user guide. In addition to your own application, you only need a Helm Chart and a K8s Ingress object. Kubernetes also manages to hide many complex layers and technologies with just a few abstract objects such as deployment and ingress. With a NETWAYS Managed Kubernetes solution, you can take full advantage of this abstraction and concentrate on your own application. So get started!

Our portfolio

0 Comments

Submit a Comment

Your email address will not be published. Required fields are marked *

How did you like our article?