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:
- 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.
- 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.
- 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 YAMLO 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?
- 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 ). - 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 ) . - 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:
- 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. .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.- 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) .”