As imagens do Docker também podem ser construídas no werf usando o Dockerfile usual

Antes tarde do que nunca. Ou como quase cometemos um erro grave, não tendo o suporte de Dockerfiles comuns para criar imagens de aplicativos.



Falaremos sobre o werf , um utilitário GitOps que se integra a qualquer sistema de CI / CD e fornece controle sobre todo o ciclo de vida do aplicativo, permitindo:

  • Coletar e publicar imagens
  • Implantar aplicativos no Kubernetes
  • Exclua imagens não utilizadas usando políticas especiais.

A filosofia do projeto é montar ferramentas de baixo nível em um único sistema unificado que oferece aos engenheiros do DevOps controle sobre aplicativos. Sempre que possível, os utilitários existentes (como Helm e Docker) devem estar envolvidos. Se não houver solução para um problema, podemos criar e manter tudo o necessário para isso.

Plano de fundo: Seu coletor de imagens


Foi o que aconteceu com o coletor de imagens no werf: não possuímos o Dockerfile usual. Se você mergulhar rapidamente na história do projeto, esse problema se manifestará nas primeiras versões do werf (então ainda conhecido como dapp ).

Criando uma ferramenta para criar aplicativos nas imagens do Docker, percebemos rapidamente que o Dockerfile não era adequado para algumas tarefas muito específicas:

  1. A necessidade de criar aplicativos da Web pequenos típicos de acordo com o seguinte esquema padrão:
    • Instale dependências de aplicativos em todo o sistema
    • instalar pacote de bibliotecas de dependência de aplicativos,
    • coletar ativos
    • e o mais importante, atualize o código na imagem de maneira rápida e eficiente.
  2. Quando são feitas alterações nos arquivos do projeto, o construtor deve criar rapidamente uma nova camada aplicando uma correção aos arquivos modificados.
  3. Se certos arquivos foram alterados, é necessário reconstruir o estágio dependente apropriado.

Hoje em nosso colecionador existem muitas outras possibilidades, mas os desejos e impulsos iniciais eram esses.

Em geral, sem pensar duas vezes, nos armamos com a linguagem de programação usada (veja abaixo) e pegamos a estrada - implementamos nossa própria DSL ! Correspondendo às tarefas, pretendia-se descrever o processo de montagem por etapas e determinar as dependências dessas etapas nos arquivos. E complementado por seu próprio colecionador , que transformou a DSL no objetivo final - uma imagem montada. No início, o DSL estava em Ruby e, quando mudamos para Golang , a configuração do nosso coletor começou a ser descrita no arquivo YAML.


Configuração antiga para dapp em Ruby


Configuração atual para werf no YAML

O mecanismo do coletor também mudou com o tempo. Primeiro, simplesmente geramos um Dockerfile temporário temporário a partir de nossa configuração em tempo real e, em seguida, começamos a executar instruções de montagem em contêineres temporários e fizemos o commit.

NB : No momento, nosso coletor, que trabalha com sua configuração (em YAML) e é chamado de Stapel-coletor, já se tornou uma ferramenta bastante poderosa. Sua descrição detalhada merece artigos separados e os principais detalhes podem ser encontrados na documentação .

Consciência do problema


Mas percebemos, e não imediatamente, que cometemos um erro: não adicionamos a capacidade de coletar imagens através do Dockerfile padrão e as integramos à mesma infraestrutura para gerenciamento de aplicativos integrado (ou seja, coletar imagens, implantar e limpá-las). Como você pode criar uma ferramenta de implantação no Kubernetes e não implementar o suporte ao Dockerfile, ou seja, uma maneira padrão de descrever imagens para a maioria dos projetos? ..

Em vez de responder a essa pergunta, oferecemos uma solução. E se você já tiver um Dockerfile (ou um conjunto de Dockerfiles) e quiser usar o werf?

NB : A propósito, por que você gostaria de usar o werf? Os principais recursos são os seguintes:

  • ciclo completo de gerenciamento de aplicativos, incluindo limpeza de imagens;
  • a capacidade de controlar a montagem de várias imagens a partir de uma única configuração;
  • Processo aprimorado de implantação de gráfico compatível com o Helm.

Uma lista mais completa deles pode ser encontrada na página do projeto .

Portanto, se antes sugeriríamos reescrever o Dockerfile em nossa configuração, agora teremos o maior prazer em dizer: "Vamos criar seus Dockerfiles!"

Como usar?


A implementação completa desse recurso apareceu na versão werf v1.0.3-beta.1 . O princípio geral é simples: o usuário especifica o caminho para o Dockerfile existente na configuração do werf e, em seguida, executa o comando werf build ... e é isso - o werf coletará a imagem. Considere um exemplo abstrato.

Dockerfile seguinte Dockerfile na raiz do projeto:

 FROM ubuntu:18.04 RUN echo Building ... 

E declare werf.yaml que usa este Dockerfile :

 configVersion: 1 project: dockerfile-example --- image: ~ dockerfile: ./Dockerfile 

Isso é tudo! Resta executar o werf build :



Além disso, você pode declarar o seguinte werf.yaml por criar várias imagens de diferentes Dockerfiles de uma só vez:

 configVersion: 1 project: dockerfile-example --- image: backend dockerfile: ./dockerfiles/Dockerfile-backend --- image: frontend dockerfile: ./dockerfiles/Dockerfile-frontend 

Por fim, ele também suporta a transferência de parâmetros adicionais de construção - como --build-arg e --add-host - através da configuração do werf. Uma descrição completa da configuração da imagem do Dockerfile está disponível na página de documentação .

Como isso funciona?


Durante o processo de criação, o cache da camada local padrão no Docker funciona. No entanto, o mais importante, o werf também integra a configuração do Dockerfile à sua infraestrutura . O que isso significa?

  1. Cada imagem coletada do Dockerfile consiste em um estágio chamado dockerfile (mais sobre o que são os estágios no werf, você pode ler aqui ).
  2. Por estágio, o dockerfile werf calcula a assinatura, que depende do conteúdo da configuração do Dockerfile. Quando a configuração do Dockerfile é alterada, a assinatura do estágio dockerfile é alterada e o werf inicia a reconstrução desse estágio com a nova configuração do Dockerfile. Se a assinatura não for alterada, o werf removerá a imagem do cache (mais detalhes sobre o uso de assinaturas no werf foram descritos neste relatório ) .
  3. Além disso, as imagens coletadas podem ser publicadas werf publish comando werf publish (ou o werf build-and-publish ) e usadas para implantação no Kubernetes. As imagens publicadas no Docker Registry serão limpas com produtos de limpeza werf padrão, ou seja, ele limpará automaticamente imagens antigas (mais de N dias), imagens associadas a ramificações Git inexistentes e outras políticas.

Você pode aprender mais sobre os pontos descritos aqui na documentação:


Notas e precauções


1. URL externo no ADD não é suportado


Atualmente, o uso de um URL externo na diretiva ADD não é suportado. O Werf não iniciará a reconstrução quando um recurso for alterado para o URL especificado. Em breve, está planejado adicionar esse recurso.

2. Você não pode adicionar .git a uma imagem


De um modo geral, adicionar um diretório .git a uma imagem é uma prática ruim e é por isso que:

  1. Se o .git permanecer na imagem final, isso violará os princípios do aplicativo de 12 fatores : como a imagem final deve ser associada a um commit, não será possível fazer um git checkout um commit arbitrário.
  2. .git aumenta o tamanho da imagem (o repositório pode ser grande devido ao fato de que arquivos grandes foram adicionados a ela e excluídos). O tamanho da árvore de trabalho, associado apenas a uma confirmação específica, não dependerá do histórico de operações no Git. Ao mesmo tempo, adicionar e remover .git da imagem final não funcionará: a imagem ainda terá uma camada extra - é assim que o Docker funciona.
  3. O Docker pode iniciar a reconstrução desnecessária, mesmo se o mesmo commit estiver sendo construído, mas a partir de diferentes árvores de trabalho. Por exemplo, o GitLab cria diretórios clonados separados em /home/gitlab-runner/builds/HASH/[0-N]/yourproject quando a montagem paralela está ativada. A reconstrução extra ocorrerá porque o diretório .git difere em diferentes versões clonadas do mesmo repositório, mesmo que a mesma confirmação seja coletada.

O último ponto tem uma consequência ao usar o werf. O Werf exige que o cache coletado esteja presente quando determinados comandos forem executados (por exemplo, werf deploy ). Durante a operação de tais comandos, o werf calcula as assinaturas de palco das imagens especificadas em werf.yaml e elas devem estar no cache de montagem - caso contrário, a equipe não poderá continuar trabalhando. Se a assinatura do estágio depender do conteúdo do .git , obteremos um cache instável para alterações em arquivos irrelevantes, e o werf não poderá perdoar tal supervisão (consulte a documentação para obter mais detalhes).

Em geral, adicionar apenas certos arquivos necessários através da instrução ADD aumenta a eficiência e a confiabilidade do Dockerfile gravado e também melhora a estabilidade do cache compilado por este Dockerfile contra alterações irrelevantes no Git.

Sumário


Nossa maneira inicial de escrever nosso próprio compilador para certas necessidades foi difícil, honesta e direta: em vez de usar muletas sobre o Dockerfile padrão, escrevemos nossa própria solução com sintaxe personalizada. E isso deu suas vantagens: o Stapel-builder lida perfeitamente com sua tarefa.

No entanto, no processo de escrever nosso próprio coletor, ignoramos o suporte dos Dockerfiles existentes. Agora, essa falha foi corrigida e, no futuro, planejamos desenvolver o suporte ao Dockerfile junto com nosso coletor Stapel personalizado para montagem distribuída e para montagem usando o Kubernetes (ou seja, montagem em corredores dentro do Kubernetes, como é feito no kaniko).

Então, de repente, você tinha alguns Dockerfiles por aí ... tente werf !

PS Lista de documentação relacionada



Leia também em nosso blog: “ werf é nossa ferramenta de CI / CD no Kubernetes (revisão e reportagem em vídeo) .”

Source: https://habr.com/ru/post/pt463613/


All Articles