Despliegues automáticos canary con Flagger e Istio

Despliegues automáticos canary con Flagger e Istio

CD se ha reconocido como una práctica de software corporativo, resultado de la evolución natural de los principios establecidos de CI. Sin embargo, CD sigue siendo un fenómeno relativamente raro, posiblemente debido a la complejidad de la gestión y al miedo a implementaciones fallidas que afectan la disponibilidad del sistema.

Flagger es un operador de Kubernetes de código abierto cuyo objetivo es eliminar relaciones confusas. Automatiza la promoción de implementaciones canarias utilizando el desvío de tráfico de Istio y métricas de Prometheus para analizar el comportamiento de la aplicación durante un lanzamiento controlado.

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

Configuración del clúster de Kubernetes

Comience creando un clúster de GKE con la extensión de Istio (si no tiene una cuenta de GCP, puede registrarse aquí para obtener créditos gratuitos).

Inicie sesión en Google Cloud, cree un proyecto y habilite la facturación para él. Instale la herramienta de línea de comandos gcloud y configure su proyecto usando gcloud init.

Establezca el proyecto predeterminado, la región de cómputo y la zona (reemplazando PROJECT_ID por 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 HPA y extensiones de 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 pool de nodos por defecto que incluirá dos VM n1-standard-2 (vCPU: 2, RAM 7,5 GB, disco: 30 GB). Idealmente, se deberían aislar los componentes de Istio de sus cargas de trabajo, pero no existe una manera sencilla de ejecutar pods de Istio en un pool de nodos dedicados. Los manifiestos de Istio se consideran de solo lectura, y GKE revertirá cualquier cambio, como el enlace a un nodo o la desconexión de un pod.

Configure las 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)"

Instale la herramienta de línea de comandos Helm:

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

Despliegue Tiller en el namespace kube-system:

helm init --service-account tiller

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

Confirme la 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.

Configuración de la puerta de enlace de entrada de Istio

Cree una dirección IP estática llamada istio-gateway, utilizando 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 con su dominio):

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

Verifique que el comodín DNS funcione:

watch host test.istio.example.com

Cree una puerta de enlace pública de Istio para ofrecer servicios fuera de la malla de servicio 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 debe ofrecer servicios en línea sin SSL. Para proteger la puerta de enlace de entrada de Istio con cert-manager, CloudDNS y Let’s Encrypt, consulte la documentación Flagger GKE.

Instalación de Flagger

La capa de GKE Istio no incluye una instancia de Prometheus que se encargue de la limpieza del servicio de telemetría de Istio. Dado que Flagger utiliza métricas HTTP de Istio para realizar análisis canarios, debe desplegar la siguiente configuración de Prometheus, similar a la que se proporciona 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/)

Despliegue Flagger en el namespace istio-system, habilitando 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 namespace si puede interactuar con el servicio de Istio Prometheus a través del puerto 9090.

Flagger tiene un panel de monitoreo Grafana para análisis canarios. Instale Grafana en el namespace. 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

Exponha Grafana através do gateway público, criando um serviço virtual (substitua example.com pelo seu domínio):

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

Salve o recurso acima como grafana-virtual-service.yaml e, em seguida, aplique-o:

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

Ao acessar http://grafana.istio.example.com no navegador, você deve ser direcionado para a página de login do Grafana.

Implantação de Aplicativos Web com Flagger

Flagger implanta Kubernetes e, se necessário, escalonamento automático horizontal (HPA), em seguida, cria uma série de objetos (implantações do Kubernetes, serviços ClusterIP e serviços virtuais Istio). Esses objetos expõem o aplicativo na service mesh e gerenciam a análise e promoção do canary.

Despliegues automáticos canary con Flagger e Istio

Crie um namespace de teste com a injeção do Istio Sidecar habilitada:

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

Crie uma implantação e uma ferramenta de escalonamento automático horizontal de pod:

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

Implante um serviço de carga de teste para gerar tráfego durante a análise canary:

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

Crie um recurso canary personalizado (substitua example.com con su 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/"

Salve o recurso acima como podinfo-canary.yaml e, em seguida, aplique-o:

kubectl apply -f ./podinfo-canary.yaml

A análise acima, em caso de sucesso, será realizada por cinco minutos, verificando as métricas HTTP a cada meia hora. Você pode determinar o tempo mínimo necessário para verificar e promover a implantação canary pela seguinte fórmula: interval * (maxWeight / stepWeight). Os campos do Canary CRD são documentados aquí.

Depois de alguns segundos, o Flagger criará os 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

Abre tu navegador y ve a app.istio.example.com, deberías ver el número de versión de la aplicación de demostración.

Análisis y promoción canary automáticos

Flagger implementa un ciclo de control que gradualmente mueve el tráfico hacia la versión canary, mientras mide indicadores clave de rendimiento, como la tasa de éxito de las solicitudes HTTP, la duración promedio de las solicitudes y la disponibilidad del pod. Según el análisis de los KPI, la versión canary se promueve o se detiene, y los resultados del análisis se publican en Slack.

Despliegues automáticos canary con Flagger e Istio

El despliegue canary se inicia cuando se actualiza uno de los siguientes objetos:

  • El PodSpec de despliegue (imagen del contenedor, comando, puertos, env, etc.)
  • ConfigMaps montados como volúmenes o transformados en variables de entorno
  • Secretos montados como volúmenes o transformados en variables de entorno

Inicio del despliegue 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 se ha cambiado la versión del despliegue y comienza a analizarla:

kubectl -n test describe canary/podinfo

Eventos:

Nueva revisión detectada podinfo.test
Aumentando podinfo.test
Esperando que termine el despliegue de podinfo.test: 0 de 1 réplicas actualizadas están disponibles
Aumentar peso canary de podinfo.test 5
Aumentar peso canary de podinfo.test 10
Aumentar peso canary de podinfo.test 15
Aumentar peso canary de podinfo.test 20
Aumentar peso canary de podinfo.test 25
Aumentar peso canary de podinfo.test 30
Aumentar peso canary de podinfo.test 35
Aumentar peso canary de podinfo.test 40
Aumentar peso canary de podinfo.test 45
Aumentar peso canary de podinfo.test 50
Copiando la especificación de plantilla de podinfo.test a podinfo-primary.test
Esperando que termine el despliegue de podinfo-primary.test: 1 de 2 réplicas actualizadas están disponibles
¡Promoción completada! Reducción de podinfo.test

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

Despliegues automáticos canary con Flagger e Istio

Ten en cuenta: si se aplican nuevos cambios al despliegue durante el análisis canary, Flagger reiniciará la fase de análisis.

Haz una lista de todos los ‘canarios’ en tu 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 has habilitado las notificaciones de Slack, recibirás los siguientes mensajes:

Despliegues automáticos canary con Flagger e Istio

Rollback automático

Durante el análisis canary, se pueden generar errores sintéticos HTTP 500 y alta latencia de respuesta para verificar que Flagger no detenga el despliegue.

Crea un pod de prueba y realiza la siguiente acción 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

Generación de errores HTTP 500:

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

Generación de latencia:

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

Cuando el número de verificaciones fallidas alcanza el umbral, el tráfico se redirige de vuelta al canal primario, el canario se escala a cero y el despliegue se marca como fallido.

Los errores de canario y los picos de retraso se registran como eventos de Kubernetes y se registran en Flagger en formato JSON:

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

Iniciando el despliegue canario para podinfo.test
Aumentar el peso canario de podinfo.test 5
Aumentar el peso canario de podinfo.test 10
Aumentar el peso canario de podinfo.test 15
Detener el avance de podinfo.test tasa de éxito 69.17% < 99%
Detener el avance de podinfo.test tasa de éxito 61.39% < 99%
Detener el avance de podinfo.test tasa de éxito 55.06% < 99%
Detener el avance de podinfo.test tasa de éxito 47.00% < 99%
Detener el avance de podinfo.test tasa de éxito 37.00%  500ms
Detener el avance de podinfo.test duración de la solicitud 1.600s > 500ms
Detener el avance de podinfo.test duración de la solicitud 1.915s > 500ms
Detener el avance de podinfo.test duración de la solicitud 2.050s > 500ms
Detener el avance de podinfo.test duración de la solicitud 2.515s > 500ms
Revertir podinfo.test umbral de verificaciones fallidas alcanzado 10
¡Canario fallido! Reducción de podinfo.test

Si has habilitado las notificaciones de Slack, recibirás un mensaje cuando se supere el plazo de ejecución o se alcance el número máximo de verificaciones fallidas durante el análisis:

Despliegues automáticos canary con Flagger e Istio

En conclusión

Implementar una malla de servicios, como Istio, además de Kubernetes, proporcionará métricas automáticas, registros y protocolos, pero el despliegue de cargas de trabajo todavía depende de herramientas externas. Flagger busca cambiar esta situación añadiendo capabilities de Istio entrega progresiva.

Flagger es compatible con cualquier solución CI/CD para Kubernetes, y el análisis canario se puede ampliar fácilmente con webhooks para realizar pruebas de integración/aceptación del sistema, pruebas de carga o cualquier otra verificación personalizada. Dado que Flagger es declarativo y responde a eventos de Kubernetes, se puede utilizar en canalizaciones GitOps junto con Weave Flux o JenkinsX. Si utilizas JenkinsX, puedes instalar Flagger con los plugins de jx.

Flagger es apoyado por Weaveworks y proporciona despliegues canarios en Weave Cloud. El proyecto se prueba en GKE, EKS y en "bare metal" con kubeadm.

Si tienes sugerencias para mejorar Flagger, por favor envía una pregunta o PR en GitHub a stefanprodan/flagger. ¡Las contribuciones son más que bienvenidas!

Gracias Rey Tsan.

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster