Considering you already have a kubernetes cluster here we are going to use the kubernetes ingress-nginx helm chart to install nginx and serve a simple example app named status-app
, once the load balancer is deployed we will use the IP to point a dns A
record to it and finally add whitelist to only allow specific set of IPs or CIDR ranges and block everything else.
First, let's add the helm repo, pull and untar it locally:
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm pull ingress-nginx/ingress-nginx --untar
Second, install the ingress-nginx
chart which will create a load balancer/Ingress in your cluster, wait for it to be healthy:
helm install ingress-nginx -n ingress-nginx \
ingress-nginx -f values/ingress-nginx/values.yaml\
--create-namespace
Example in GCP for me it looks like this:
Now go to your DNS dashboard and add a wildcard (*
), A
record pointing to the IP used by the load balancer created by the nginx Ingress load balancer. Example in my case:
Deploy the sample status-app
and it's kubernetes service:
apiVersion: apps/v1
kind: Deployment
metadata:
name: status-app
namespace: default
labels:
app: status-app
spec:
selector:
matchLabels:
app: status-app
template:
metadata:
labels:
app: status-app
spec:
containers:
- name: nodejs-server-port-80
image: cooervo/server-with-args:v1.0
args: ["status app running 馃檪馃憤"]
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: status-app
namespace: default
labels:
app: status-app
spec:
type: NodePort
selector:
app: status-app
ports:
- name: http
port: 80 # this Service port (to receive connections externally)
targetPort: 80 # the Pod port (to send connections to)
Finally, to allow external navigation into it you need to use a kubernetes Ingress
notice spec.ingressClassName: nginx
and the annotation with the IPs or CIDR ranges:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: status-app
namespace: default
annotations:
nginx.ingress.kubernetes.io/whitelist-source-range: "120.0.200.127/32,100.0.0.2" # Add your IPs or CIDR ranges, here separated by commas
spec:
ingressClassName: nginx
rules:
- host: status.cooervo.com
http:
paths:
- pathType: Prefix
backend:
service:
name: status-app
port:
number: 80
path: /
That's all, this has the advantage of configuring on the service/deployment level, which you can customize for each one of your kubernetes deployments.
If you try to visit the website from an IP that is not in whitelist-source-range annotation you'll get nginx's 403 Forbidden
error screen.
I have created an example in github for easy reference.