[referência ao conto infantil americano "O Pequeno Trem que Podia" ("The Little Engine That Could") — nota do tradutor]*

Como criar imagens Docker minúsculas automaticamente para suas necessidades
Uma obsessão incomum
Nos últimos meses, estive obcecado pela ideia: até onde consigo reduzir uma imagem Docker, fazendo com que o aplicativo continue funcionando?
Eu sei, a ideia é estranha.
Antes de mergulhar nos detalhes e nas questões técnicas, gostaria de explicar por que esse problema me chamou a atenção e como isso impacta você.
Por que o tamanho importa
Ao reduzir o conteúdo da imagem Docker, também diminuímos a lista de vulnerabilidades. Além disso, deixamos as imagens mais limpas, pois elas contêm apenas o que é necessário para executar os aplicativos.
Há mais uma pequena vantagem — as imagens são baixadas um pouco mais rápido, mas, na minha opinião, isso não é tão importante.
Vale lembrar: Se o tamanho é uma preocupação, as imagens Alpine são pequenas por si só e provavelmente atenderão suas necessidades.
Imagens Distroless
oferece uma coleção de imagens "distroless" básicas, que não contêm gerenciadores de pacotes, shells e outras ferramentas que você está acostumado a ver na linha de comando. Como resultado, não será possível usar gerenciadores de pacotes como pip e apt :
FROM gcr.io/distroless/python3
RUN pip3 install numpyDockerfile usando imagem distroless Python 3
Enviando contexto de construção para o daemon Docker 2.048kB
Passo 1/2: FROM gcr.io/distroless/python3
---> 556d570d5c53
Passo 2/2: RUN pip3 install numpy
---> Executando em dbfe5623f125
/bin/sh: 1: pip3: não encontradoPip não está na imagem
Normalmente, esse problema é resolvido usando uma construção em várias etapas:
FROM python:3 as builder
RUN pip3 install numpy
FROM gcr.io/distroless/python3
COPY --from=builder /usr/local/lib/python3.7/site-packages /usr/local/lib/python3.5/Construção em várias etapas
O resultado é uma imagem de 130 MB. Não é tão ruim! Para comparação: a imagem do Python padrão pesa 929 MB, enquanto a "magra" (3.7-slim) — 179 MB, a imagem alpine (3.7-alpine) — 98,6 MB, enquanto a imagem distroless básica usada no exemplo é 50,9 MB.
Pode-se argumentar que, no exemplo anterior, estamos copiando um diretório inteiro /usr/local/lib/python3.7/site-packages, que pode conter dependências desnecessárias. Embora esteja claro que a diferença nos tamanhos de todas as imagens base do Python varia.
No momento da redação destas linhas, a Google distroless não suporta muitas imagens: Java e Python estão em fase experimental, e o Python existe apenas para 2.7 e 3.5.
Imagens minúsculas
Vamos voltar à minha obsessão por criar imagens pequenas.
Na verdade, eu queria ver como funcionam as imagens distroless. O projeto distroless utiliza a ferramenta de construção do Google bazel. No entanto, para instalar o Bazel e escrever minhas próprias imagens, tive que ralar (e, para ser completamente honesto, reinventar a roda — isso é divertido e instrutivo). Eu queria simplificar a criação de imagens reduzidas: o ato de criar uma imagem deve ser o mais simples possível, banal. Para que não haja arquivos de configuração, apenas uma linha no console: simplesmente construir uma imagem para.
. Então, se você quiser criar suas próprias imagens, saiba que existe uma imagem docker única, scratch. Scratch é uma imagem 'vazia', não contém arquivos, embora por padrão pese — uau! — 77 bytes.
FROM scratchA imagem scratch
A ideia por trás da imagem scratch é que você pode copiar quaisquer dependências da máquina host para ela e usá-las dentro do Dockerfile (é como copiá-las para apt e instalar do zero), ou mais tarde, quando a imagem Docker se materializa. Isso permite controlar completamente o conteúdo do contêiner Docker e, assim, o tamanho da imagem.
Agora precisamos de uma maneira de reunir essas dependências. Ferramentas existentes como apt permitindo baixar pacotes, mas estão atreladas à máquina atual e, no final das contas, não suportam Windows ou MacOS.
Então, comecei a desenvolver minha própria ferramenta, que automaticamente reunir imagens básicas do menor tamanho possível e ainda fosse capaz de executar qualquer aplicativo. Eu usei pacotes Ubuntu/Debian, fiz a extração (obtendo pacotes diretamente dos repositórios) e localizei recursivamente suas dependências. O programa deveria baixar automaticamente a versão estável mais recente do pacote, minimizando os riscos de segurança.
Eu chamei a ferramenta de fetchy, porque ela... encontra e traz... o que é necessário [do inglês 'fetch', 'trazer' — nota do tradutor.] A ferramenta funciona através de uma interface de linha de comando, mas também oferece uma API.
Para criar uma imagem usando fetchy (vamos usar desta vez a imagem Python), tudo o que você precisa fazer é usar o CLI assim: fetchy dockerize python. Podem solicitar o sistema operacional de destino e o nome do código, já que fetchy atualmente utiliza apenas pacotes baseados em Debian e Ubuntu.
Agora é possível escolher quais dependências são realmente desnecessárias (no nosso contexto) e excluí-las. Por exemplo, o Python depende do Perl, embora funcione perfeitamente sem a instalação do Perl.
Resultados
A imagem do Python, criada com o comando fetchy dockerize python3.5 pesando apenas 35MB (tenho certeza de que no futuro ela poderá ser ainda mais leve). Assim, conseguimos reduzir mais 15MB a partir da imagem distroless.
Todas as imagens coletadas até agora podem ser vistas .
Projeto — .
Se você sentir falta de funcionalidades, basta criar um pedido — ficarei feliz em ajudar 🙂 Na verdade, estou atualmente trabalhando na integração de outros gerenciadores de pacotes ao fetchy, de modo que a necessidade de builds em várias etapas seja eliminada.
Fonte: habr.com
