Рубрики
Без рубрики

Почему вы должны использовать многоступенчатые сборки Docker

В этом уроке я продемонстрирую, как создавать тонкие образы docker с помощью многоступенчатых сборок docker,… С тегами docker, java, maven, tutorial.

В этом руководстве я продемонстрирую, как создавать тонкие образы docker с помощью многоступенчатых сборок docker, где вы можете сэкономить до 800 МБ дискового пространства на образ.

Первоначально опубликовано на containers.fan

О

Мы будем использовать многоступенчатые сборки docker из образа alpine в качестве нашего образа сборки, чтобы получить зависимости, создать двоичный файл go и использовать наш скретч-образ для размещения встроенного двоичного файла на нашем целевом изображении, чтобы получить небольшие изображения docker.

Почему размер имеет значение

Итак, давайте предположим, что у вас есть оркестратор, такой как ECS, Swarm или Kubernetes, со 100 узлами за группой автоматического масштабирования, где количество узлов вашего кластера равно 10 при низком трафике и 100 узлам при большом трафике.

По мере масштабирования наш сервис может масштабироваться с 10 реплик до 500 реплик, и давайте предположим, что размер нашего образа контейнера составляет 800 МБ, когда новый узел присоединяется к кластеру, образ контейнера не будет находиться в кэше, поэтому демону docker необходимо загрузить этот образ из реестра docker. Итак, допустим, 100 узлов присоединяются к кластеру, и наш сервис масштабируется до 100 реплик, это означает, что каждому узлу необходимо загрузить 800 МБ из реестра docker, что составляет около 80 ГБ входящей пропускной способности сети в кластер.

Таким образом, когда мы используем многоступенчатые сборки и в данном случае используем Go, мы можем уменьшить наш образ контейнера до менее чем 3 МБ, если мы выполним те же вычисления, то пропускная способность составит чуть менее 300 МБ, и если новый узел присоединяется к кластеру, а образ контейнера отсутствует, потребуется примерно секунда или две на загрузку и запуск контейнера (в зависимости от скорости Интернета), и вы, очевидно, экономите место на диске.

Перейти к приложению

Мы будем использовать библиотеку, которая генерирует случайные данные из go-random data в нашем приложении, app.go :

package main

import (
    "fmt"
    "github.com/Pallinder/go-randomdata"
)

func main() {
    profile := randomdata.GenerateProfile(randomdata.Male | randomdata.Female | randomdata.RandomGender)
    fmt.Printf("The new profile's username is: %s and password (md5): %s\n", profile.Login.Username, profile.Login.Md5)
}

Одноступенчатая Сборка Docker

В этом примере мы будем использовать образ golang для получения зависимостей и сборки приложения в одном образе, нашем Dockerfile.single_stage :

FROM golang:latest as builder
RUN mkdir -p /go/src/github.com/ruanbekker
WORKDIR /go/src/github.com/ruanbekker
RUN useradd -u 10001 app
COPY . .
ENV GO111MODULE=auto
RUN go get
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .
USER app
CMD ["/go/src/github.com/ruanbekker/main"]

Создание имиджа:

docker build -f Dockerfile.single_stage -t goapp:singlestage .

Многоступенчатая Сборка Docker

Наш многоступенчатый состоит из образа сборки, где мы будем использовать образ golang для извлечения наших зависимостей и сборки нашего приложения, затем мы используем образ scratch в качестве цели для копирования скомпилированного двоичного файла и запуска контейнера из slim-образа, нашего Dockerfile.multi_stage :

FROM golang:latest as builder
RUN mkdir -p /go/src/github.com/ruanbekker
WORKDIR /go/src/github.com/ruanbekker
RUN useradd -u 10001 app
COPY . .
ENV GO111MODULE=auto
RUN go get
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .

FROM scratch
COPY --from=builder /go/src/github.com/ruanbekker/main /main
COPY --from=builder /etc/passwd /etc/passwd
USER app
CMD ["/main"]

Создание имиджа:

docker build -f Dockerfile.multi_stage -t goapp:multistage .

Сравнение различий в размерах

Когда мы сравниваем различия в размерах наших изображений docker между обычной сборкой и многоступенчатой сборкой, мы видим огромную разницу:

docker images | head -3
REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
goapp                             singlestage         0d0c1f4c98a2        54 seconds ago      896MB
goapp                             multistage          d74ac27a39c8        2 hours ago         2.75MB

И просто чтобы показать, что оба контейнера запускаются из встроенных образов docker, наша единая сборка:

docker run -it goapp:singlestage
The new profile's username is: Maregrass and password (md5): 56da7705b7648a38f539b043e6a494be

И наша многоступенчатая сборка:

docker run -it goapp:multistage
The new profile's username is: Shirtplaid and password (md5): 7d8606ee86f2da3ed12c595ab617bf4e

Спасибо

Если вам понравился этот контент, пожалуйста, обязательно поделитесь им или зайдите поздороваться на мой сайт или в твиттер:

Оригинал: “https://dev.to/ruanbekker/why-you-should-use-multi-stage-docker-builds-571e”