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.
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
Inicie sesión en Google Cloud, cree un proyecto y habilite la facturación. Instale la utilidad de línea de comando 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
brew install kubernetes-helm
Homebrew 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: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
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-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
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
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-system
habilitando 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.
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
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
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.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:
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:
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:
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
Señalador apoyado
Si tiene sugerencias para mejorar Flagger, envíe un problema o PR en GitHub en
Gracias
Fuente: habr.com