The goal of Ingress is to be a L7 Load balancer: Ingress will handel your load-balancing, authentication, SSL, and URL based routing config. This still needs to be exposed using a NodePort.
This uses a LB/reverse-proxy like GCE, NGINX, HAPROXY, Traefik as your Ingress Controller (Doesn’t come with Kube by default, so if you don’t build these your ingress stuff won’t work). GCE and NGINXS are currently being supported/maintained by the Kuberneties project. The rules that are configured are the Ingress Resources.
We will also need the service to expose the Ingress to the outside
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx
spec:
type: LoadBalancer
selector:
app: nginx-ingress
ports:
- protocol: TCP
port: 80
targetPort: 80
- protocol: TCP
port: 443
targetPort: 443
You’ll also need the config-map that is referenced in the Deployment
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-configuration
Next we’ll need to deploy the nginx pod
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-ingress-controller
spec:
replicas: 2
selector:
matchLabels:
app: nginx-ingress
template:
metadata:
labels:
app: nginx-ingress
spec:
serviceAccountName: nginx-ingress-serviceaccount
containers:
- name: nginx-ingress-controller
image: quay.io/repository/kubernetes-ingress-controller/nginx-ingress-controller:0.21.0 # A specal nginx image for kub ingress controllers
args:
- /nginx-ingress-controller
- --configmap=$(POD_NAMESPACE)/nginx-configuration #config map we made before
env:
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
resources:
limits:
cpu: "500m"
memory: "512Mi"
requests:
cpu: "200m"
memory: "256Mi"
We’ll also need a service account so that the system can monitor watching for Ingress objects and configure the NGINX to make them work, for that it will need a service account
apiVersion: v1
kind: ServiceAccount
metadata:
name: nginx-ingress-serviceaccount
Well that wasn’t fun at all, but now we should be able to setup the LB features, like routing based on the path name: So going to <node-ip>/pod-a for example
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: / # NGINX only, This will remove the /pod-a or /pod-b from the URL
spec:
rules:
- http:
paths:
- path: /pod-a
pathType: Prefix # This sets it up so that /pod-a and /pod-a/info would both go to the pod as /, so it will remove everything in the path if it matches /pod-a/
backend:
service:
name: pod-a-service
port:
number: 80
- path: /pod-b
pathType: Prefix
backend:
service:
name: pod-b-service
port:
number: 80
Please note the line nginx.ingress.kubernetes.io/rewrite-target: /
This will re-wite anything that patches the path to /, so /pod-a/info will be re-written and pod-a will get the path /.
If you wanted to keep the /info you could do something like this (This code is un-tested)
nginx.ingress.kubernetes.io/rewrite-target: /$2
paths:
- path: /pod-a(/|$)(.*)
pathType: Prefix
backend:
With this The path regex captures the part after /pod-a into $2, The rewrite-target uses $2 to forward only the remainder of the path to the backend service.
- Example with Modified Configuration:
- Request: /pod-a/info
- Backend Receives: /info
- Request: /pod-a/
- Backend Receives: /
- Request: /pod-a/info
But what if you want to host multiple websites on the same Kube server? For that you would want to look into the hosts field.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: pod-a.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: pod-a-service
port:
number: 80
- host: pod-b.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: pod-b-service
port:
number: 80