
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.
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 - 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 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-aHabilite 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_PERMISSIVEEl 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 istioCree 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 :
brew install kubernetes-helmHomebrew 2.0 ahora también está disponible para .
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:tillerExpandir Tiller en el espacio de nombres kube-system:
helm init --service-account tillerDeberí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
Confirmar configuración:
kubectl -n istio-system get svcDespué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-central1Ahora 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.comCree 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.yamlNingú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 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.yamlAgregue 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=flaggerPuede 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-meExponga 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-grafanaGuarde el recurso anterior como grafana-virtual-service.yaml y luego aplíquelo:
kubectl apply -f ./grafana-virtual-service.yamlcuando 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.
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.yamlCree 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.yamlImplemente un servicio de prueba de carga para generar tráfico durante el análisis canario:
helm upgrade -i flagger-loadtester flagger/loadtester
--namepace=testCree 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.yamlEl 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 .
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/podinfoAbra su navegador y vaya a app.istio.example.com, deberías ver el número de versió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.
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.1Flagger 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.testDurante el análisis, los resultados canary se pueden monitorear usando Grafana:
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:07ZSi ha habilitado las notificaciones de Slack, recibirá los siguientes mensajes:
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 shGenerando errores HTTP 500:
watch curl http://podinfo-canary:9898/status/500Generación de retraso:
watch curl http://podinfo-canary:9898/delay/1Cuando 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.testSi 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:
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 .
Flagger es compatible con cualquier solución CI/CD para Kubernetes y el análisis canary se puede ampliar fácilmente con 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 o . Si está utilizando JenkinsX, puede instalar Flagger con complementos jx.
Señalador apoyado y proporciona implementaciones canary en . 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 . ¡Las contribuciones son más que bienvenidas!
Gracias .
Fuente: habr.com
