Agora você pode criar imagens do Docker em werf usando um Dockerfile regular

Antes tarde do que nunca. Ou como quase cometemos um erro grave ao não ter suporte para Dockerfiles regulares para construir imagens de aplicativos.

Agora você pode criar imagens do Docker em werf usando um Dockerfile regular

Nós falaremos sobre bem — Utilitário GitOps que se integra a qualquer sistema CI/CD e fornece gerenciamento de todo o ciclo de vida da aplicação, permitindo:

  • coletar e publicar imagens,
  • implantar aplicativos no Kubernetes,
  • exclua imagens não utilizadas usando políticas especiais.


A filosofia do projeto é reunir ferramentas de baixo nível em um único sistema unificado que dê aos engenheiros de DevOps controle sobre os aplicativos. Se possível, devem ser usados ​​utilitários existentes (como Helm e Docker). Se não houver solução para um problema, podemos criar e apoiar tudo o que for necessário para isso.

Plano de fundo: seu próprio coletor de imagens

Foi o que aconteceu com o coletor de imagens no werf: o Dockerfile usual não foi suficiente para nós. Se você der uma olhada rápida na história do projeto, esse problema apareceu já nas primeiras versões do werf (então ainda conhecido como dapp).

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

  1. A necessidade de construir pequenas aplicações web típicas de acordo com o seguinte esquema padrão:
    • instalar dependências de aplicativos em todo o sistema,
    • instalar um pacote de bibliotecas de dependência de aplicativos,
    • coletar ativos,
    • e o mais importante, atualize o código da imagem de forma rápida e eficiente.
  2. Quando são feitas alterações nos arquivos do projeto, o construtor deve criar rapidamente uma nova camada aplicando um patch aos arquivos alterados.
  3. Se determinados arquivos foram alterados, será necessário reconstruir o estágio dependente correspondente.

Hoje nosso colecionador tem muitas outras possibilidades, mas esses foram os desejos e vontades iniciais.

Em geral, sem pensar duas vezes, nos armamos com a linguagem de programação que usamos (veja abaixo) e pegar a estrada para implementar próprio DSL! De acordo com os objectivos, pretendeu-se descrever o processo de montagem por etapas e determinar as dependências destas etapas em relação aos ficheiros. E complementou próprio colecionador, que transformou o DSL no objetivo final - uma imagem montada. No início a DSL era em Ruby, mas como transição para Golang — a configuração do nosso coletor passou a ser descrita em um arquivo YAML.

Agora você pode criar imagens do Docker em werf usando um Dockerfile regular
Configuração antiga para dapp em Ruby

Agora você pode criar imagens do Docker em werf usando um Dockerfile regular
Configuração atual para werf em YAML

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

NB: No momento, nosso coletor, que funciona com configuração própria (em YAML) e é chamado de coletor Stapel, já se tornou uma ferramenta bastante poderosa. Sua descrição detalhada merece artigos separados, e detalhes básicos podem ser encontrados em documentação.

Consciência do problema

Mas percebemos, e não imediatamente, que havíamos cometido um erro: não adicionamos a habilidade construir imagens via Dockerfile padrão e integrá-los na mesma infraestrutura de gerenciamento de aplicativos ponta a ponta (ou seja, coletar imagens, implantá-las e limpá-las). Como seria possível fazer uma ferramenta para implantação no Kubernetes e não implementar o suporte Dockerfile, ou seja, maneira padrão de descrever imagens para a maioria dos projetos?

Em vez de responder a esta 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ê iria querer usar o werf? As principais características se resumem ao seguinte:

  • ciclo completo de gerenciamento de aplicativos, incluindo limpeza de imagens;
  • a capacidade de gerenciar a montagem de várias imagens ao mesmo tempo a partir de uma única configuração;
  • Processo de implantação aprimorado para gráficos compatíveis com Helm.

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

Então, se antes tivéssemos nos oferecido para reescrever o Dockerfile em nossa configuração, agora diremos com alegria: “Deixe o werf construir seus Dockerfiles!”

Como usar?

A implementação completa deste recurso apareceu no lançamento werf v1.0.3-beta.1. O princípio geral é simples: o usuário especifica o caminho para um Dockerfile existente na configuração do werf e, em seguida, executa o comando werf build... e pronto - o Werf montará a imagem. Vejamos um exemplo abstrato.

Vamos anunciar o próximo Dockerfile na raiz do projeto:

FROM ubuntu:18.04
RUN echo Building ...

E vamos anunciar werf.yamlque usa isso Dockerfile:

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

Todos! Esquerda correr werf build:

Agora você pode criar imagens do Docker em werf usando um Dockerfile regular

Além disso, você pode declarar o seguinte werf.yaml para construir 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

Finalmente, ele também suporta a passagem de parâmetros de construção adicionais, como --build-arg и --add-host - através da configuração do werf. Uma descrição completa da configuração da imagem Dockerfile está disponível em página de documentação.

Como isso funciona?

Durante o processo de construção, o cache padrão das camadas locais no Docker funciona. No entanto, o que é importante é que werf também integra a configuração do Dockerfile em sua infraestrutura. O que isto significa?

  1. Cada imagem construída a partir de um Dockerfile consiste em um estágio chamado dockerfile (você pode ler mais sobre quais estágios estão no werf aqui).
  2. Para palco dockerfile werf calcula uma assinatura que depende do conteúdo da configuração do Dockerfile. Quando a configuração do Dockerfile muda, a assinatura do estágio muda dockerfile e o werf inicia uma reconstrução deste estágio com uma nova configuração do Dockerfile. Se a assinatura não mudar, então o werf pega a imagem do cache (mais detalhes sobre o uso de assinaturas no werf foram descritos em este relatório).
  3. A seguir, as imagens coletadas podem ser publicadas com o comando werf publish (ou werf build-and-publish) e use-o para implantação no Kubernetes. As imagens publicadas no Docker Registry serão limpas usando ferramentas de limpeza werf padrão, ou seja, Imagens antigas (com mais de N dias), imagens associadas a ramificações Git inexistentes e outras políticas serão limpas automaticamente.

Mais detalhes sobre os pontos descritos aqui podem ser encontrados na documentação:

Notas e precauções

1. URL externo não é compatível com ADD

Atualmente não é suportado usar uma URL externa em uma diretiva ADD. O Werf não iniciará uma reconstrução quando o recurso no URL especificado for alterado. Planejamos adicionar esse recurso em breve.

2. Você não pode adicionar .git à imagem

De modo geral, adicionar um diretório .git na imagem - uma má prática cruel e aqui está o porquê:

  1. Se .git permanece na imagem final, isso viola os princípios aplicativo de 12 fatores: Como a imagem final deve estar vinculada a um único commit, não deveria ser possível fazer git checkout 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 ele e depois excluídos). O tamanho de uma árvore de trabalho associada apenas a um commit específico não dependerá do histórico de operações no Git. Neste caso, a adição e posterior remoção .git da imagem final não funcionará: a imagem ainda adquirirá uma camada extra - é assim que o Docker funciona.
  3. O Docker pode iniciar uma reconstrução desnecessária, mesmo que o mesmo commit esteja sendo compilado, mas a partir de árvores de trabalho diferentes. Por exemplo, o GitLab cria diretórios clonados separados em /home/gitlab-runner/builds/HASH/[0-N]/yourproject quando a montagem paralela está habilitada. A remontagem extra será devido ao fato do diretório .git é diferente em diferentes versões clonadas do mesmo repositório, mesmo que o mesmo commit seja compilado.

O último ponto também tem consequências ao usar o werf. Werf requer que o cache construído esteja presente ao executar alguns comandos (por exemplo, werf deploy). Quando esses comandos são executados, o werf calcula assinaturas de estágio para as imagens especificadas em werf.yaml, e eles devem estar no cache de montagem - caso contrário, o comando não poderá continuar funcionando. Se a assinatura do palco depende do conteúdo .git, então obtemos um cache que é instável a alterações em arquivos irrelevantes, e o werf não será capaz de perdoar tal descuido (para mais detalhes, consulte documentação).

Em geral, adicionando apenas alguns arquivos necessários através das instruções ADD em qualquer caso, aumenta a eficiência e a confiabilidade do escrito Dockerfile, e também melhora a estabilidade do cache coletado para este Dockerfile, para mudanças irrelevantes no Git.

Total

Nosso caminho inicial para escrever nosso próprio construtor para necessidades específicas foi difícil, honesto e direto: em vez de usar muletas no Dockerfile padrão, escrevemos nossa solução com sintaxe personalizada. E isso teve suas vantagens: o coletor Stapel cumpre perfeitamente sua tarefa.

No entanto, no processo de escrever nosso próprio construtor, perdemos de vista o suporte para Dockerfiles existentes. Essa falha foi corrigida e, no futuro, planejamos desenvolver suporte ao Dockerfile junto com nosso construtor Stapel personalizado para compilações distribuídas e para compilações usando Kubernetes (ou seja, compilações em executores dentro do Kubernetes, como é feito em kaniko).

Então, se de repente você tiver alguns Dockerfiles por aí... tente bem!

PS Lista de documentação sobre o tema

Leia também em nosso blog: “werf - nossa ferramenta para CI/CD no Kubernetes (visão geral e relatório em vídeo)".

Fonte: habr.com

Adicionar um comentário