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.
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
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.
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.
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: 18.104.22.168/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
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)
- Secure backends