Implantação Canary no Kubernetes nº 1: Gitlab CI

Usaremos Gitlab CI e GitOps manual para implementar e usar a implantação Canary no Kubernetes

Implantação Canary no Kubernetes nº 1: Gitlab CI

Artigos desta série:

Realizaremos a implantação do Canary manualmente via GitOps e criando/modificando os principais recursos do Kubernetes. Este artigo destina-se principalmente à introdução sobre como funciona a implantação no Kubernetes Canary, já que existem métodos de automação mais eficazes, que consideraremos nos artigos a seguir.


Implantação Canary no Kubernetes nº 1: Gitlab CI

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

Implantação canário

Com a estratégia Canary, as atualizações são aplicadas primeiro apenas a um subconjunto de usuários. Através de monitoramento, dados de log, testes manuais ou outros canais de feedback, a versão é testada antes de ser liberada para todos os usuários.

Implantação do Kubernetes (atualização contínua)

A estratégia padrão para implantação do Kubernetes é a atualização contínua, em que um determinado número de pods é lançado com novas versões das imagens. Se eles foram criados sem problemas, os pods com versões antigas de imagens serão encerrados e novos pods serão criados em paralelo.

GitOps

Usamos GitOps neste exemplo porque:

  • usando Git como uma única fonte de verdade
  • usamos operações Git para construção e implantação (nenhum comando além de git tag/merge é necessário)

Exemplo

Vamos adotar uma boa prática: ter um repositório para código de aplicação e outro para infraestrutura.

Repositório de aplicativos

Esta é uma API Python+Flask muito simples que retorna uma resposta como JSON. Construiremos o pacote via GitlabCI e enviaremos o resultado para o registro do Gitlab. No registro, temos duas versões de lançamento diferentes:

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

A única diferença entre eles é a alteração no arquivo JSON retornado. Usamos este aplicativo para visualizar o mais facilmente possível com qual versão estamos nos comunicando.

Repositório de infraestrutura

Neste nabo iremos implantar via GitlabCI no Kubernetes, .gitlab-ci.yml é o seguinte:

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 você mesmo precisará de um cluster, você pode 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 de um garfo https://gitlab.com/wuestkamp/k8s-deployment-example-canary-infrastructure e crie uma variável KUBECONFIG no GitlabCI, que conterá a configuração para acesso kubectl para o seu cluster.

Você pode ler sobre como obter credenciais para um cluster (Gcloud) aqui.

Infraestrutura Yaml

No repositório de infraestrutura temos serviço:

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

E implantação 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 outra implantação 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 app-deploy ainda não possui réplicas definidas.

Executando a implantação inicial

Para iniciar a implantação inicial, você pode iniciar o pipeline GitlabCI manualmente no branch master. Depois disso kubectl deve gerar o seguinte:

Implantação Canary no Kubernetes nº 1: Gitlab CI

Nós vemos app implantação com 10 réplicas e app-canary com 0. Há também um LoadBalancer do qual podemos acessar através curl via IP externo:

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

Implantação Canary no Kubernetes nº 1: Gitlab CI

Vemos que nosso aplicativo de teste retorna apenas “v1”.

Executando a implantação Canary

Etapa 1: lançar uma nova versão para alguns usuários

Definimos o número de réplicas como 1 no arquivo deploy-canary.yaml e na 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 alteramos o número de réplicas para 9:

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

Enviamos essas alterações para o repositório a partir do qual a implantação será iniciada (via GitlabCI) e vemos o resultado:

Implantação Canary no Kubernetes nº 1: Gitlab CI

Nosso Serviço apontará para ambas as implantações, já que ambas possuem o seletor de aplicativos. Devido à randomização padrão do Kubernetes, devemos ver respostas diferentes para aproximadamente 10% das solicitações:

Implantação Canary no Kubernetes nº 1: Gitlab CI

O estado atual da nossa aplicação (GitOps, retirado do Git como Single Source Of Truth) é a presença de duas implantações com réplicas ativas, uma para cada versão.

Cerca de 10% dos usuários se familiarizam com uma nova versão e a testam involuntariamente. Agora é a hora de verificar se há erros nos logs e monitorar os dados para encontrar problemas.

Etapa 2: liberar a nova versão para todos os usuários

Decidimos que tudo correu bem e agora precisamos lançar a nova versão para todos os usuários. Para fazer isso, simplesmente atualizamos deploy.yaml instalando uma nova versão da imagem e o número de réplicas igual a 10. Em deploy-canary.yaml definimos o número de réplicas de volta para 0. Após a implantação, o resultado será o seguinte:

Implantação Canary no Kubernetes nº 1: Gitlab CI

Resumindo

Para mim, executar a implantação manualmente dessa forma ajuda a entender como ela pode ser facilmente configurada usando k8s. Como o Kubernetes permite atualizar tudo por meio de uma API, essas etapas podem ser automatizadas por meio de scripts.

Outra coisa que precisa ser implementada é um ponto de entrada do testador (LoadBalancer ou via Ingress) através do qual somente a nova versão poderá ser acessada. Ele pode ser usado para navegação manual.

Em artigos futuros, verificaremos outras soluções automatizadas que implementam a maior parte do que fizemos.

Leia também outros artigos em nosso blog:

Fonte: habr.com

Adicionar um comentário