Suporte a monorepo e multirepo no werf e qual a relação com o Docker Registry.

Suporte a monorepo e multirepo no werf e qual a relação com o Docker Registry.

O tema do monorepositório já foi discutido diversas vezes e, geralmente, provoca debates bastante acalorados. Ao criar werf uma ferramenta de código aberto, destinada a melhorar os processos de construção de código de aplicações do Git em imagens Docker (e sua posterior entrega no Kubernetes), raramente refletimos sobre qual escolha é melhor. Para nós, o primordial é garantir tudo que é necessário para os defensores de diferentes opiniões (se isso não contradizer o bom senso, é claro).

O apoio recente ao mono-repo no werf é um bom exemplo disso. Mas, antes de tudo, vamos entender como esse suporte se relaciona ao uso do werf e qual a conexão com o Docker Registry...

Problemas

Vamos imaginar a seguinte situação. A empresa possui várias equipes de desenvolvedores trabalhando em projetos independentes. A maioria das aplicações opera no Kubernetes, e, consequentemente, está conteinerizada. Para armazenar contêineres e imagens, é necessário um registro (registry). A empresa utiliza o Docker Hub com uma única conta COMPANY. Por analogia com a maioria dos sistemas de armazenamento de código fonte, o Docker Hub não permite criar uma hierarquia de repositórios aninhados, como COMPANY/PROJECT/IMAGE. Nesse caso... como armazenar no registro aplicações não monolíticas sem criar uma conta separada para cada projeto?

Suporte a monorepo e multirepo no werf e qual a relação com o Docker Registry.

Talvez a situação descrita seja familiar para alguns, mas vamos considerar a questão da organização do armazenamento de aplicações de forma geral, ou seja, sem amarras ao exemplo mencionado acima e ao Docker Hub.

Soluções

Se a aplicação for monolítica, não há problemas e simplesmente armazenamos as imagens no registro de contêineres do projeto.

Quando a aplicação é apresentada na forma de vários componentes, microsserviços, é necessário escolher um determinado enfoque. Tomando como exemplo uma aplicação web típica, composta por duas imagens: frontend e backend — as opções possíveis são:

  1. Armazenar as imagens em repositórios aninhados separados:

    Suporte a monorepo e multirepo no werf e qual a relação com o Docker Registry.

  2. Armazenar tudo em um único repositório, considerando o nome da imagem no tag, por exemplo, da seguinte forma:

    Suporte a monorepo e multirepo no werf e qual a relação com o Docker Registry.

NB: Na verdade, há também a opção de armazenamento em diferentes repositórios, PROJECT-frontend e PROJECT-backend, mas não iremos considerar isso devido à complexidade de suporte, organização e distribuição de direitos entre os usuários.

Suporte no werf

Inicialmente, o werf limitou-se a repositórios aninhados — felizmente, a maioria dos registros suporta essa possibilidade. A partir da versão v1.0.4-alpha.3, foi adicionada a possibilidade de trabalhar com registros que não suportam aninhamento, incluindo o Docker Hub. A partir de agora, o usuário teve a opção de como armazenar as imagens da aplicação.

A implementação está disponível na opção --images-repo-mode=multirepo|monorepo (por padrão, multirepo, ou seja, armazenamento em repositórios aninhados). Ela determina os padrões de como as imagens são armazenadas no registro. É suficiente escolher o modo desejado ao usar os comandos principais, e tudo o mais permanecerá inalterado.

Como a maioria das opções do werf pode ser definida por variáveis de ambiente, em sistemas CI/CD, o modo de armazenamento geralmente é fácil de definir globalmente para todo o projeto. Por exemplo, no caso do GitLab, basta adicionar uma variável de ambiente nas configurações do projeto: Configurações -> CI / CD -> Variáveis: WERF_IMAGES_REPO_MODE: multirepo|monorepo.

Falando sobre a publicação de imagens e o lançamento de aplicações (sobre esses processos, pode-se ler em detalhes nos artigos correspondentes da documentação: Processo de Publicação e Processo de Implantação), o modo define exclusivamente o padrão de como trabalhar com a imagem.

O diabo está nos detalhes.

A diferença e a principal dificuldade ao adicionar uma nova forma de armazenamento são o processo de limpeza do registro (as capacidades de limpeza suportadas no werf estão na Processo de Limpeza).

Ao limpar, o werf considera as imagens usadas nos clusters Kubernetes, bem como as políticas configuradas pelo usuário. A base das políticas é a divisão de tags em estratégias. As estratégias atualmente suportadas são:

  1. 3 estratégias relacionadas a primitivas do Git, como tag, ramo e commit;
  2. 1 estratégia para tags personalizadas arbitrárias.

As informações sobre a estratégia de tag são armazenadas ao publicar a imagem nos rótulos da imagem final. O próprio valor — o chamado metatag — é necessário para a aplicação de algumas políticas. Por exemplo, ao excluir um ramo ou uma tag do repositório Git, é lógico remover também as imagens não utilizadas do registro, o que é coberto por uma parte de nossas políticas.

Ao armazenar em um único repositório (monorepo), na tag da imagem, além do metatag, também pode ser armazenado o nome da imagem: PROJETO:frontend-META-TAG. Para separá-los, não introduzimos um delimitador específico, mas apenas adicionamos o valor necessário ao rótulo da imagem final ao publicá-la.

NB: Se estiver interessado em ver tudo que foi descrito no código-fonte do werf, um ponto de partida pode ser PR 1684.

Neste artigo, não vamos nos aprofundar mais nos problemas e na justificativa da nossa abordagem: sobre estratégias de tagueamento, armazenamento de dados em rótulos e o processo de publicação em geral — tudo isso foi descrito em detalhes no recente relatório de Dmitry Stolyarov: “werf — nossa ferramenta para CI/CD no Kubernetes».

Resumindo

A falta de suporte para registros sem aninhamento não foi um fator bloqueador para nós ou para os usuários conhecidos do werf — sempre é possível levantar um registro separado de imagens (ou mudar para um Container Registry no Google Cloud)… No entanto, a remoção dessa limitação parecia lógica para que a ferramenta fosse mais conveniente para uma comunidade DevOps mais ampla. Ao implementá-la, encontramos a principal dificuldade na reestruturação do mecanismo de limpeza do registro de contêineres. Agora, com tudo pronto, é gratificante saber que facilitou a vida de alguém, e para nós (como principais desenvolvedores do projeto) não prevemos grandes dificuldades na manutenção futura dessa funcionalidade.

Fique conosco e em breve contaremos sobre outras inovações em werf!

P.S.

Confira também 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