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.
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
Faça login no Google Cloud, crie um projeto e ative o faturamento para ele. Instale o utilitário de linha de comando 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
brew install kubernetes-helm
O Homebrew 2.0 agora também está disponível para
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
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-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 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
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-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 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.
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
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
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.
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:
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:
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:
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
Flagger é compatível com qualquer solução Kubernetes CI/CD, e a análise canário pode ser facilmente estendida com
Sinalizador suportado
Se você tiver sugestões para melhorar o Flagger, envie um problema ou PR no GitHub em
Obrigado
Fonte: habr.com