
O CD é reconhecido como uma prática de desenvolvimento de software corporativo; é o resultado de uma evolução natural dos princípios estabelecidos de IC. No entanto, o CD ainda é uma ocorrência bastante rara, possivelmente devido à complexidade do gerenciamento e ao medo de implantações malsucedidas que afetam a disponibilidade do sistema.
O Flagger é um operador Kubernetes de código aberto que visa eliminar relacionamentos confusos. Ele automatiza a promoção de implantações de canários usando desvios de tráfego do Istio e métricas do Prometheus para analisar o comportamento do aplicativo durante a implementação gerenciada.
Abaixo está um guia passo a passo sobre como configurar e usar o Flagger no Google Kubernetes Engine (GKE).
Configurar o cluster Kubernetes
Você começa criando um cluster GKE com o suplemento Istio (se você não possui uma conta GCP, pode se registrar aqui para receber créditos gratuitos).
Faça login no Google Cloud, crie um projeto e ative o faturamento. Instale o utilitário de linha de comando gcloud e personalize seu projeto com o gcloud init
.
Defina o projeto padrão, a área de cálculo 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 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 conjunto de nós padrão que inclui duas VMs n1-standard-2
(vCPU: 2, RAM 7,5 GB, disco: 30 GB). Idealmente, vale a pena isolar os componentes do Istio de suas cargas de trabalho, mas não há maneira fácil de executar pods do Istio em um conjunto de nós dedicado. Os manifestos do Istio são considerados somente leitura e o GKE desfaz todas as alterações, como vincular a um nó ou desconectar-se de uma lareira.
Configure credenciais para o kubectl
:
gcloud container clusters get-credentials istio
Crie a ligação da 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
Agora, o Homebrew 2.0 também está disponível para Linux .
Crie uma conta de serviço e uma ligaçã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 kube-system
:
helm init --service-account tiller
Você deve considerar o uso de SSL entre Helm e Tiller. Para obter mais informações sobre como proteger uma instalação Helm, consulte docs.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 istio-ingressgateway
.
Configuração do Gateway de Entrada Istio
Crie um endereço IP estático chamado istio-gateway
usando 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 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 curinga do DNS está funcionando:
watch host test.istio.example.com
Crie um gateway comum do Istio para fornecer serviços fora da malha de serviço sobre 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 Istio com o gerenciador de certificados, CloudDNS e Let's Encrypt, leia a documentação do Flagger GKE.
Instalação do Flagger
O suplemento GKE Istio não inclui a instância do Prometheus, que limpa o serviço de telemetria do Istio. Como o Flagger usa as métricas HTTP do Istio para executar análises de canárias, é necessário 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 do Flagger Helm:
helm repo add flagger https://flagger.app
Expanda Flagger no istio-system
istio-system istio-system
ativando 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 espaço de nome se ele puder se comunicar com o serviço Istio Prometheus pela porta 9090.
O Flagger possui um painel Grafana para análise de canários. Instale o Grafana no 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
Expanda o Grafana através de um gateway aberto, 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 aplique-o:
kubectl apply -f ./grafana-virtual-service.yaml
Ao acessar http://grafana.istio.example.com
em um navegador, você deve ser direcionado para a página de login da Grafana.
Implantação de aplicativo Web com o Flagger
O Flagger implementa o Kubernetes e, se necessário, o escalonamento automático horizontal (HPA) e cria uma série de objetos (implantações do Kubernetes, serviços ClusterIP e serviços virtuais Istio). Esses objetos abrem o aplicativo na malha de serviço e gerenciam a análise e a promoção do canary.

Crie um espaço para nome de teste com a implementação do Istio Sidecar ativada:
REPO=https://raw.githubusercontent.com/stefanprodan/flagger/master kubectl apply -f ${REPO}/artifacts/namespaces/test.yaml
Crie uma ferramenta de escala horizontal automática de implantação e aquecimento:
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 do canary:
helm upgrade -i flagger-loadtester flagger/loadtester \ --namepace=test
Crie um recurso canário 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 aplique-o:
kubectl apply -f ./podinfo-canary.yaml
A análise acima, se for bem-sucedida, será realizada em cinco minutos, com as métricas HTTP verificadas a cada meio minuto. Você pode determinar o tempo mínimo necessário para verificar e promover uma implantação de canário usando a seguinte fórmula: interval * (maxWeight / stepWeight)
. Os campos Canary CRD estão documentados aqui .
Em alguns segundos, o Flagger criará objetos canários:
# 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 acesse app.istio.example.com
. Você verá o número da versão do aplicativo de demonstração .
Análise e promoção automáticas de canários
O Flagger implementa um loop de controle que gradualmente move o tráfego para o canário, enquanto mede os principais indicadores de desempenho, por exemplo, a taxa de sucesso de solicitações HTTP, a duração média das solicitações e o desempenho da lareira. Com base na análise, o canário do KPI progride ou é interrompido, e os resultados da análise são publicados no Slack.

A implantação do Canary é iniciada quando um dos seguintes objetos é alterado:
- Implantar o PodSpec (imagem do contêiner, comando, portas, env, etc.)
- Os ConfigMaps são montados como volumes ou convertidos em variáveis de ambiente
- Segredos são montados como volumes ou convertidos em variáveis de ambiente
Iniciando uma implantação canary ao atualizar uma imagem de contêiner:
kubectl -n test set image deployment/podinfo \ podinfod=quay.io/stefanprodan/podinfo:1.4.1
O Flagger descobre 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 das canárias podem ser rastreados usando o Grafana:

Observação: se novas alterações forem aplicadas à implantação durante a análise de canários, o Flagger reiniciará a fase de análise.
Faça uma lista de todos os "canários" no 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:

Reversão automática
Durante a análise do canário, você pode gerar erros HTTP 500 sintéticos e um alto atraso de resposta para verificar se o Flagger interromperá a implantação.
Crie uma sub de teste e faça o seguinte:
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
Geração de erro HTTP 500:
watch curl http://podinfo-canary:9898/status/500
Atraso na geração:
watch curl http://podinfo-canary:9898/delay/1
Quando o número de verificações sem êxito atinge o valor limite, o tráfego é roteado de volta para o canal primário, o canary é dimensionado para zero e a implantação é marcada como sem êxito.
Erros canários e picos de atraso 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ê ativou as notificações do Slack, receberá uma mensagem quando o prazo for atingido ou quando o número máximo de falhas de verificação durante a análise for atingido:

Em conclusão
O lançamento 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 de cargas de trabalho ainda depende de ferramentas externas. O Flagger procura mudar isso adicionando os recursos de entrega progressiva do Istio.
O Flagger é compatível com qualquer solução de CI / CD da Kubernetes, e a análise do canário pode ser facilmente estendida usando webhooks para executar testes de integração / aceitação do sistema, testes de estresse ou quaisquer outros testes do usuário. Como o Flagger é declarativo e responsivo aos eventos do Kubernetes, ele pode ser usado nos pipelines do GitOps com o Weave Flux ou o JenkinsX . Se você estiver usando o JenkinsX, poderá instalar o Flagger com complementos jx.
O Flagger é suportado pelo Weaveworks e fornece implementações de canários para o Weave Cloud . O projeto é testado em GKE, EX e bare metal com kubeadm.
Se você tiver alguma sugestão para melhorar o Flagger, envie uma pergunta ou relações públicas ao GitHub em stefanprodan / flagger . As contribuições são mais que bem-vindas!
Obrigado Ray Tsang .