Reduzindo imagens docker com MultiStage

Este post não tem tags.

Compartilhe:

Se você usa linguagens compiladas (Golang, Java) e está buscando uma forma eficiente de reduzir o tamanho das suas imagens docker, está no lugar certo.

Mas antes de decidir utilizar imagens pequenas, precisamos entender o real impacto do uso das imagens grandes.

Esse impacto pode ser maior que o imaginado em ambientes de alta volumetria.

Cenário:

  • Uma aplicação utiliza uma imagem docker de 1GB.
  • Essa aplicação está em um cluster de 100 nós.

No cenário descrito acima, imagine que a aplicação recebe uma volumetria inesperada e vai escalar automaticamente de 1 para 100 containers.

Isso significa que o cluster todo vai trafegar até 99GB de informação, fazendo pull (download) da imagem docker em cada nó que ainda não a tem disponível.

Pra piorar a situação, resolvemos fazer deploy de uma nova versão com a aplicação escalada, ou seja, todas as imagens serão substituídas nesse processo (~100GB).

Resultado:

  • Altas taxas de transferência
  • Concorrência de banda entre pull de imagens e usuários
  • Escalabilidade afetada

Para tentar resolver essa questão, vamos falar de Docker multistage, que apesar de ser uma funcionalidade bastante conhecida na comunidade, ainda gera dúvidas em alguns dos nossos clientes.

Antes da prática, vamos entender a teoria do uso de Multi Stage para o nosso caso:

imagine que o processo de build de uma aplicação precise atender uma série de dependências. Essas dependências criam camadas que fazem a imagem docker ficar cada vez maior.

Com o uso de Multi Stage, temos a possibilidade de utilizar imagens diferentes entre o processo de build e o processo de execução do binário. O resultado disso é uma imagem significativamente menor, já que as camadas anteriores são ‘descartadas’, restando somente o binário para execução em uma imagem enxuta.

Dockerfile:

FROM golang:1.7.3 AS builder
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY -–from=builder /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"]

O exemplo acima, ilustra o uso da imagem golang:1.7.3 com a tag builder, para o processo de build
da aplicação.

Em seguida, a imagem alpine:latest, é utilizada como imagem de execução, onde copiamos somente o
binário da imagem anterior: COPY –from=builder /go/src/github.com/alexellis/href-counter/app .

Isso traz resultados relevantes, já que a imagem final precisa somente do binário compilado.

Mão na Massa

Para o nosso laboratório prático, vamos utilizar um projeto opensource mantido pelo Luizalabs
chamado Teresa, onde tive a chance de colaborar para uma redução significativa da imagem docker.

A ideia do passo a passo é fazer o build da imagem antes do commit com Multi Stage, e depois do
commit pra fazermos a comparação.

Antes do Multi Stage

1 – Vamos começar clonando o projeto

$git clone https://github.com/luizalabs/teresa.git

2 – Em seguda acesse a pasta teresa

$cd teresa

3 – Voltando para o commit antes da alteração

$git checkout 70da95bbe2197ce1db3b46e8945ab990b28ebd8a

4 – Visualizando dockerfile

$cat Dockerfile


FROM golang:1.8
RUN mkdir -p /go/src/github.com/luizalabs/teresa
WORKDIR /go/src/github.com/luizalabs/teresa
COPY . /go/src/github.com/luizalabs/teresa
RUN make build-server
ENTRYPOINT ["./teresa-server"]
CMD ["run"]
EXPOSE 50051

5 – Fazendo build da imagem antiga

$docker build -t teresa-old .

6 – Listando imagens existentes

$docker images

Reduzindo imagens docker com MultiStage 1

Observe que a imagem tinha o tamanho de 823MB antes da alteração.

Depois do Multi Stage

1 – Indo para o commit depois da alteração

$git checkout 15de6e124ac1d081479320259c106f34628b989f

2 – Visualizando dockerfile novo

$cat Dockerfile

FROM golang:1.8 AS builder
WORKDIR /go/src/github.com/luizalabs/teresa
COPY . /go/src/github.com/luizalabs/teresa
RUN make build-server

FROM debian:9-slim
RUN apt-get update && \
apt-get install ca-certificates -y &&\
rm -rf /var/lib/apt/lists/* &&\
rm -rf /var/cache/apt/archives/*
WORKDIR /app
COPY –from=builder /go/src/github.com/luizalabs/teresa .
ENTRYPOINT [“./teresa-server”]
CMD [“run”]
EXPOSE 50051

3 – Fazendo build da imagem nova

$docker build -t teresa-new .

4 – Listando imagens existentes

$docker images

Reduzindo imagens docker com MultiStage 2

Pós alteração, a imagem chegou a 172MB, com possibilidade de melhoras.

Se você ainda não conhecia Docker Multistage, agora já conhece e pode utilizar na busca por imagens menores.
Se você já utiliza, compartilhe conosco o seu case também. 🙂

Sobre o autor(a)

Função não encontrada

Sysadmin, evangelista devops, agile expert e desenvolvedor nas horas vagas.

Artigos relacionados

Avelino segurando um microfone e uma camiseta preta escrita Agile. Ele é pardo, barba e cabelos grisalhos.

Este final de semana estive na casa de meus pais fazendo uma limpa e me deparei com um trabalho da minha primeira pós-graduação. O método ágil Crystal. Na corrida dos métodos ágeis é perceptível que o Scrum ganhou ampla dianteira…

Avelino segurando um microfone e uma camiseta preta escrita Agile. Ele é pardo, barba e cabelos grisalhos.

Uma frase que ficou muito popular é que quando adotamos a agilidade, passamos a entregar mais valor. Agilidade é entregar valor. Mas sem definir o que é valor, sua transformação será frágil, não ágil. Então, o que você pode fazer…

Avelino segurando um microfone e uma camiseta preta escrita Agile. Ele é pardo, barba e cabelos grisalhos.

É uma pergunta comum em diversos times ágeis: Temos capacidade para atender a demanda? A resposta é não. Como diz Rodrigo de Toledo: “No trabalho do conhecimento, a demanda sempre irá superar a nossa capacidade de atendê-la.”. O desafio é…

Avelino segurando um microfone e uma camiseta preta escrita Agile. Ele é pardo, barba e cabelos grisalhos.

Data storytelling. Se você acompanha o nosso blog, já deve ter percebido que eu gosto muito de trabalhar com métricas, dados e gráficos. É interessante, mas esses artefatos, apesar de serem interessantes, sozinhos eles não vão dizer muitas coisas. Você…