Despliegues Canary con Traefik en Kubernetes

Publicado por Alejandro Font el

KubernetestraefikDevOps

En este segundo post sobre Traefik, montaremos un ejemplo de cómo realizar despliegues de tipo Canary con esta herramienta.

Para aquellos que no sepan en que consisten este tipo de despliegues, se trata de una forma de desplegar diferentes versiones de nuestro aplicativo asignando un peso determinado en la nueva versión, de forma que solo determinado trafico o un grupo reducido de usuarios hagan uso de la misma.

Mas info aquí:  https://martinfowler.com/bliki/CanaryRelease.html

Aunque lo podríamos hacer a base de aumentar las réplicas en una versión determinada, esa forma tan "manual" no es 100% fiable ya que requiere de un alto numero de réplicas para que estadísticamente funcione bien. En este punto veremos como Traefik nos puede ayudar a que esta tarea sea realmente fácil.

Instalación

Realicemos la instalación de Traefik tal y como vimos en el anterior post de la serie https://enmilocalfunciona.io/traefik-como-ingresscontroller-en-kubernetes:

helm install --name tr --values values.yaml stable/traefik  
values.yaml
dashboard:  
  enabled: true
  domain: traefik-ui.dashboard
rbac:  
  enabled: true
kubernetes:  
  namespaces:
   - default
   - kube-system    

Despliegue

Creamos dos versiones de una misma aplicación y las desplegamos.

Para ello haremos uso de la aplicación de prueba hello-node
que podéis encontrar en https://kubernetes.io/docs/tutorials/hello-minikube/.

Para poder identificar a cual de las dos aplicaciones se está invocando en cada una de las pruebas, podéis modificar el mensaje de salida.

A continuación ejecutamos el comando kubectl apply que nos actualiza el cluster de Kubernetes aplicando la configuración definida en el fichero pasado como parámetro:

kubectl apply -f canarytr.yaml  
canarytr.yaml
kind: Deployment  
apiVersion: extensions/v1beta1  
metadata:  
  name: hello-node
  labels:
    app: hello-node
spec:  
  replicas: 2
  selector:
    matchLabels:
      app: hello-node
  template:
    metadata:
      labels:
        app: hello-node
        version: v2
    spec:
      containers:
      - name: hello-node
        image: hello-node:v2
        ports:
        - containerPort: 8090
---
apiVersion: v1  
kind: Service  
metadata:  
  name: hello-node
spec:  
  ports:
  - name: http
    targetPort: 8090
    port: 80
  selector:
    app: hello-node


---
kind: Deployment  
apiVersion: extensions/v1beta1  
metadata:  
  name: hello-node3
  labels:
    app: hello-node3
spec:  
  replicas: 1
  selector:
    matchLabels:
      app: hello-node3
  template:
    metadata:
      labels:
        app: hello-node3
        version: v3
    spec:
      containers:
      - name: hello-node3
        image: hello-node:v3
        ports:
        - containerPort: 8090
---
apiVersion: v1  
kind: Service  
metadata:  
  name: hello-node3
spec:  
  ports:
  - name: http
    targetPort: 8090
    port: 80
  selector:
    app: hello-node3

En este fichero hemos definido que nos cree dos replicas de la versión 2 y una replica de la versión 3.

Aquí podemos ver nuestras dos versiones:

alt

Posteriormente creamos un ingress, donde especificamos que el 99% de las peticiones se dirigan a hello-node y el 1% a hello-node v3 y volvemos a aplicar la nueva configuración en nuestro cluster:

kubectl apply -f ingressCanarytr.yaml  
ingressCanarytr.yaml
apiVersion: extensions/v1beta1  
kind: Ingress  
metadata:  
  annotations:
    traefik.ingress.kubernetes.io/service-weights: |
      hello-node: 99%
      hello-node3: 1%
  name:  hello-node
spec:  
  rules:
  - host: hellonode.ejemplo
    http:
        paths:
        - backend:
            serviceName: hello-node
            servicePort: 80
          path: /
        - backend:
            serviceName: hello-node3
            servicePort: 80
          path: /
alt

Aunque podemos ir haciendo peticiones e ir viendo la salida y observar que generalmente nos responde la versión a la que le hemos asignado el 99%, lo ideal es hacer uso de alguna herramienta de monitorización para ver gráficamente como se resuelven nuestras peticiones.

Instalamos Prometheus y Grafana

En esta ocasión hemos elegido Prometheus y Grafana para monitorizar el tráfico. En el post Monitorización como Código con Grafana en Kubernetes tenéis información más extensa acerca de su instalación y configuración.

Pasamos a instalarlos con Helm, ejecutando:

helm install stable/prometheus-operator --name prometheus-operator --namespace monitor  

Tras invocar a nuestra aplicación un número significativo de veces, podemos ver de una forma más gráfica en nuestro dashboard de Grafana cómo se reparte nuestro tráfico o peticiones:

alt
alt

Conclusiones

Aquí damos por finalizada por ahora la serie de Traefik sobre Kubernetes.

Lógicamente, no hemos cubierto todo lo que da de si la herramienta, pero espero que sea útil para aquellas personas que la desconocían y sea un punto de introducción a la misma.

Autor

Alejandro Font

Oracle ACE y Líder Técnico de la Comunidad Oracle Fusion Middleware en knowmad mood. Actualmente con foco en Arquitecturas Ágiles y Contenedores