Ingress controller for Subdomain based Routing

In this post I will run the steps required to set up MetalLB for LoadBalancer IP allocation, the NGINX Ingress Controller for routing traffic based on subdomains, and how to configure local DNS to enable subdomain-based routing for Kubernetes services.

Ingress-nginx install

We will use Helm to install our ingress controller ingress-nginx, which will be used to route traffic based on subdomains.

# install  ingress controller ingress-nginx
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm -n ingress-nginx install ingress-nginx ingress-nginx/ingress-nginx --create-namespace

# check for ingressclasses
kubectl get ingressclasses.networking.k8s.io 
NAME    CONTROLLER             PARAMETERS   AGE
nginx   k8s.io/ingress-nginx         149m

MetalLB for loadbalancing

Then we will set up MetalLB in local K8s cluster, to enable LoadBalancer service.

MetalLB works in two modes: Layer 2 (simpler for home labs) or BGP (more complex, used in production environments), here we will deploy MetalLB manifest and create MetalLB ConfigMap For a Layer 2 configuration, assign a range of IP addresses on local network that MetalLB will use for load balancers.

# install metallb manifest
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.7/config/manifests/metallb-native.yaml

root@asb:~# kubectl get all -n metallb-system 
NAME                                 READY   STATUS    RESTARTS   AGE
pod/controller-fbf54885d-skzkl       1/1     Running   0         174m
pod/speaker-49m7r                    1/1     Running   0         174m
pod/speaker-5zvfk                    1/1     Running   0         174m
pod/speaker-gdm26                    1/1     Running   0         174m

NAME                          TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
service/webhook-service       ClusterIP   10.101.12.65           443/TCP   174m

NAME                        DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
daemonset.apps/speaker      3         3         3       3            3           kubernetes.io/os=linux   174m

NAME                                 READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/controller           1/1     1            1           174m

NAME                                         DESIRED   CURRENT   READY   AGE
replicaset.apps/controller-fbf54885d         1         1         1       174m

# Create a IP range for loadbalancer IP pool
vim metalab-pool.yaml 
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: my-ip-pool
  namespace: metallb-system
spec:
  addresses:
    - 11.0.1.240-11.0.1.252

# verify IP pool
kubectl describe ipaddresspool my-ip-pool -n metallb-system
kubectl get ipaddresspool -n metallb-system
NAME         AUTO ASSIGN   AVOID BUGGY IPS   ADDRESSES
my-ip-pool   true          false             ["11.0.1.240-11.0.1.252"]

# Loadbalancer auto assigned for Ingress Controller and joesite service with LoadBalancer   
kubectl get svc -A | grep Load
ingress-nginx       ingress-nginx-controller                               LoadBalancer   10.106.123.55    11.0.1.242    80:32279/TCP,443:31291/TCP      157m
joesite-argo        joesite-service                                       LoadBalancer   10.111.85.29     11.0.1.240    80:30500/TCP                     23d

Local DNS setup

I want to replace all the NodePort services with a subdomain for simplicity, so I need to edit both local PC and kubeconfig VM's host file to point all subdomains to the Ingress Controller LoadBalancer IP (11.0.1.242)

vim /etc/hosts
11.0.1.242      pm.tina.place am.tina.place gf.tina.place lh.tina.place ag.tina.place

Ingress rules for traffic control

Now we can create a list of Ingress rules to route the K8S services to subdomains. As those services come with different namespaces, we need to split each Ingress rule for services in different namespaces, also need to pay attention to TLS setting for https requests to avoid too many redirects.

vim monitoring-ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: monitoring-ingress
  namespace: monitoring
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - host: gf.tina.place
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: prometheus-stack-grafana
            port:
              number: 80
  - host: am.tina.place
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: prometheus-stack-kube-prom-alertmanager
            port:
              number: 9093
  - host: pm.tina.place
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: prometheus-stack-kube-prom-prometheus
            port:
              number: 9090
kubectl apply -f monitoring-ingress.yaml
kubectl apply -f other-ingress.yaml
root@asb:~/path-based# kubectl get ingress -A
NAMESPACE         NAME                   CLASS   HOSTS                                 ADDRESS     PORTS     AGE
argocd            argocd-ingress         nginx   ag.tina.place                         11.0.1.242  80, 443   

Welcome to Zack's Blog

Join me for fun journey about ##AWS ##DevOps ##Kubenetes ##MLOps

  • Latest Posts