Blog

Proxying av Kubernetes-tjänster med Traefik

MAR 30, 2017

En inblick i den nya världen av tjänsteupptäckt

Henrik Hoegh

Henrik is a DevOps Consultant based in Aarhus. He specializes in Docker, Kubernetes and everything Atlassian. Away from the office Henrik designs loudspeakers and takes a keen interest in quantum physics and astrophotography.

Så proxyar du en tjänst som körs i Kubernetes via Traefik som load balancer och proxy.

Proxya Kubernetes-tjänster

I vårt senaste blogginlägg om Traefik visade vi hur enkelt det är att proxya Docker-containrar som körs på en värd. Den här gången visar vi hur enkelt det är att proxya containrar från ett Kubernetes-kluster via Traefik.

Traefik är en reverse proxy skapad för den nya världen av tjänsteupptäckt och är särskilt användbar när du kör tjänster i Kubernetes.

I det här blogginlägget tittar vi på hur du kan proxya en tjänst som körs i Kubernetes via Traefik som load balancer och proxy.

Vi driftsätter en tjänst i Kubernetes och får åtkomst till den via Traefik med ett DNS-namn. Vi skapar en ingress-regel i Kubernetes för att definiera routningen. Traefik läser sedan in regeln och konfigurerar sig automatiskt.

Förutsättningar

Du behöver ett Kubernetes-kluster som körs och en maskin där load balancern ska köras. Maskinen som kör Traefik måste ha routes konfigurerade för att kunna nå pods via deras ClusterIP. Det ligger utanför den här artikelns omfattning, men här är ett tips:

K8S_NODES=$(kubectl get nodes | grep "Ready" | cut -d" " -f1 | tr '\n' '\t')for node in $K8S_NODES; do  NODE_IP=$(kubectl describe node $node \            | egrep -w "Addresses"      \            | tr '\n' '\t'              \            | cut -d"," -f1             \            | rev                       \            | cut -d$'\t' -f1           \            | rev)  kubectl describe node ${node}  \            | egrep -w "Name:|PodCIDR"  \            | tr '\n' '\t'              \            | awk -v IP=$NODE_IP '{ print "sudo route add -net " , $4 , " gw " , IP }'done

Om du lägger till fler worker-noder behöver du även lägga till nya routes för dem.

Exemplet ovan förutsätter att du använder CNI-nätverk. Det fungerar inte med overlay-nätverk. I så fall måste maskinen som kör load balancern vara ansluten till samma overlay-nätverk.

Driftsätt en deployment, tjänst och ingress i Kubernetes

Driftsätt en NGINX-deployment i Kubernetes

Först skapar vi en deployment för NGINX så att vi senare kan uppdatera och skala den samt hålla den igång.

Skapa en fil med namnet nginx-deployment.yaml med följande innehåll

apiVersion: extensions/v1beta1kind: Deploymentmetadata:  name: nginx-deploymentspec:  replicas: 3  template:    metadata:      labels:        app: nginx    spec:      containers:      - name: nginx        image: nginx:1.7.9        ports:        - containerPort: 8

YAML-filen ovan ger oss en deployment, ett replica set och 3 pods som kör nginx 1.7.9 när vi kör följande

> kubectl create -f nginx-deployment.yaml deployment "nginx-deployment" created

Kontrollera deploymenten

> kubectl get deployments NAME              DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE nginx-deployment  3        3        3           0          4s

Efter en stund bör ”AVAILABLE=0” ändras till 3, och då är du redo att fortsätta.

Kontrollera nu att poddarna är igång.

> kubectl get podsNAME                                READY     STATUS    RESTARTS   AGEnginx-deployment-4087004473-clz6x   1/1       Running   0          3mnginx-deployment-4087004473-jwz0k   1/1       Running   0          3mnginx-deployment-4087004473-zfkzn   1/1       Running   0          3m

Driftsätt en NGINX-tjänst i Kubernetes

Nu behöver vi skapa en tjänst – ett objekt i Kubernetes som har en fast IP-adress och Cluster DNS för vår deployment.

Skapa en fil med namnet nginx-service.yaml med följande innehåll

apiVersion: v1kind: Servicemetadata:  labels:    name: nginxservice  name: nginxservicespec:  ports:    # The port that this service should serve on.    - port: 80  # Label keys and values that must match in order to receive traffic for this service.  selector:    app: nginx  type: ClusterIP

Detta skapar ett tjänsteobjekt i Kubernetes med en ClusterIP och endpoint-IP-adresser till våra pods. Om en pod avslutas startas en ny och tjänstens endpoint uppdateras.

Skapa tjänsten genom att köra

> kubectl create -f nginx-service.yaml service "nginxservice" created

Kontrollera tjänsten genom att köra

> kubectl get servicesNAME            CLUSTER-IP    EXTERNAL-IP   PORT(S)          AGEkubernetes      10.32.0.1     <none>        443/TCP          3dnginxservice    10.32.0.102   <none>        80/TCP           1m

Här ser vi att ClusterIP för vår nya tjänst är 10.32.0.102.

Driftsätt en ingress i Kubernetes

Hittills har vi använt Kubernetes på samma sätt som vi gjorde innan ingress-objektet introducerades.

Nu definierar vi vår routningsregel från omvärlden till vår NGINX-tjänst genom att skapa filen nginx-ingress.yaml med följande YAML

apiVersion: extensions/v1beta1kind: Ingressmetadata:  name: nginxingressspec:  rules:  - host: nginx.example.com    http:      paths:      - path: /        backend:          serviceName: nginxservice          servicePort: 80

Skapa ingressen genom att köra

> kubectl create -f nginx-ingress.yaml ingress "nginxingress" created

Installera Traefik

Nu är vårt kluster redo. Vi behöver bara installera och konfigurera Traefik samt lägga till en post i vår hosts-fil.

Ladda ner binärfilen

Gå till GitHub och ladda ner den senaste stabila versionen av Traefik för din arkitektur, och gör den körbar. I skrivande stund är versionen 1.1.2.

https://github.com/containous/traefik/releases/latest

wget https://github.com/containous/traefik/releases/download/v1.1.2/traefik_linux-amd64 mv traefik_linux-amd64 traefik chmod u+x traefik </code>

Skapa en konfigurationsfil

Skapa en fil som heter traefik.toml i samma mapp som traefik, med följande innehåll

[web] address = ":8080" ReadOnly = true [kubernetes] # Kubernetes server endpoint endpoint = "http://controller.example.com:8080" namespaces = ["default","kube-system"]

Konfigurationen ovan instruerar Traefik att endast leverera innehåll från de två namnrymderna ”default” och ”kube-system”. Om du vill att Traefik ska leverera innehåll från alla namnrymder tar du bara bort raden.

Avsnittet [web] instruerar traefik att tillhandahålla en dashboard på port 8080. Det är praktiskt och visar alla tjänster som traefik för närvarande tillhandahåller.

Avsnittet [kubernetes] beskriver hur traefik ska ansluta till din Kubernetes kube-apiserver. I det här exemplet lyssnar kube-apiserver på port 8080 på controller.example.com. Om du använder SSL (och lyssnar på port 8443) kan du definiera certifikat och token i dessa två filer:

/var/run/secrets/kubernetes.io/serviceaccount/ca.crt/var/run/secrets/kubernetes.io/serviceaccount/token

Även om du inte använder någon token eller något certifikat behöver du dessa två filer. I så fall skapar du bara de två filerna utan innehåll.

Starta Traefik

Starta nu Traefik manuellt

./traefik -c traefik.toml

eller använd detta som mall om du vill att Traefik ska köras som en tjänst

\
[Unit] Description=Traefik proxy server Documentation=https://github.com/containous/traefik [Service] ExecStart=/root/traefik/traefik \  -c /root/traefik/traefik.toml Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target </code>

Lägg till DNS i vår hosts-fil

I vårt ingress-objekt definierade vi att vår nginx-tjänst ska vara åtkomlig via DNS-namnet nginx.example.com. Eftersom jag inte har någon DNS-server skapar jag helt enkelt en post i min hosts-fil

Ersätt [load-balancer-ip] med IP-adressen till maskinen som kör Traefik.

su -c 'echo "[load-balancer-ip] nginx.example.com" &gt;&gt; /etc/hosts'

Testa vår tjänst

Gå först till Traefiks dashboard och kontrollera att nginx-tjänsten finns med på http://[localbalancer-ip]:8080. Du bör se dashboarden samt nginx frontend och backend. Frontend beskriver regeln och backend våra poddar.

Traefik Nginx

Öppna nu en ny flik i webbläsaren och gå till http://nginx.example.com. Du bör då se nginxs startsida, som levereras via HTTP.

nginx

Dina förfrågningar lastbalanseras mellan de tre nginx-poddarna som körs i vårt Kubernetes-kluster. Prova att avsluta en av dem och se att du fortfarande kan trycka på F5 hur många gånger du vill. Traefik upptäcker det och konfigurerar om. När en ny podd startar och ersätter den avslutade kommer även den automatiskt att hanteras av Traefik. Service discovery när det är som bäst.

Lägg till SSL och omdirigering från http till https

Exemplet ovan fungerar bra, men är inte användbart i produktion eftersom det bara hanterar http-förfrågningar. Vi vill använda SSL över https. Låt oss se hur enkelt det är.

Redigera vår traefik.toml så att den innehåller en omdirigering från http till https och våra certifikat, så här:

defaultEntryPoints = ["http", "https"][entryPoints][entryPoints.http]  address = ":80"[entryPoints.http.redirect]  entryPoint = "https"[entryPoints.https]  address = ":443"[entryPoints.https.tls][[entryPoints.https.tls.certificates]]CertFile = "/certs/kubernetes.pem"KeyFile = "/certs/kubernetes-key.pem"[web]address = ":8080"ReadOnly = true[kubernetes]# Kubernetes server endpointendpoint = "http://controller.example.com:8080"namespaces = ["default","kube-system"]

Vi har lagt till två standard-entry points (http och https). I avsnittet för entry points konfigurerar vi en omdirigering från http till https, från port 80 till 433.

Sedan har vi ett avsnitt för certifikat där vi definierar vårt certifikat och vår nyckelfil. Klart.

Starta nu om Traefik, antingen genom att trycka på ctrl + c och köra det igen, eller genom att stoppa tjänsten och starta om den.

Om Traefik inte körs som en tjänst

ctrl + c ./traefik -c traefik.toml

Om Traefik körs som en tjänst

sudo service traefik stop sudo service traefik start

Öppna nu http://nginx.example.com i en webbläsare och se att du omdirigeras till https.

Om du använder självsignerade certifikat kommer webbläsaren att varna dig. Lägg bara till ett undantag och fortsätt.

Och voilà: nginx hanteras från ett Kubernetes-kluster med https, med endast 20 rader statisk konfiguration och service discovery.

Nginx not safe
  • Cloud

Subscribe to our newsletter