Fairwinds | Blog

Intro to Kube ingress: Set up nginx Ingress in Kubernetes Bare Metal

Written by Luke Reed | Aug 31, 2020 2:56:45 PM

An ingress is a resource that enables traffic to come into your Kubernetes cluster from the outside. This is usually to HTTP or HTTPS service. There are ways to map non-HTTP services to an ingress, but that is less common. This blog will only focus on HTTP and HTTPS traffic. 

One of the more interesting aspects of an ingress resource is that even though it is a basic primitive that ships with Kubernetes - like pods, deployments, replica sets etc., it actually requires something called an ingress controller to be installed on the cluster for the ingress resource to function. Creating an ingress resource without one of the controllers installed will have no effect. 

Since ingress resources require the controller to be running, the configuration of an ingress can be a bit open-ended. Any configuration that's specific to the type of controller you've chosen is generally done by annotating the ingress resources. 

You can think of an ingress controller as a sort of web server for all of your services in your Kubernetes cluster. It is configured to route requests to the proper service; not unlike the days of installing Apache on a bare metal server to expose a website to the internet. 

You can visualize how the ingress controller vs ingress resource is architected:

Source: Google Community Tutorials

Most ingress controllers will allow you to do both host based routing so foo.com should route to foo service in the foo namespace as well as path based routing - foo.com/dashboard should route to the foo-dashboard service. 

For simplicity sake, I’ll demo a single ingress controller - the nginx ingress controller. It's a popular choice in the Kubernetes community, but I also want to encourage you to investigate the various ingress controllers out there and decide which one makes most sense for your applications.

Let's take a look at an example.

You’ll first need to install the nginx ingress controller as documented in the GitHub repository. This launches the pods and related resources that will process and serve Ingress resources for you. The Nginx Ingress Getting Started page provides Kubernetes manifests for installing in Kubernetes on your own machine, AWS, GCP, or Azure clouds. For example, to install Nginx Ingress in Kubernetes running on your machine:

kubectl apply -f 
https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.34.1/deploy/static/provider/baremetal/deploy.yaml
…..
NodePort:                 http  32316/TCP

Next test the Kubernetes Service that provides access to the Nginx Ingress Controller pods, which in turn provide access to your Ingress objects. Kubernetes running on your machine will have been configured with a NodePort Service, and cloud installations with a LoadBalancer Service. To connect to a NodePort Service, in the case of Kubernetes running on your machine:

$ kubectl describe service -n ingress-nginx ingress-nginx-controller

In this case, connect to localhost:32316 on your machine. You should receive a page which displays “404 Not Found" - this is the Ingress Controller default response. IF you are using cloud-hosted Kubernetes, use the above “kubectl describe” command, and connect to the host name of the load balancer instead.

Now you’ll deploy a test application to Kubernetes.

This application is httpbin, a simple tool for requesting and receiving replies from an API. It provides the API and a front-end so it's good for testing. The Service is of type ClusterIP, and the ingress will send traffic to the endpoints (pods) of that Service. Now take a look at the ingress manifest that was applied by the above command.

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: httpbin
  namespace: httpbin
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: localhost
    http:
      paths:
      - backend:
          serviceName: httpbin
          servicePort: 80
        path: /

nginx is the class we're using. The controller looks for this annotation and knows that it owns this ingress. You'll notice here in the rules section that we set the host to be localhost. This will obviously be different if you're launching a production deployment - it could be your company's website or whatever url you are using for your application. For the backend, we’re pointing to that httpbin service that we just launched. Now make sure the httpbin pods are running.

$ kubectl get po -n httpbin -w

NAME                       READY   STATUS    RESTARTS   AGE   IP               NODE       NOMINATED NODE   READINESS GATES
httpbin-675dcdbdbd-w64f7   1/1     Running   0          9s    10.244.120.104   NodeName         none		none     

This app also provides a restful API, JSON. You can take a look at it in the browser localhost:

We can also look at the API in the browser by accessing the Nginx Ingress Controller service, making sure to specify “localhost” as the HTTP host header. The HOST header must match the host name specified in the Ingress. For example, replace “ServiceHostName” with localhost (if running Kubernetes on your machine) or the host name of your cloud load balancer: curl --header "HOST: localhost" http://ServiceHostName

There is a lot more to ingress. We encourage you to read more documentation or trial other ingress controllers. If you need help, do get in touch. Fairwinds offers Kubernetes services to help at any stage in your cloud native journey. 

Additional Resources