Kubernetes ingress is an API object that manages the external access to the kubernetes services. It provides routing rules to provide external users access to the services in a Kubernetes cluster, typically via HTTPS/HTTP. Ingress helps to provide an easy method to access the services without creating multiple load balancers or using the NodePort. In the last article, we have seen how to expose the Nginx service using a load balancer. Since it was in a bare-metal environment, we deployed MetalLB to simulate the load balancer. This setup might look easy at first sight but in the real environment, you might end up deploying multiple load balancers to expose the services.
To avoid multiple load balancers and multiple external IPs, we can use an Ingress controller to route the traffic from the load balancer to kubernetes services. An Ingress does not expose arbitrary ports or protocols other than HTTP/HTTPS. Exposing other services to the internet typically uses a service of type Service.Type=NodePort or Service.Type=LoadBalancer.
Kubernetes doesn’t provide the ingress controllers but supports multiple third-party ingress controllers. Traefik is one of the most widely used ingress controllers for Kubernetes.
Let’s see how to deploy and configure traefik to expose the kubernetes services to the outside world.
Prerequisite:
- Kubernetes Cluster 1.14+
- MetalLB – LoadBalancer
- Setup a dynamic NFS storage to create a persistent volume
Deploying Traefik v2
1. Log into the kubernetes cluster with the required privileges for the deployment.
2. Set up the traefik helm repo for deployment.
lingesh@uamaster1:~$ helm repo add traefik https://helm.traefik.io/traefik "traefik" has been added to your repositories lingesh@uamaster1:~$ helm repo update Hang tight while we grab the latest from your chart repositories... ...Successfully got an update from the "kasten" chart repository ...Successfully got an update from the "traefik" chart repository ...Successfully got an update from the "prometheus-community" chart repository ...Successfully got an update from the "jupyterhub" chart repository ...Successfully got an update from the "bitnami" chart repository Update Complete. ⎈Happy Helming!⎈ lingesh@uamaster1:~$
3. Find the traefik version on the repo.
lingesh@uamaster1:~$ helm search repo traefik NAME CHART VERSION APP VERSION DESCRIPTION traefik/traefik 10.24.3 2.8.5 A Traefik based Kubernetes ingress controller lingesh@uamaster1:~$
4. Download the value file from the helm repo to enable the persistent volume.
lingesh@uamaster1:~$ helm show values traefik/traefik > traefik-values.yaml lingesh@uamaster1:~$
5. Update the value file with the persistence field enabled to hold the TLS certificates.
lingesh@uamaster1:~$ cat traefik-values.yaml |grep -a1 persistence: # It will persist TLS certificates. persistence: enabled: true lingesh@uamaster1:~$
6. Create a new namespace called “traefik”
lingesh@uamaster1:~$ kubectl create ns traefik namespace/traefik created
7. Deploy the traefik helm chart with the override value file.
lingesh@uamaster1:~$ helm install traefik traefik/traefik --values traefik-values.yaml -n traefik NAME: traefik LAST DEPLOYED: Wed Sep 21 17:38:04 2022 NAMESPACE: traefik STATUS: deployed REVISION: 1 TEST SUITE: None lingesh@uamaster1:~$
8. Here is the traefik deployment status. In My case, the external load balancer IP is “192.168.23.150”.
lingesh@uamaster1:~$ kubectl get all -n traefik NAME READY STATUS RESTARTS AGE pod/traefik-675bcc5d95-lqw4s 1/1 Running 0 88s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/traefik LoadBalancer 10.233.48.67 192.168.23.150 80:30543/TCP,443:31708/TCP 88s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/traefik 1/1 1 1 88s NAME DESIRED CURRENT READY AGE replicaset.apps/traefik-675bcc5d95 1 1 1 88s lingesh@uamaster1:~$
Traefik is ready to serve the incoming traffic.
Test the traefik deployment:
1. Let’s test the traefik ingressroute. Here is my existing nginx deployment and the service is listening to the clusterIP.
lingesh@uamaster1:~$ kubectl get all -n nginx-test NAME READY STATUS RESTARTS AGE pod/nginx-deployment-74d589986c-lxkfq 1/1 Running 0 2d1h NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/nginx-deployment ClusterIP 10.233.11.165 <none> 80/TCP 2d NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/nginx-deployment 1/1 1 1 2d1h NAME DESIRED CURRENT READY AGE replicaset.apps/nginx-deployment-74d589986c 1 1 1 2d1h lingesh@uamaster1:~$
2. For the above-mentioned nginx deployment, create the ingressroute config like the below.
--- apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: nginx-deployment namespace: nginx-test spec: entryPoints: - web routes: - match: Host(`nginx.ua.com`) kind: Rule services: - name: nginx-deployment port: 80
3. Create the ingress resource for nginx deployment.
lingesh@uamaster1:~$ kubectl create -f nginx_ingress.yaml ingressroute.traefik.containo.us/nginx-deployment created lingesh@uamaster1:~$ kubectl get ingressroute -n nginx-test NAME AGE nginx-deployment 21s lingesh@uamaster1:~$
4. Refer to step 8 to know your external IP. For this IP, you need to create a DNS A record to access the Nginx deployment. (192.168.23.150). In my case, I have added the following entry in my host’s file.
192.168.23.150 nginx.ua.com
5. Open the browser and try to access nginx.ua.com.
If you wonder how we are able to access the Nginx deployment from Kubernetes, just look at the below diagram one more.
Expose/Enable traefik GUI:
Traefik offers readonly GUI portal to view the ingress configs and entry points. Let’s expose the traefik port 9000 to view the webpage.
- Create a traefik ingressroute manifest for the dashboard.
lingesh@uamaster1:~$ cat traefik_dashboard.yaml # dashboard.yaml apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: traefik-dashboard namespace: traefik spec: entryPoints: - web routes: - match: Host(`traefik.ua.com`) kind: Rule services: - name: api@internal kind: TraefikService lingesh@uamaster1:~$
2. Create the ingressroute resource using kubectl.
lingesh@uamaster1:~$ kubectl create -f traefik_dashboard.yaml -n traefik ingressroute.traefik.containo.us/traefik-dashboard created lingesh@uamaster1:~$ kubectl describe ingressroute traefik-dashboard -n traefik Name: traefik-dashboard Namespace: traefik Labels: <none> Annotations: <none> API Version: traefik.containo.us/v1alpha1 Kind: IngressRoute Metadata: Creation Timestamp: 2022-09-22T03:12:32Z Generation: 1 Managed Fields: API Version: traefik.containo.us/v1alpha1 Fields Type: FieldsV1 fieldsV1: f:spec: .: f:entryPoints: f:routes: Manager: kubectl-create Operation: Update Time: 2022-09-22T03:12:32Z Resource Version: 1498880 UID: e86c4083-aa35-4621-89bf-6e369d795315 Spec: Entry Points: web Routes: Kind: Rule Match: Host(`traefik.ua.com`) Services: Kind: TraefikService Name: api@internal Events: <none> lingesh@uamaster1:~$
3. Ensure that you have created the DNS A record for the traefik host rule on your DNS server or local “hosts” file to resolve the IP to FQDN.
192.168.23.150 nginx.ua.com 192.168.23.150 traefik.ua.com
4. Try to access nginx.ua.com. You should be able to see the traefik dashboard like below.
Conclusion:
We have deployed the traefik ingress controller and enabled ingress for one of the services successfully. Ingress controller to keep the environment scalable and reduce the number of load balancers in the environment to expose the services. In the end, we have enabled the traefik dashboard using the ingressroute. In the next article, we will look at TLS and Middleware options available in the traefik.
Leave a Reply