The vast majority of Kubernetes clusters are used to host containers that process incoming requests from microservices to full web applications. Having these incoming requests come into a central location, then get handed out via services in Kubernetes, is the most secure way to configure a cluster. That central incoming point is an ingress controller.
The most common product used as an ingress controller for privately-hosted Kubernetes clusters is NGINX. NGINX has most of the features enterprises are looking for, and will work as an ingress controller for Kubernetes regardless of which cloud, virtualization platform, or Linux operating system Kubernetes is running on.
The first step required to use NGINX as an Ingress controller on a Platform9 managed Kubernetes cluster, is to have a running Kubernetes cluster.
In this case the cluster we will be using is called “ingress-test” and it is listed as healthy. It is a single node cluster running on an Ubuntu 16.04 server.
% ssh firstname.lastname@example.org Welcome to Ubuntu 16.04.6 LTS (GNU/Linux 4.4.0-173-generic x86_64) root@pmkft:~# kubectl get nodes NAME STATUS ROLES AGE VERSION 18.104.22.168 Ready master 10h v1.14.8 root@pmkft:~# kubectl get namespaces NAME STATUS AGE default Active 11h kube-node-lease Active 11h kube-public Active 11h kube-system Active 11h
Running “kubectl get nodes” and “kubectl get namespaces” confirm that authentication is working, the cluster nodes are ready, and there are no NGINX Ingress controllers configured.
Mandatory Components for an NGINX Ingress Controller
An ingress controller, because it is a core component of Kubernetes, requires configuration to more moving parts of the cluster than just deploying a pod and a route.
In the case of NGINX, its recommended configuration has three ConfigMaps:
- Base Deployment
- TCP configuration
- UDP configuration
A service account to run the service is within the cluster, and that service account will be assigned a couple roles.
A cluster role is assigned to the service account, which allows it to get, list, and read the configuration of all services and events. This could be limited if you were to have multiple ingress controllers. But in most cases, that is overkill.
A namespace-specific role is assigned to the service account to read and update all the ConfigMaps and other items that are specific to the NGINX Ingress controller’s own configuration.
The last piece is the actual pod deployment into its own namespace to make it easy to draw boundaries around it for security and resource quotas.
The deployment specifies which ConfigMaps will be referenced, the container image and command line that will be used, and any other specific information around how to run the actual NGINX Ingress controller.
NGINX has a single file they maintain in GitHub linked to from the Kubernetes documentation that has all this configuration spelled out in YAML and ready to deploy.
To apply this configuration, the command to run is:
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.28.0/deploy/static/mandatory.yaml
Which will generate the following output:
namespace/ingress-nginx created configmap/nginx-configuration created configmap/tcp-services created configmap/udp-services created serviceaccount/nginx-ingress-serviceaccount created clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created role.rbac.authorization.k8s.io/nginx-ingress-role created rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created deployment.apps/nginx-ingress-controller created limitrange/ingress-nginx created