ProHoster > Blog > administração > 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.
é 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:
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.