Marcação baseada em conteúdo no coletor werf: por que e como funciona?

Marcação baseada em conteúdo no coletor werf: por que e como funciona?

bem é nosso utilitário GitOps CLI de código aberto para construir e entregar aplicativos para Kubernetes. EM versão v1.1 um novo recurso foi introduzido no coletor de imagens: marcar imagens por conteúdo ou marcação baseada em conteúdo. Até agora, o esquema típico de marcação no werf envolvia a marcação de imagens Docker por tag Git, branch Git ou commit Git. Mas todos estes esquemas têm desvantagens que são completamente resolvidas pela nova estratégia de etiquetagem. Detalhes sobre isso e por que é tão bom estão em segredo.

Implementando um conjunto de microsserviços de um repositório Git

Muitas vezes ocorre uma situação quando um aplicativo é dividido em muitos serviços mais ou menos independentes. As liberações desses serviços podem ocorrer de forma independente: um ou mais serviços podem ser liberados por vez, enquanto os demais devem continuar funcionando sem nenhuma alteração. Mas do ponto de vista do armazenamento de código e do gerenciamento de projetos, é mais conveniente manter esses serviços de aplicação em um único repositório.

Existem situações em que os serviços são verdadeiramente independentes e não estão associados a uma única aplicação. Neste caso, eles estarão localizados em projetos separados e sua liberação será realizada através de processos CI/CD separados em cada um dos projetos.

No entanto, na realidade, os desenvolvedores muitas vezes dividem um único aplicativo em vários microsserviços, mas criar um repositório e um projeto separados para cada um... é um claro exagero. É esta situação que será discutida mais adiante: vários desses microsserviços estão localizados em um único repositório de projeto e as liberações ocorrem através de um único processo em CI/CD.

Marcação por branch Git e tag Git

Digamos que a estratégia de marcação mais comum seja usada: tag-ou-ramo. Para ramificações do Git, as imagens são marcadas com o nome da ramificação; para uma ramificação por vez, há apenas uma imagem publicada com o nome dessa ramificação. Para tags Git, as imagens são marcadas de acordo com o nome da tag.

Quando uma nova tag Git é criada — por exemplo, quando uma nova versão é lançada — uma nova tag Docker será criada para todas as imagens do projeto no Docker Registry:

  • myregistry.org/myproject/frontend:v1.1.10
  • myregistry.org/myproject/myservice1:v1.1.10
  • myregistry.org/myproject/myservice2:v1.1.10
  • myregistry.org/myproject/myservice3:v1.1.10
  • myregistry.org/myproject/myservice4:v1.1.10
  • myregistry.org/myproject/myservice5:v1.1.10
  • myregistry.org/myproject/database:v1.1.10

Esses novos nomes de imagens são passados ​​por meio de modelos do Helm para a configuração do Kubernetes. Ao iniciar a implantação com o comando werf deploy campo está sendo atualizado image nos manifestos de recursos do Kubernetes e reiniciando os recursos correspondentes devido à alteração do nome da imagem.

problema: no caso em que, de fato, o conteúdo da imagem não mudou desde o lançamento anterior (tag Git), mas apenas sua tag Docker, isso acontece excesso reiniciar este aplicativo e, consequentemente, algum tempo de inatividade é possível. Embora não houvesse nenhum motivo real para realizar esta reinicialização.

Como resultado, com o esquema de marcação atual é necessário cercar vários repositórios Git separados e surge o problema de organizar a implementação desses vários repositórios. Em geral, tal esquema acaba sendo sobrecarregado e complexo. É melhor combinar vários serviços em um único repositório e criar tags Docker para que não haja reinicializações desnecessárias.

Marcação por commit do Git

werf também possui uma estratégia de marcação associada aos commits do Git.

Git-commit é um identificador para o conteúdo de um repositório Git e depende do histórico de edição de arquivos no repositório Git, portanto parece lógico usá-lo para marcar imagens no Docker Registry.

No entanto, a marcação por commit do Git tem as mesmas desvantagens que a marcação por ramificações do Git ou tags do Git:

  • Pode ser criado um commit vazio que não altera nenhum arquivo, mas a tag Docker da imagem será alterada.
  • Pode ser criado um commit de mesclagem que não altera os arquivos, mas a tag Docker da imagem será alterada.
  • Pode ser feito um commit que altera os arquivos no Git que não são importados para a imagem, e a tag Docker da imagem será alterada novamente.

A marcação do nome da ramificação do Git não reflete a versão da imagem

Há outro problema associado à estratégia de marcação para ramificações do Git.

A marcação por nome de branch funciona desde que os commits nesse branch sejam coletados sequencialmente em ordem cronológica.

Se no esquema atual o usuário começar a reconstruir um commit antigo associado a um determinado branch, então o werf irá reescrever a imagem usando a tag Docker correspondente com uma versão recém-construída da imagem para o commit antigo. As implantações que usam essa tag a partir de agora correm o risco de obter uma versão diferente da imagem ao reiniciar os pods, fazendo com que nosso aplicativo perca a conexão com o sistema de CI e fique dessincronizado.

Além disso, com pushes sucessivos em um branch com um curto período de tempo entre eles, o commit antigo pode ser compilado depois do mais recente: a versão antiga da imagem substituirá a nova usando a tag do branch Git. Tais problemas podem ser resolvidos por um sistema CI/CD (por exemplo, no GitLab CI o pipeline deste último é lançado para uma série de commits). No entanto, nem todos os sistemas suportam isto e deve haver uma forma mais fiável de prevenir um problema tão fundamental.

O que é marcação baseada em conteúdo?

Então, o que é marcação baseada em conteúdo - marcação de imagens por conteúdo.

Para criar tags Docker, não são usadas primitivas Git (ramificação Git, tag Git...), mas uma soma de verificação associada a:

  • conteúdo da imagem. A tag de ID da imagem reflete seu conteúdo. Ao construir uma nova versão, este identificador não será alterado se os arquivos da imagem não forem alterados;
  • história de criação desta imagem no Git. Imagens associadas a diferentes ramificações do Git e diferentes históricos de construção via werf terão tags de ID diferentes.

Essa etiqueta identificadora é a chamada assinatura de palco de imagem.

Cada imagem consiste em um conjunto de etapas: from, before-install, git-archive, install, imports-after-install, before-setup, ... git-latest-patch etc. Cada estágio possui um identificador que reflete seu conteúdo - assinatura de palco (assinatura de palco).

A imagem final, composta por essas etapas, é marcada com a chamada assinatura do conjunto dessas etapas - assinatura de etapas, - que é generalizante para todas as fases da imagem.

Para cada imagem da configuração werf.yaml no caso geral, haverá assinatura própria e, consequentemente, uma tag Docker.

A assinatura do palco resolve todos estes problemas:

  • Resistente a commits vazios do Git.
  • Resistente a commits do Git que alteram arquivos que não são relevantes para a imagem.
  • Não leva ao problema de revisar a versão atual da imagem ao reiniciar compilações para commits antigos do Git de uma ramificação.

Esta é agora a estratégia de marcação recomendada e é o padrão no werf para todos os sistemas de CI.

Como habilitar e usar no werf

O comando agora tem uma opção correspondente werf publish: --tag-by-stages-signature=true|false

Em um sistema CI, a estratégia de marcação é especificada pelo comando werf ci-env. Anteriormente, o parâmetro era definido para ele werf ci-env --tagging-strategy=tag-or-branch. Agora, se você especificar werf ci-env --tagging-strategy=stages-signature ou não especifique esta opção, o werf usará a estratégia de marcação por padrão stages-signature. Equipe werf ci-env definirá automaticamente os sinalizadores necessários para o comando werf build-and-publish (ou werf publish), portanto, nenhuma opção adicional precisa ser especificada para esses comandos.

Por exemplo, o comando:

werf publish --stages-storage :local --images-repo registry.hello.com/web/core/system --tag-by-stages-signature

...pode criar as seguintes imagens:

  • registry.hello.com/web/core/system/backend:4ef339f84ca22247f01fb335bb19f46c4434014d8daa3d5d6f0e386d
  • registry.hello.com/web/core/system/frontend:f44206457e0a4c8a54655543f749799d10a9fe945896dab1c16996c6

é 4ef339f84ca22247f01fb335bb19f46c4434014d8daa3d5d6f0e386d é uma assinatura dos estágios da imagem backendE f44206457e0a4c8a54655543f749799d10a9fe945896dab1c16996c6 - assinatura de estágios de imagem frontend.

Ao usar funções especiais werf_container_image и werf_container_env Não há necessidade de alterar nada nos modelos do Helm: essas funções gerarão automaticamente os nomes de imagem corretos.

Exemplo de configuração em um sistema CI:

type multiwerf && source <(multiwerf use 1.1 beta)
type werf && source <(werf ci-env gitlab)
werf build-and-publish|deploy

Mais informações sobre configuração estão disponíveis na documentação:

No total

  • Nova opção werf publish --tag-by-stages-signature=true|false.
  • Novo valor de opção werf ci-env --tagging-strategy=stages-signature|tag-or-branch (se não for especificado, o padrão será stages-signature).
  • Se você usou anteriormente as opções de marcação para commits do Git (WERF_TAG_GIT_COMMIT ou opção werf publish --tag-git-commit COMMIT) e mude para a estratégia de marcação assinatura de estágios.
  • É melhor mudar imediatamente novos projetos para o novo esquema de marcação.
  • Ao transferir para o werf 1.1, é aconselhável mudar os projetos antigos para o novo esquema de marcação, mas o antigo tag-ou-ramo ainda é suportado.

A marcação baseada em conteúdo resolve todos os problemas abordados no artigo:

  • Resistência do nome da tag Docker a commits vazios do Git.
  • Resiliência do nome da tag Docker para commits do Git que alteram arquivos irrelevantes para a imagem.
  • Não leva ao problema de revisar a versão atual da imagem ao reiniciar compilações para commits antigos do Git para ramificações do Git.

Use-o! E não se esqueça de nos visitar em GitHubpara criar um problema ou encontrar um existente, adicionar um plus, criar um PR ou simplesmente observar o desenvolvimento do projeto.

PS

Leia também em nosso blog:

Fonte: habr.com

Adicionar um comentário