/traefik-ingress-example

Demo using the Traefik ingress controller in AKS

MIT LicenseMIT

Traefik Ingress Example

Demo using the Traefik ingress controller in AKS.

Assumptions:

  • Path based routing for a single domain (shouldn't be too hard to extend this sample to handle multiple domains)
  • Steps shown here are Azure-centric but Traefik works in any Kubernetes cluster
  • Tested in Bash on Ubuntu (WSL2 on Windows 10) -- some adjustments to commands may be needed for other platforms

Also shows:

  • TLS using Let's Encrypt certificates
  • Using BasicAuth middleware to protect a service

Steps

Create AKS cluster and ACR (optional)

Follow these steps to create an AKS cluster: https://docs.microsoft.com/en-us/azure/aks/kubernetes-walkthrough

TL;DR steps:

RESOURCE_GROUP=<myresourcegroup>
LOCATION=australiaeast
ACR_NAME=<myacrname>
CLUSTER_NAME=traefikdemo
AKS_VERSION=1.19.9
NODE_COUNT=3

az group create -n ${RESOURCE_GROUP} -l ${LOCATION}
az acr create -g ${RESOURCE_GROUP} -n ${ACR_NAME} --sku Basic
ACR_ID=$(az acr show -g ${RESOURCE_GROUP} -n ${ACR_NAME} --query id -o tsv)

az aks create \
  -g ${RESOURCE_GROUP} \
  -n ${CLUSTER_NAME} \
  -c ${NODE_COUNT} \
  -k ${AKS_VERSION} \
  --attach-acr ${ACR_ID} \
  -a monitoring \
  --generate-ssh-keys

sudo az aks install-cli # if you don't have `kubectl` installed
az aks get-credentials -g ${RESOURCE_GROUP} -n ${CLUSTER_NAME}

Install Traefik via Helm into the cluster

Install Helm

See: https://helm.sh/docs/intro/install/

curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh

Edit the field acme.email in the file traefik-values.yaml with a valid email address (or override the value with --set acme.email=your@email.com on the helm install commandline).

Now, install the Traefik Ingress chart:

helm repo add stable https://kubernetes-charts.storage.googleapis.com/
helm repo update
helm install traefik-ingress stable/traefik -n kube-system --values traefik-values.yaml
# Wait for the external IP to be assigned by watching the traefik service (CTRL+C to exit)
kubectl get svc traefik -n kube-system -w
# Wait for the traefik pod to be 'Running' (CTRL+C to exit)
kubectl get pod -n kube-system -w

If you want to update any of the values for Traefik, edit the file traefik-values.yaml and run a helm upgrade:

helm upgrade traefik-ingress stable/traefik -n kube-system --values traefik-values.yaml

See the Traefik helm chart configuration for explanation of options.

Set DNS name for the public IP of the Traefik controller:

Get the IP address of the traefik ingress controller service using kubectl get.

kubectl get svc traefik -n kube-system
# *** EXTERNAL IP  ***
# *** XXX.XX.XX.XX ***

Update the DNS name for the public IP of the Traefik ingress

# Public IP address
IP="<your_public_ip>"

# Name to associate with public IP address
DNSNAME=<unique-prefix-name> # e.g. traefik7242

# Get the resource-id of the public ip
PUBLICIPID=$(az network public-ip list --query "[?ipAddress!=null]|[?contains(ipAddress, '$IP')].[id]" --output tsv)

# Update public ip address with dns name
az network public-ip update --ids $PUBLICIPID --dns-name $DNSNAME

Deploy a sample app that uses Traefik ingress

Retrieve FQDN (<DNSNAME>.<LOCATION>.cloudapp.azure.com) mapped to the Ingress controller's public IP:

az network public-ip show --ids $PUBLICIPID --query dnsSettings.fqdn -o tsv
# DNSNAME.LOCATION.cloudapp.azure.com

Update the host field in the Ingress resource of azure-vote-app.yaml to match your Traefik public IP FQDN retrieve above:

  host: <DNSNAME>.<LOCATION>.cloudapp.azure.com

Now deploy the sample app resources:

kubectl create ns azure-vote
kubectl apply -f azure-vote-app.yaml -n azure-vote

Wait until all resources have been created:

kubectl get all -n azure-vote

Browse to: https://DNSNAME.LOCATION.cloudapp.azure.com

The TLS certificate should be valid in your browser.

Adding basic auth to the sample app

Create the basic auth secret:

sudo apt install apache2-utils  # Needed for htpasswd tool; otherwise install this another way
htpasswd -c auth myuser
kubectl create secret generic mysecret --from-file=auth -n azure-vote

Redeploy the sample app using basic auth:

Uncomment the following lines in the Ingress resource of azure-vote-app.yaml and apply the changes:

  annotations:
    kubernetes.io/ingress.class: traefik
    # ingress.kubernetes.io/auth-type: basic
    # ingress.kubernetes.io/auth-secret: mysecret

so that it looks like:

  annotations:
    kubernetes.io/ingress.class: traefik
    ingress.kubernetes.io/auth-type: basic
    ingress.kubernetes.io/auth-secret: mysecret
kubectl apply -f azure-vote-app.yaml -n azure-vote

Reloading the sample app in the browser should now prompt you for a username and password.

Troubleshooting

  • Ensure you updated the placeholder values in any input files
  • Ensure you use unique domain names
  • Ensure your email for LEt's encrypt is valid
  • For Traefik or Let's Encrypt issues, check the logs on your Traefik pod:
kubectl get pods -n kube-system
# traefik-847d6b54f9-x5btx
kubectl logs traefik-847d6b54f9-x5btx -n kube-system

Resources / Credits