In previous posts on deploying an application to a Kubernetes cluster we used a NodePort to expose the service to the outside world. Ingress is a separate Pod where we can control this exposure via routing, security and rate limiting. In this post we will discuss how to route a specific path to a service and how to whitelist clients based on IP address.

If you just can’t wait to dive into the code. The complete configuration can be found on github.

Setup Ingress

We will use the example application from an earlier post. So you will have a minikube cluster with a pod and a services. Then we setup minikube to enable Ingress:

minikube addons enable ingress

And using the power of helm we install Ingress on our cluster:

helm install stable/nginx-ingress --namespace jenkings-project --set controller.service.externalTrafficPolicy=Local

Routing

This is what the definition of our service looked like.

apiVersion: v1
kind: Service
metadata:
  name: java-spring-api
spec:
  type: NodePort
  ports:
  - nodePort: 31311
    port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: java-spring-api

It uses the NodePort to expose the service to the world outside of the cluster. This is a direct entrance so we have no control of it what so ever. Let’s change this so the service is only exposed inside the cluster.

apiVersion: v1
kind: Service
metadata:
  name: java-spring-api
spec:
  ports:
    - name: http
      port: 8080
      protocol: TCP
      targetPort: 8080
  selector:
    app: java-spring-api

Note that the service is now unavailable on the old address when we applied this service configuration.

Screenshot 2019 03 01 at 11.23.07 - KUBERNETES INGRESS

Now we can add an Ingress configuration to regain access.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: java-spring-api-rules
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /spring
        backend:
          serviceName: java-spring-api
          servicePort: 8080

We see that the path /spring will be routed to the service java-spring-api on port 8080. Now we can apply this Ingress configuration.

cd deployment/base
kustomize build ../overlays/test | kubectl apply --record -f -

And the service is available on the path we specified.

Screenshot 2019 03 01 at 11.30.20 - KUBERNETES INGRESS

Whitelist

A security measure for this API we have could be to only accept requests from whitelisted IP addresses. Let’s say we want for every environment different whitelists. We can configure this as follows in the overlays section per environment, in overlays/test/ingress.yaml.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: java-spring-api-rules
  annotations:
    nginx.ingress.kubernetes.io/whitelist-source-range: 82.32.164.22/0

I have chosen a bogus IP address but configure your IP range here to only allow trusted clients. We only have to specify the way this file is taken into account like this and we are done.

patchesStrategicMerge:
- ingress.yaml

Other configurations

There are many more configurable parts of Ingress that we haven’t seen yet. Here are just a couple if you’re interested:

  • Host based routing
  • TLS configuration
  • Rate limiting (on #connections or #connections per IP address)
  • CORS
  • Secure backends
  • Authentication