Implementaciones canary automáticas con Flagger e Istio

Implementaciones canary automáticas con Flagger e Istio

CD es reconocido como una práctica de software empresarial y es una evolución natural de los principios de CI establecidos. Sin embargo, el CD sigue siendo bastante raro, quizás debido a la complejidad de la gestión y al temor de que las implementaciones fallidas afecten la disponibilidad del sistema.

Flagger es un operador de Kubernetes de código abierto que tiene como objetivo eliminar relaciones confusas. Automatiza la promoción de implementaciones canary utilizando compensaciones de tráfico de Istio y métricas de Prometheus para analizar el comportamiento de las aplicaciones durante una implementación administrada.

A continuación se muestra una guía paso a paso para configurar y usar Flagger en Google Kubernetes Engine (GKE).

Configurar un clúster de Kubernetes

Comienza creando un clúster de GKE con el complemento Istio (si no tienes una cuenta de GCP, puedes registrarte aquí - para recibir créditos gratis).

Inicie sesión en Google Cloud, cree un proyecto y habilite la facturación. Instale la utilidad de línea de comando nube de gcloud y configura tu proyecto con gcloud init.

Establezca el proyecto, el área de cálculo y la zona predeterminados (reemplace PROJECT_ID para su proyecto):

gcloud config set project PROJECT_ID
gcloud config set compute/region us-central1
gcloud config set compute/zone us-central1-a

Habilite el servicio GKE y cree un clúster con complementos HPA e Istio:

gcloud services enable container.googleapis.com
K8S_VERSION=$(gcloud beta container get-server-config --format=json | jq -r '.validMasterVersions[0]')
gcloud beta container clusters create istio 
--cluster-version=${K8S_VERSION} 
--zone=us-central1-a 
--num-nodes=2 
--machine-type=n1-standard-2 
--disk-size=30 
--enable-autorepair 
--no-enable-cloud-logging 
--no-enable-cloud-monitoring 
--addons=HorizontalPodAutoscaling,Istio 
--istio-config=auth=MTLS_PERMISSIVE

El comando anterior creará un grupo de nodos predeterminado que consta de dos máquinas virtuales. n1-standard-2 (vCPU: 2, RAM 7,5 GB, disco: 30 GB). Idealmente, los componentes de Istio deberían estar aislados de sus cargas de trabajo, pero no existe una manera fácil de ejecutar pods de Istio en un grupo de nodos dedicado. Los manifiestos de Istio se consideran de solo lectura y GKE revertirá cualquier cambio, como vincularse a un nodo o desconectarse de un pod.

Configurar credenciales para kubectl:

gcloud container clusters get-credentials istio

Cree un enlace de rol de administrador de clúster:

kubectl create clusterrolebinding "cluster-admin-$(whoami)" 
--clusterrole=cluster-admin 
--user="$(gcloud config get-value core/account)"

Instalar la herramienta de línea de comando Casco:

brew install kubernetes-helm

Homebrew 2.0 ahora también está disponible para Linux.

Cree una cuenta de servicio y un enlace de rol de clúster para Tiller:

kubectl -n kube-system create sa tiller && 
kubectl create clusterrolebinding tiller-cluster-rule 
--clusterrole=cluster-admin 
--serviceaccount=kube-system:tiller

Expandir Tiller en el espacio de nombres kube-system:

helm init --service-account tiller

Debería considerar el uso de SSL entre Helm y Tiller. Para obtener más información sobre cómo proteger su instalación de Helm, consulte docs.helm.sh

Confirmar configuración:

kubectl -n istio-system get svc

Después de unos segundos, GCP debería asignar una dirección IP externa al servicio. istio-ingressgateway.

Configurar una puerta de enlace de Istio Ingress

Crea una dirección IP estática con el nombre istio-gatewayutilizando la dirección IP de la puerta de enlace de Istio:

export GATEWAY_IP=$(kubectl -n istio-system get svc/istio-ingressgateway -ojson | jq -r .status.loadBalancer.ingress[0].ip)
gcloud compute addresses create istio-gateway --addresses ${GATEWAY_IP} --region us-central1

Ahora necesita un dominio de Internet y acceso a su registrador DNS. Agregue dos registros A (reemplace example.com a tu dominio):

istio.example.com   A ${GATEWAY_IP}
*.istio.example.com A ${GATEWAY_IP}

Verifique que el comodín DNS esté funcionando:

watch host test.istio.example.com

Cree una puerta de enlace Istio genérica para proporcionar servicios fuera de la malla de servicios a través de HTTP:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: public-gateway
  namespace: istio-system
spec:
  selector:
    istio: ingressgateway
  servers:
    - port:
        number: 80
        name: http
        protocol: HTTP
      hosts:
        - "*"

Guarde el recurso anterior como public-gateway.yaml y luego aplíquelo:

kubectl apply -f ./public-gateway.yaml

Ningún sistema de producción debería proporcionar servicios en Internet sin SSL. Para proteger su puerta de enlace de ingreso de Istio con cert-manager, CloudDNS y Let's Encrypt, lea documentación Abanderado G.K.E.

Instalación de abanderados

El complemento GKE Istio no incluye la instancia de Prometheus que limpia el servicio de telemetría de Istio. Dado que Flagger utiliza métricas HTTP de Istio para realizar análisis canary, debe implementar la siguiente configuración de Prometheus, similar a la que viene con el esquema oficial de Istio Helm.

REPO=https://raw.githubusercontent.com/stefanprodan/flagger/master
kubectl apply -f ${REPO}/artifacts/gke/istio-prometheus.yaml

Agregue el repositorio Flagger Helm:

helm repo add flagger [https://flagger.app](https://flagger.app/)

Expandir Flagger al espacio de nombres istio-systemhabilitando las notificaciones de Slack:

helm upgrade -i flagger flagger/flagger 
--namespace=istio-system 
--set metricsServer=http://prometheus.istio-system:9090 
--set slack.url=https://hooks.slack.com/services/YOUR-WEBHOOK-ID 
--set slack.channel=general 
--set slack.user=flagger

Puede instalar Flagger en cualquier espacio de nombres siempre que pueda comunicarse con el servicio Istio Prometheus en el puerto 9090.

Flagger tiene un panel de Grafana para análisis canario. Instale Grafana en el espacio de nombres istio-system:

helm upgrade -i flagger-grafana flagger/grafana 
--namespace=istio-system 
--set url=http://prometheus.istio-system:9090 
--set user=admin 
--set password=change-me

Exponga Grafana a través de una puerta de enlace abierta mediante la creación de un servicio virtual (reemplace example.com a tu dominio):

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: grafana
  namespace: istio-system
spec:
  hosts:
    - "grafana.istio.example.com"
  gateways:
    - public-gateway.istio-system.svc.cluster.local
  http:
    - route:
        - destination:
            host: flagger-grafana

Guarde el recurso anterior como grafana-virtual-service.yaml y luego aplíquelo:

kubectl apply -f ./grafana-virtual-service.yaml

cuando va a http://grafana.istio.example.com Su navegador debería redirigirlo a la página de inicio de sesión de Grafana.

Implementación de aplicaciones web con Flagger

Flagger implementa Kubernetes y, si es necesario, escalado automático horizontal (HPA), luego crea una serie de objetos (implementaciones de Kubernetes, servicios ClusterIP y servicios virtuales de Istio). Estos objetos exponen la aplicación a la malla de servicios y gestionan el análisis y la promoción canary.

Implementaciones canary automáticas con Flagger e Istio

Cree un espacio de nombres de prueba con la implementación de Istio Sidecar habilitada:

REPO=https://raw.githubusercontent.com/stefanprodan/flagger/master
kubectl apply -f ${REPO}/artifacts/namespaces/test.yaml

Cree una implementación y una herramienta de escalado horizontal automático para el pod:

kubectl apply -f ${REPO}/artifacts/canaries/deployment.yaml
kubectl apply -f ${REPO}/artifacts/canaries/hpa.yaml

Implemente un servicio de prueba de carga para generar tráfico durante el análisis canario:

helm upgrade -i flagger-loadtester flagger/loadtester 
--namepace=test

Cree un recurso canario personalizado (reemplace example.com a tu dominio):

apiVersion: flagger.app/v1alpha3
kind: Canary
metadata:
  name: podinfo
  namespace: test
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: podinfo
  progressDeadlineSeconds: 60
  autoscalerRef:
    apiVersion: autoscaling/v2beta1
    kind: HorizontalPodAutoscaler
    name: podinfo
  service:
    port: 9898
    gateways:
    - public-gateway.istio-system.svc.cluster.local
    hosts:
    - app.istio.example.com
  canaryAnalysis:
    interval: 30s
    threshold: 10
    maxWeight: 50
    stepWeight: 5
    metrics:
    - name: istio_requests_total
      threshold: 99
      interval: 30s
    - name: istio_request_duration_seconds_bucket
      threshold: 500
      interval: 30s
    webhooks:
      - name: load-test
        url: http://flagger-loadtester.test/
        timeout: 5s
        metadata:
          cmd: "hey -z 1m -q 10 -c 2 http://podinfo.test:9898/"

Guarde el recurso anterior como podinfo-canary.yaml y luego aplíquelo:

kubectl apply -f ./podinfo-canary.yaml

El análisis anterior, si tiene éxito, se ejecutará durante cinco minutos y comprobará las métricas HTTP cada medio minuto. Puede determinar el tiempo mínimo necesario para probar y promover una implementación canary mediante la siguiente fórmula: interval * (maxWeight / stepWeight). Los campos CRD canarios están documentados aquí.

Después de un par de segundos, Flagger creará objetos canary:

# applied 
deployment.apps/podinfo
horizontalpodautoscaler.autoscaling/podinfo
canary.flagger.app/podinfo
# generated 
deployment.apps/podinfo-primary
horizontalpodautoscaler.autoscaling/podinfo-primary
service/podinfo
service/podinfo-canary
service/podinfo-primary
virtualservice.networking.istio.io/podinfo

Abra su navegador y vaya a app.istio.example.com, deberías ver el número de versión aplicaciones de demostración.

Análisis y promoción automática de canarios.

Flagger implementa un bucle de control que mueve gradualmente el tráfico al canario mientras mide indicadores clave de rendimiento, como la tasa de éxito de las solicitudes HTTP, la duración promedio de las solicitudes y el estado del pod. Según el análisis de KPI, el canario se promociona o se cancela y los resultados del análisis se publican en Slack.

Implementaciones canary automáticas con Flagger e Istio

La implementación canary se activa cuando uno de los siguientes objetos cambia:

  • Implementar PodSpec (imagen de contenedor, comando, puertos, entorno, etc.)
  • Los ConfigMaps se montan como volúmenes o se convierten en variables de entorno.
  • Los secretos se montan como volúmenes o se convierten en variables de entorno.

Ejecute la implementación canary al actualizar la imagen del contenedor:

kubectl -n test set image deployment/podinfo 
podinfod=quay.io/stefanprodan/podinfo:1.4.1

Flagger detecta que la versión de implementación ha cambiado y comienza a analizarla:

kubectl -n test describe canary/podinfo

Events:

New revision detected podinfo.test
Scaling up podinfo.test
Waiting for podinfo.test rollout to finish: 0 of 1 updated replicas are available
Advance podinfo.test canary weight 5
Advance podinfo.test canary weight 10
Advance podinfo.test canary weight 15
Advance podinfo.test canary weight 20
Advance podinfo.test canary weight 25
Advance podinfo.test canary weight 30
Advance podinfo.test canary weight 35
Advance podinfo.test canary weight 40
Advance podinfo.test canary weight 45
Advance podinfo.test canary weight 50
Copying podinfo.test template spec to podinfo-primary.test
Waiting for podinfo-primary.test rollout to finish: 1 of 2 updated replicas are available
Promotion completed! Scaling down podinfo.test

Durante el análisis, los resultados canary se pueden monitorear usando Grafana:

Implementaciones canary automáticas con Flagger e Istio

Tenga en cuenta: si se aplican nuevos cambios a la implementación durante el análisis canario, Flagger reiniciará la fase de análisis.

Haga una lista de todos los canarios en su clúster:

watch kubectl get canaries --all-namespaces
NAMESPACE   NAME      STATUS        WEIGHT   LASTTRANSITIONTIME
test        podinfo   Progressing   15       2019-01-16T14:05:07Z
prod        frontend  Succeeded     0        2019-01-15T16:15:07Z
prod        backend   Failed        0        2019-01-14T17:05:07Z

Si ha habilitado las notificaciones de Slack, recibirá los siguientes mensajes:

Implementaciones canary automáticas con Flagger e Istio

Reversión automática

Durante el análisis canary, puede generar errores HTTP 500 sintéticos y una alta latencia de respuesta para verificar si Flagger detendrá la implementación.

Cree un módulo de prueba y haga lo siguiente en él:

kubectl -n test run tester 
--image=quay.io/stefanprodan/podinfo:1.2.1 
-- ./podinfo --port=9898
kubectl -n test exec -it tester-xx-xx sh

Generando errores HTTP 500:

watch curl http://podinfo-canary:9898/status/500

Generación de retraso:

watch curl http://podinfo-canary:9898/delay/1

Cuando la cantidad de comprobaciones fallidas alcanza un umbral, el tráfico se enruta de regreso al canal principal, el valor canario se escala a cero y la implementación se marca como fallida.

Los errores canary y los picos de latencia se registran como eventos de Kubernetes y Flagger los registra en formato JSON:

kubectl -n istio-system logs deployment/flagger -f | jq .msg

Starting canary deployment for podinfo.test
Advance podinfo.test canary weight 5
Advance podinfo.test canary weight 10
Advance podinfo.test canary weight 15
Halt podinfo.test advancement success rate 69.17% < 99%
Halt podinfo.test advancement success rate 61.39% < 99%
Halt podinfo.test advancement success rate 55.06% < 99%
Halt podinfo.test advancement success rate 47.00% < 99%
Halt podinfo.test advancement success rate 37.00% < 99%
Halt podinfo.test advancement request duration 1.515s > 500ms
Halt podinfo.test advancement request duration 1.600s > 500ms
Halt podinfo.test advancement request duration 1.915s > 500ms
Halt podinfo.test advancement request duration 2.050s > 500ms
Halt podinfo.test advancement request duration 2.515s > 500ms
Rolling back podinfo.test failed checks threshold reached 10
Canary failed! Scaling down podinfo.test

Si ha habilitado las notificaciones de Slack, recibirá un mensaje cuando se supere la fecha límite para completar o alcanzar el número máximo de revisiones fallidas en un análisis:

Implementaciones canary automáticas con Flagger e Istio

en conclusión

Ejecutar una malla de servicios como Istio sobre Kubernetes proporcionará métricas, registros y registros automáticos, pero la implementación de cargas de trabajo aún depende de herramientas externas. Flagger pretende cambiar esto añadiendo capacidades de Istio entrega progresiva.

Flagger es compatible con cualquier solución CI/CD para Kubernetes y el análisis canary se puede ampliar fácilmente con ganchos web para realizar pruebas de integración/aceptación del sistema, pruebas de carga o cualquier otra prueba personalizada. Debido a que Flagger es declarativo y responde a eventos de Kubernetes, se puede usar en canalizaciones de GitOps junto con Flujo de tejido o JenkinsX. Si está utilizando JenkinsX, puede instalar Flagger con complementos jx.

Señalador apoyado Tejidos y proporciona implementaciones canary en tejer nube. El proyecto se prueba en GKE, EKS y bare metal con kubeadm.

Si tiene sugerencias para mejorar Flagger, envíe un problema o PR en GitHub en stefanprodan/flagger. ¡Las contribuciones son más que bienvenidas!

Gracias Ray Tsang.

Fuente: habr.com

Añadir un comentario