🥇StealthWatch: análise e investigação de incidentes. Parte 3 | ProHoster

Usaremos Gitlab CI e GitOps manual para implementar e utilizar o Canary deployment no Kubernetes

🥇StealthWatch: análise e investigação de incidentes. Parte 3 | ProHoster

Artigos desta série:

Faremos o Canary deployment manualmente através de GitOps e criação/modificação de recursos principais do Kubernetes. Este artigo é destinado principalmente para familiarização com o funcionamento do Canary deployment no Kubernetes, pois existem métodos mais eficientes de automação que abordaremos nos próximos artigos.


🥇StealthWatch: análise e investigação de incidentes. Parte 3 | ProHoster

https://www.norberteder.com/canary-deployment/

Canary Deployment

Na estratégia de Canary, as atualizações são inicialmente aplicadas apenas para uma parte dos usuários. Por meio de monitoramento, dados de logs, testes manuais ou outros canais de feedback, a versão é testada antes de sua aplicação para todos os usuários.

Kubernetes Deployment (atualização gradual)

A estratégia padrão para o Kubernetes Deployment é a atualização gradual, onde um determinado número de pods com novas versões de imagens é iniciado. Se forem criados sem problemas, os pods com as versões antigas das imagens são encerrados e novos pods são criados em paralelo.

GitOps

Usamos GitOps neste exemplo, pois:

  • usamos o Git como a única fonte da verdade
  • usamos operações Git para construção e deployment (sem comandos, exceto git tag/merge são necessários)

Exemplo

Vamos seguir uma boa prática — ter um repositório para o código dos aplicativos e outro para a infraestrutura.

Repositório para aplicativos

Esta é uma API muito simples em Python+Flask, que retorna uma resposta em formato JSON. Compilaremos o pacote através do GitlabCI e enviaremos o resultado para o Gitlab Registry. No registry temos duas versões diferentes de releases:

  • wuestkamp/k8s-deployment-example-app:v1
  • wuestkamp/k8s-deployment-example-app:v2

A única diferença entre elas é a alteração no arquivo JSON retornado. Usamos esta aplicação para visualização máxima do qual versão estamos interagindo.

Repositório de infraestrutura

Neste repositório, faremos o deployment através do GitlabCI no Kubernetes, .gitlab-ci.yml fica da seguinte forma:

image: traherom/kustomize-docker

before_script:
   - printenv
   - kubectl version

stages:
 - deploy

deploy test:
   stage: deploy
   before_script:
     - echo $KUBECONFIG
   script:
     - kubectl get all
     - kubectl apply -f i/k8s

   only:
     - master

Para executá-lo por conta própria, você precisará de um cluster, podendo usar o Gcloud:

gcloud container clusters create canary --num-nodes 3 --zone europe-west3-b

gcloud compute firewall-rules create incoming-80 --allow tcp:80

Você precisa fazer um fork https://gitlab.com/wuestkamp/k8s-deployment-example-canary-infrastructure e criar uma variável KUBECONFIG no GitlabCI, que conterá a configuração para acesso kubectl ao seu cluster.

Sobre como obter credenciais para o cluster (Gcloud) você pode ler aqui.

Yaml de infraestrutura

No repositório de infraestrutura, temos um service:

apiVersion: v1
kind: Service
metadata:
 labels:
   id: app
 name: app
spec:
 ports:
 - port: 80
   protocol: TCP
   targetPort: 5000
 selector:
   id: app
 type: LoadBalancer

E deployment em deploy.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
 name: app
spec:
 replicas: 10
 selector:
   matchLabels:
     id: app
     type: main
 template:
   metadata:
     labels:
       id: app
       type: main
   spec:
     containers:
     - image: registry.gitlab.com/wuestkamp/k8s-deployment-example-app:v1
       name: app
       resources:
         limits:
           cpu: 100m
           memory: 100Mi

E outro deployment em deploy-canary.yaml:

kind: Deployment
metadata:
 name: app-canary
spec:
 replicas: 0
 selector:
   matchLabels:
     id: app
     type: canary
 template:
   metadata:
     labels:
       id: app
       type: canary
   spec:
     containers:
     - image: registry.gitlab.com/wuestkamp/k8s-deployment-example-app:v2
       name: app
       resources:
         limits:
           cpu: 100m
           memory: 100Mi

Observe que o app-deploy ainda não tem réplicas definidas.

Execução da implantação inicial

Para iniciar o deployment inicial, você pode executar o pipeline do GitlabCI manualmente no branch principal. Depois disso, kubectl deve apresentar o seguinte:

🥇StealthWatch: análise e investigação de incidentes. Parte 3 | ProHoster

Nós vemos app deployment com 10 réplicas e app-canary com 0. Também há um LoadBalancer que podemos acessar através do curl IP Externo:

while true; do curl -s 35.198.149.232 | grep label; sleep 0.1; done

🥇StealthWatch: análise e investigação de incidentes. Parte 3 | ProHoster

Nós vemos que nosso aplicativo de teste retorna apenas 'v1'.

Execução do Canary deployment

Passo 1: liberar uma nova versão para parte dos usuários

Definimos o número de réplicas como 1 no arquivo deploy-canary.yaml e a imagem da nova versão:

kind: Deployment
metadata:
 name: app-canary
spec:
 replicas: 1
 selector:
   matchLabels:
     id: app
     type: canary
 template:
   metadata:
     labels:
       id: app
       type: canary
   spec:
     containers:
     - image: registry.gitlab.com/wuestkamp/k8s-deployment-example-app:v2
       name: app
       resources:
         limits:
           cpu: 100m
           memory: 100Mi

No arquivo deploy.yaml nós mudamos o número de réplicas para 9:

kind: Deployment
metadata:
 name: app
spec:
 replicas: 9
 selector:
   matchLabels:
     id: app
...

Estamos enviando essas alterações para o repositório, de onde o deployment será iniciado (via GitlabCI) e vemos o resultado:

🥇StealthWatch: análise e investigação de incidentes. Parte 3 | ProHoster

Nosso Service apontará para ambos os deployments, já que ambos têm o seletor app. Devido à distribuição aleatória padrão no Kubernetes, devemos ver respostas diferentes em ~ 10% das solicitações:

🥇StealthWatch: análise e investigação de incidentes. Parte 3 | ProHoster

O estado atual do nosso aplicativo (GitOps, retirado do Git como a Única Fonte da Verdade) consiste na presença de dois deployments com réplicas ativas, um para cada versão.

~10% dos usuários estão se familiarizando com a nova versão e testando-a inadvertidamente. Agora é hora de verificar se há erros nos logs e nos dados de monitoramento para encontrar problemas.

Passo 2: liberar uma nova versão para todos os usuários

Decidimos que tudo correu bem e agora precisamos implementar a nova versão para todos os usuários. Para isso, simplesmente atualizamos deploy.yaml instalando a nova versão da imagem e setando o número de réplicas igual a 10. No deploy-canary.yaml Definimos o número de réplicas como igual a zero. Após o deployment, o resultado será o seguinte:

🥇StealthWatch: análise e investigação de incidentes. Parte 3 | ProHoster

Resumindo

Para mim, iniciar o deployment manualmente dessa forma ajuda a entender como ele pode ser facilmente configurado com o k8s. Como o Kubernetes permite atualizar tudo através da API, esses passos podem ser automatizados por scripts.

Outra coisa que precisamos implementar é a entrada do testador (LoadBalancer ou através do Ingress), pela qual podemos acessar apenas a nova versão. Isso pode ser usado para visualização manual.

Nos próximos artigos, iremos explorar outras soluções automatizadas que implementam a maior parte do que fizemos.

Leia também outros artigos em nosso blog:

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