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

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

O CD é reconhecido como uma prática de software empresarial e é o resultado de uma evolução natural dos princípios de IC estabelecidos. No entanto, o CD ainda é bastante raro, talvez devido à complexidade do gerenciamento e ao medo de falhas nas implantações que afetam a disponibilidade do sistema.

Sinalizador é um operador Kubernetes de código aberto que visa eliminar relacionamentos confusos. Ele automatiza a promoção de implantações canárias usando compensação de tráfego do Istio e métricas do Prometheus para analisar o comportamento do aplicativo durante uma distribuição gerenciada.

Abaixo está um guia passo a passo para configurar e usar o sinalizador no Google Kubernetes Engine (GKE).

Configurando um cluster do Kubernetes

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

Faça login no Google Cloud, crie um projeto e ative o faturamento para ele. Instale o utilitário de linha de comando gcloud e monte seu projeto com gcloud init.

Defina o projeto padrão, a área de computação e a zona (substitua PROJECT_ID para o 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 os 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

O comando acima criará um pool de nós padrão incluindo duas VMs n1-standard-2 (vCPU: 2, RAM 7,5 GB, disco: 30 GB). O ideal é isolar os componentes do Istio de suas cargas de trabalho, mas não há uma maneira fácil de executar pods do Istio em um pool dedicado de nós. Os manifestos do Istio são considerados somente leitura e o GKE desfará todas as alterações, como vincular a um nó ou desanexar de um pod.

Configurar 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 Capacete:

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

Expanda o Tiller no namespace kube-system:

helm init --service-account tiller

Você deve considerar o uso de SSL entre o Helm e o Tiller. Para obter mais informações sobre como proteger sua instalação do Helm, consulte documentos.helm.sh

Confirme as configurações:

kubectl -n istio-system get svc

Após alguns segundos, o GCP deve atribuir um endereço IP externo para o serviço istio-ingressgateway.

Configurando o gateway de entrada do Istio

Crie um endereço IP estático com um nome istio-gatewayusando o endereço IP do gateway 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 da Internet e acesso ao seu registrador de DNS. Adicione dois registros A (substitua example.com para o seu domínio):

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

Verifique se o caractere curinga do DNS está funcionando:

watch host test.istio.example.com

Crie um gateway Istio genérico para fornecer serviços fora da malha de serviço por 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 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 Istio com cert-manager, CloudDNS e Let's Encrypt, leia documentação Flagger G.K.E.

Instalação do Sinalizador

O complemento GKE Istio não inclui uma instância do Prometheus que limpa o serviço de telemetria do Istio. Como o sinalizador usa métricas HTTP do Istio para realizar a análise canário, você precisa implantar a seguinte configuração do Prometheus, semelhante à que vem 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/)

Expandir sinalizador para namespace istio-systemativando as 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 ele possa se comunicar com o serviço Istio Prometheus na porta 9090.

Flagger tem um painel do 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

Exponha o Grafana por meio de um gateway aberto criando um serviço virtual (substitua example.com para o 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 aplique-o:

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

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

Implantando aplicativos da web com Flagger

O sinalizador implanta o Kubernetes e, opcionalmente, expande automaticamente (HPA) e, 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 à malha de serviço e controlam a análise e o progresso do canary.

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

Crie um namespace de teste com a injeção 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 expansão automática de pod:

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

Implante um serviço de carregamento de teste para gerar tráfego durante a análise canário:

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

Crie um recurso canário personalizado (substitua example.com para o 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 aplique-o:

kubectl apply -f ./podinfo-canary.yaml

A análise acima, se bem-sucedida, será executada por cinco minutos, verificando as métricas de HTTP a cada meio minuto. Você pode determinar o tempo mínimo necessário para validar e promover uma implantação canário usando a seguinte fórmula: interval * (maxWeight / stepWeight). Os campos Canary CRD são documentados aqui.

Após alguns segundos, o Flagger criará objetos canário:

# 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 um navegador e vá para app.istio.example.com, você deve ver o número da versão aplicativos de demonstração.

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

O sinalizador implementa um loop de controle que gradualmente move o tráfego para o canário enquanto mede as principais métricas de desempenho, como taxa de sucesso de solicitação HTTP, duração média da solicitação e integridade do pod. Com base na análise do KPI, o canário é promovido ou interrompido e os resultados da análise são publicados no Slack.

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

A implantação canário é acionada quando um dos seguintes objetos é alterado:

  • Implantar PodSpec (imagem de contêiner, comando, portas, env, etc.)
  • ConfigMaps são montados como volumes ou mapeados para variáveis ​​de ambiente
  • Os segredos são montados como volumes ou convertidos em variáveis ​​de ambiente

Execute canary deploy ao atualizar uma imagem de contêiner:

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

Flagger detecta que a versão de implantação foi alterada e começa a analisá-la:

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 a análise, os resultados do canary podem ser rastreados usando o Grafana:

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

Observe que, se novas alterações forem aplicadas a uma implantação durante a análise canary, o sinalizador reiniciará a fase de análise.

Faça uma lista de todos os canários em seu cluster:

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

Se você ativou as notificações do Slack, receberá as seguintes mensagens:

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

Reversão automática

Durante a análise canário, você pode gerar erros HTTP 500 sintéticos e alta latência de resposta para ver se o sinalizador interromperá a implantação.

Crie um pod de teste e faça o seguinte 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

Geração de atraso:

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

Quando o número de verificações com falha atinge o limite, o tráfego é roteado de volta para o canal principal, o canário é dimensionado para zero e a implantação é marcada como com falha.

Erros de canário e picos de latência são registrados como eventos do Kubernetes e registrados pelo Flagger no 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

Se você habilitou as notificações do Slack, receberá uma mensagem quando o prazo for excedido ou o número máximo de verificações com falha na análise for atingido:

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

Em conclusão

A execução de uma malha de serviço como o Istio, além do Kubernetes, fornecerá métricas, logs e protocolos automáticos, mas a implantação da carga de trabalho ainda depende de ferramentas externas. Flagger pretende mudar isso adicionando recursos do Istio entrega progressiva.

Flagger é compatível com qualquer solução Kubernetes CI/CD, e a análise canário pode ser facilmente estendida com webhooks para executar testes de aceitação/integração do sistema, testes de carga ou qualquer outra verificação personalizada. Como o sinalizador é declarativo e responde a eventos do Kubernetes, ele pode ser usado em pipelines do GitOps junto com Fluxo de tecelagem ou Jenkins X. Se você estiver usando o JenkinsX, poderá instalar o Flagger com complementos jx.

Sinalizador suportado Tecelagem e fornece implantações canário em tecer nuvem. O projeto está sendo testado em GKE, EKS e bare metal com kubeadm.

Se você tiver sugestões para melhorar o Flagger, envie um problema ou PR no GitHub em Stefanprodan/sinalizador. Contribuições são mais que bem-vindas!

Obrigado Ray Tsang.

Fonte: habr.com

Adicionar um comentário