Imagens minúsculas do Docker que acreditaram em si mesmas*

[referência ao conto de fadas infantil americano "The Little Engine That Could" - aprox. faixa]*

Imagens minúsculas do Docker que acreditaram em si mesmas*

Como criar automaticamente pequenas imagens Docker para suas necessidades

Obsessão incomum

Nos últimos meses, fiquei obcecado com o quão pequena uma imagem do Docker pode ser e ainda assim ter o aplicativo em execução.

Eu entendo, a ideia é estranha.

Antes de entrar em detalhes e aspectos técnicos, gostaria de explicar por que esse problema me incomodou tanto e como preocupa você.

Por que o tamanho é importante

Ao reduzir o conteúdo da imagem Docker, reduzimos assim a lista de vulnerabilidades. Além disso, deixamos as imagens mais limpas, pois contêm apenas o necessário para rodar os aplicativos.

Há mais uma pequena vantagem - o download das imagens é um pouco mais rápido, mas, na minha opinião, isso não é tão importante.

Observação: se você está preocupado com o tamanho, o visual Alpine em si é pequeno e provavelmente caberá em você.

Imagens sem distração

Projeto sem distribuição oferece uma seleção de imagens básicas “sem distribuição”, elas não contêm gerenciadores de pacotes, shells e outros utilitários que você está acostumado a ver na linha de comando. Como resultado, use gerenciadores de pacotes como pip и apt não funciona:

FROM gcr.io/distroless/python3
RUN  pip3 install numpy

Dockerfile usando imagem sem distribuição do Python 3

Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM gcr.io/distroless/python3
 ---> 556d570d5c53
Step 2/2 : RUN  pip3 install numpy
 ---> Running in dbfe5623f125
/bin/sh: 1: pip3: not found

Pip não está na imagem

Normalmente, esse problema é resolvido por uma construção em vários estágios:

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/

Montagem em vários estágios

O resultado é uma imagem de 130 MB de tamanho. Não é tão ruim! Para efeito de comparação: a imagem padrão do Python pesa 929 MB, e a “mais fina” (3,7-slim) - 179 MB, imagem alpina (3,7-alpine) tem 98,6 MB, enquanto a imagem base sem distribuição usada no exemplo tem 50,9 MB.

É justo ressaltar que no exemplo anterior estamos copiando um diretório inteiro /usr/local/lib/python3.7/site-packages, que pode conter dependências que não precisamos. Embora esteja claro que a diferença de tamanho de todas as imagens base Python existentes varia.

No momento em que este artigo foi escrito, o Google distroless não suporta muitas imagens: Java e Python ainda estão em fase experimental, e Python existe apenas para 2,7 e 3,5.

Imagens minúsculas

De volta à minha obsessão em criar pequenas imagens.

Em geral, eu queria ver como as imagens sem distração são construídas. O projeto distroless usa a ferramenta de construção do Google bazel. No entanto, instalar o Bazel e escrever suas próprias imagens deu muito trabalho (e para ser sincero, reinventar a roda é divertido e educativo). Queria simplificar a criação de imagens menores: o ato de criar uma imagem deveria ser extremamente simples, banal. Para que não haja arquivos de configuração para você, apenas uma linha no console: просто собрать образ для <приложение>.

Então, se você deseja criar suas próprias imagens, saiba: existe uma imagem docker única, scratch. Scratch é uma imagem “vazia”, não contém arquivos, embora pese por padrão - uau! - 77 bytes.

FROM scratch

Imagem de rascunho

A ideia de uma imagem temporária é que você pode copiar quaisquer dependências da máquina host para ela e usá-las dentro de um Dockerfile (é como copiá-las para apt e instalar do zero) ou mais tarde, quando a imagem do Docker for materializada. Isso permite controlar completamente o conteúdo do contêiner Docker e, assim, controlar completamente o tamanho da imagem.

Agora precisamos coletar de alguma forma essas dependências. Ferramentas existentes como apt permitem baixar pacotes, mas eles estão vinculados à máquina atual e, afinal, não suportam Windows ou MacOS.

Então decidi construir minha própria ferramenta que construiria automaticamente uma imagem base do menor tamanho possível e também executaria qualquer aplicativo. Usei pacotes Ubuntu/Debian, fiz uma seleção (obtendo pacotes diretamente dos repositórios) e encontrei recursivamente suas dependências. O programa deveria baixar automaticamente a versão estável mais recente do pacote, minimizando ao máximo os riscos de segurança.

Eu nomeei a ferramenta fetchy, porque ele... encontra e traz... o que é necessário [do inglês “buscar”, “trazer” - aprox. faixa]. A ferramenta funciona por meio de uma interface de linha de comando, mas ao mesmo tempo oferece uma API.

Para montar uma imagem usando fetchy (vamos pegar uma imagem Python desta vez), você só precisa usar a CLI assim: fetchy dockerize python. Você pode ser solicitado a fornecer o sistema operacional e o codinome de destino porque fetchy atualmente usa apenas pacotes baseados em Debian e Ubuntu.

Agora você pode escolher quais dependências não são necessárias (em nosso contexto) e excluí-las. Por exemplo, Python depende de perl, embora funcione bem sem Perl instalado.

Descobertas

Imagem Python criada usando o comando fetchy dockerize python3.5 pesa apenas 35 MB (tenho certeza de que no futuro poderá ficar ainda mais leve). Acontece que conseguimos eliminar mais 15 WW da imagem distrófica.

Você pode ver todas as imagens coletadas até agora aqui.

Projeto - aqui.

Se faltarem recursos, basta criar uma solicitação - ficarei feliz em ajudar :) Ainda mais, estou trabalhando atualmente na integração de outros gerenciadores de pacotes ao fetchy, para que não haja necessidade de compilações em vários estágios.

Fonte: habr.com

Adicionar um comentário