Implantações canary automáticas com Flagger e Istio

Implantações canary automáticas com Flagger e Istio

CD é reconhecido como uma prática de software corporativo, resultado da evolução natural dos princípios estabelecidos de CI. No entanto, o CD ainda é um fenômeno relativamente raro, possivelmente devido à complexidade de gerenciamento e ao medo de implantações malsucedidas que afetam a disponibilidade do sistema.

Flagger é um operador Kubernetes de código aberto, cujo objetivo é eliminar dependências complicadas. Ele automatiza a promoção de implantações canário usando a divisão de tráfego do Istio e métricas do Prometheus para analisar o comportamento do aplicativo durante um rollout controlado.

Abaixo está um guia passo a passo sobre como configurar e usar o Flagger no Google Kubernetes Engine (GKE).

Configuração do cluster Kubernetes

Você começa criando um cluster GKE com o Istio habilitado (se não tiver uma conta GCP, você pode se registrar aqui para obter créditos gratuitos).

Entre no Google Cloud, crie um projeto e ative a faturação para ele. Instale a ferramenta de linha de comando gcloud e configure seu projeto com gcloud init.

Defina o projeto padrão, a região computacional e a zona (substitua PROJECT_ID pelo seu projeto):

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

Ative o serviço GKE e crie um cluster com HPA e complementos do 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

O comando acima criará um pool de nós por padrão, incluindo duas VMs n1-standard-2 (vCPU: 2, RAM 7,5 GB, disco: 30 GB). Idealmente, os componentes do Istio devem ser isolados de suas cargas de trabalho, mas não há uma maneira simples de executar pods do Istio em um pool de nós dedicado. Os manifests do Istio são considerados somente leitura, e o GKE irá reverter quaisquer alterações, como a vinculação a um nó ou a desconexão de um pod.

Configure as credenciais para kubectl:

gcloud container clusters get-credentials istio

Crie uma vinculação de função de administrador de cluster:

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

Instale a ferramenta de linha de comando Helm:

brew install kubernetes-helm

O Homebrew 2.0 agora também está disponível para Linux.

Crie uma conta de serviço e uma vinculação de função de cluster para o Tiller:

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

Implante o Tiller no namespace kube-system:

helm init --service-account tiller

Você deve considerar usar SSL entre o Helm e o Tiller. Para mais informações sobre como proteger a instalação do Helm, veja docs.helm.sh

Confirme as configurações:

kubectl -n istio-system get svc

Em alguns segundos, o GCP deve atribuir um IP externo ao serviço istio-ingressgateway.

Configuração do gateway de entrada do Istio

Crie um endereço IP estático com o nome istio-gateway, usando o endereço IP do gateway do 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

Agora você precisa de um domínio na internet e acesso ao seu registrador DNS. Adicione duas entradas A (substitua example.com pelo seu domínio):

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

Verifique se o wildcard DNS está funcionando:

watch host test.istio.example.com

Crie um gateway público do Istio para fornecer serviços fora da service mesh via 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:
        - "*"

Salve o recurso acima como public-gateway.yaml e, em seguida, aplique-o:

kubectl apply -f ./public-gateway.yaml

Nenhum sistema de produção deve fornecer serviços na Internet sem SSL. Para proteger o gateway de entrada do Istio usando cert-manager, CloudDNS e Let's Encrypt, leia documentação Flagger GKE.

Instalação do Flagger

A instalação do GKE Istio não inclui uma instância do Prometheus, que gerencia a limpeza do serviço de telemetria do Istio. Como o Flagger usa métricas HTTP do Istio para realizar a análise canary, você precisa implantar a seguinte configuração do Prometheus, semelhante à fornecida com o esquema oficial do Istio Helm.

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

Adicione o repositório Flagger Helm:

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

Implante o Flagger no namespace istio-system, incluindo notificações do 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

Você pode instalar o Flagger em qualquer namespace, desde que possa interagir com o serviço Istio Prometheus na porta 9090.

O Flagger tem um painel Grafana para análise canary. Instale o Grafana no 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

Abra o 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

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

Implantações canary automáticas com 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 para o 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 pelo seu domínio):

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, se bem-sucedida, será executada por cinco minutos, verificando as métricas HTTP a cada meia-minuto. 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 estão documentados aqui.

Após 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

Abra o navegador e acesse app.istio.example.com, você deve ver o número da versão do aplicativo de demonstração.

Análise e promoção canary automática

O Flagger implementa um ciclo de gerenciamento que move gradualmente o tráfego para o canary, medindo simultaneamente métricas de desempenho chave, como a taxa de sucesso das solicitações HTTP, a duração média das solicitações e a disponibilidade do pod. Com base na análise das KPI, o canary é promovido ou interrompido, e os resultados da análise são publicados no Slack.

Implantações canary automáticas com Flagger e Istio

O deployment canary é iniciado quando ocorre uma mudança em um dos seguintes objetos:

  • PodSpec do Deployment (imagem do contêiner, comando, portas, env, etc.)
  • ConfigMaps montados como volumes ou transformados em variáveis de ambiente
  • Segredos montados como volumes ou transformados em variáveis de ambiente

Iniciando o deployment canary ao atualizar a imagem do contêiner:

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

O Flagger detecta que a versão do deployment mudou e começa a analisá-la:

kubectl -n test describe canary/podinfo

Eventos:

Nova revisão detectada podinfo.test
Escalando podinfo.test
Aguardando o rollout do podinfo.test terminar: 0 de 1 réplicas atualizadas estão disponíveis
Avançar peso canary podinfo.test 5
Avançar peso canary podinfo.test 10
Avançar peso canary podinfo.test 15
Avançar peso canary podinfo.test 20
Avançar peso canary podinfo.test 25
Avançar peso canary podinfo.test 30
Avançar peso canary podinfo.test 35
Avançar peso canary podinfo.test 40
Avançar peso canary podinfo.test 45
Avançar peso canary podinfo.test 50
Copiando a especificação do template podinfo.test para podinfo-primary.test
Aguardando o rollout do podinfo-primary.test terminar: 1 de 2 réplicas atualizadas estão disponíveis
Promoção concluída! Diminuindo podinfo.test

Durante a análise, os resultados do canary podem ser monitorados usando o Grafana:

Implantações canary automáticas com Flagger e Istio

Observe: se novas alterações forem aplicadas ao deployment durante a análise canary, o Flagger reiniciará a fase de análise.

Crie uma lista de todos os "canários" em seu cluster:

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

Se você habilitou as notificações do Slack, terá as seguintes mensagens:

Implantações canary automáticas com Flagger e Istio

Rollback automático

Durante a análise canary, é possível gerar erros sintéticos HTTP 500 e alta latência de resposta para verificar se o Flagger interrompe o deployment.

Crie um pod de teste e execute a seguinte ação nele:

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

Gerando erros HTTP 500:

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

Gerando latência:

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

Quando o número de verificações malsucedidas atinge o limite, o tráfego é redirecionado de volta ao canal primário, o canário é dimensionado para zero e a implantação é marcada como malsucedida.

Erros do canário e picos de latência são registrados como eventos do Kubernetes e gravados pelo Flagger no formato JSON:

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

Iniciando a implantação canária para podinfo.test
Aumentar o peso do canário podinfo.test para 5
Aumentar o peso do canário podinfo.test para 10
Aumentar o peso do canário podinfo.test para 15
Parar o avanço do podinfo.test taxa de sucesso 69.17% < 99%
Parar o avanço do podinfo.test taxa de sucesso 61.39% < 99%
Parar o avanço do podinfo.test taxa de sucesso 55.06% < 99%
Parar o avanço do podinfo.test taxa de sucesso 47.00% < 99%
Parar o avanço do podinfo.test taxa de sucesso 37.00%  500ms
Parar o avanço do podinfo.test duração da solicitação 1.600s > 500ms
Parar o avanço do podinfo.test duração da solicitação 1.915s > 500ms
Parar o avanço do podinfo.test duração da solicitação 2.050s > 500ms
Parar o avanço do podinfo.test duração da solicitação 2.515s > 500ms
Revertendo podinfo.test limite de verificações falhadas alcançado 10
Canário falhou! Diminuindo podinfo.test.

Se você ativou as notificações do Slack, receberá uma mensagem quando o prazo de execução for excedido ou o número máximo de verificações malsucedidas for alcançado durante a análise:

Implantações canary automáticas com Flagger e Istio

Para concluir

Executar um serviço de mesh, como o Istio, além do Kubernetes, fornecerá métricas automáticas, logs e protocolos, mas a implantação de cargas de trabalho ainda depende de ferramentas externas. O Flagger busca mudar essa situação, adicionando ao Istio capacidades de entrega progressiva..

O Flagger é compatível com qualquer solução CI/CD para Kubernetes, e a análise canária pode ser facilmente expandida com webhooks para executar testes de sistema de integração/aceitação, testes de carga ou quaisquer outras verificações personalizadas. Como o Flagger é declarativo e responde a eventos do Kubernetes, ele pode ser utilizado em pipelines GitOps junto com Weave Flux ou JenkinsX. Se você está usando o JenkinsX, pode instalar o Flagger com complementos jx.

O Flagger é apoiado por Weaveworks e proporciona implantações canárias em Weave Cloud. O projeto é testado no GKE, EKS e em "bare metal" com kubeadm.

Se você tiver sugestões para melhorar o Flagger, por favor, envie uma pergunta ou PR no GitHub em stefanprodan/flagger. Contribuições são mais do que bem-vindas!

Obrigado Ray Tsan.

Fonte: habr.com

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster