Идиома Dockerfile, вы должны распространять меньший контейнер

Docker

Dockerfile Idioms

Распространение контейнеров меньшего размера — это поведение, которое следует рекомендовать.

Контейнеры меньшего размера, более быстрый запуск, более быстрое распространение, более быстрое повторное использование… Для жизни быстрота — это отношение, которое означает, что ваше время более ценно: экономить время всегда правильно.

Несколько лет назад я действительно хотел написать об уменьшении контейнера, но в то время alpine не воспринимали всерьез, и его было сложно использовать отдельно, поэтому мы больше исследовали, как уменьшить окончательный размер на таком большом парне, как ubuntu. .

Отрадно, что принципы, которыми пользовались, всегда были верными.Хотя мир и эта экология меняются, принципы не изменились.

Сейчас есть много статей и много вопросов и ответов на тему уменьшения размера контейнера.

Но я все еще намерен написать один. Писатель, всегда чувствуй, что содержание написано немного, логично, со словом в одну точку, закрой лицо, ограничь язык. и т.п.

Однако в этот раз я напишу это вскользь и не планирую организовывать логику.

Checklist

Чтобы уменьшить окончательный размер контейнера, сначала рассмотрите следующий контрольный список:

  • Принять меньший пакет тестов

    • В подавляющем большинстве случаев альпийский — лучший выбор.
    • Distroless можно использовать в крайнем случае, но следствием является отсутствие оболочки и невозможность зайти в контейнер
    • Иногда вы можете использовать busybox
  • Выберите наиболее подходящий пакет тестов.

    • Для сервисов голанг,alpine:latestэто лучший выбор
      • Но если вам нужны операции сборки golang, тоgolang:alpineможет быть прав
    • Для серии Java это хороший выбор:
    • Для nodejs оптимальна версия alpine:node:8-alpine
    • Подождите, нет возможности перечислить по языку.
  • При использовании команды установки пакета не забудьте очистить индекс и установочный пакет, загруженный в процессе установки пакета.

    Я расскажу об этом позже в идиоме.

  • Удалить механизм подкачки памяти, удалить раздел подкачки

  • Не устанавливайте инструменты с зависимостями от ncurse, такие как mc

  • Не устанавливайте инструменты с инструментами отладки или свойствами инструментов отладки, такими как vim, curl. Вместо этого обязательно используйте nano и wget.

  • Отрегулируйте порядок команд, чтобы объединить одни и те же команды, что приведет к меньшему количеству слоев.

  • Уменьшите окончательный размер контейнера, используя функцию памяти для удаления пакетов, которые будут использоваться только в процессе упаковки.

    Эта функция памяти в основном относится кalpine apk --virtualфича; для apt есть инструмент apt-mark.

  • Для подходящего использованияapt install --no-install-recommends -yСпособ

  • Используйте многоэтапный процесс сборки, чтобы не допустить попадания упаковки и промежуточного содержимого в окончательный контейнер и уменьшить его размер.

Следующее основано на voxr vdeps-base для введения.

можно проконсультироватьсяGitHub.com/andnature/doc…

различные идиомы

Идиоматическое использование alpine apk

Более типичный подход таков:

RUN fetchDeps=" \
    		ca-certificates \
    		bash less nano iputils bind-tools busybox-extras \
    		wget lsof unzip \
    	"; \
    apk update \
    && apk --update add ${fetchDeps} \
    && apk info -vv | sort \
    && apk -v cache clean && rm /var/cache/apk/*
# 摘自 https://github.com/hedzr/docker-basics/blob/master/alpine-base/Dockerfile

apk -v cache cleanа такжеrm /var/cache/apk/*Вы можете выбрать один из двух, вот только пример.

Более точное и компактное решение, чем приведенный выше пример:

RUN build-deps="gcc
      freetype-dev \
      musl-dev \
      "; \
    apl add --update --no-cache bash less nano unzip && \
    apk add --no-cache --virtual .build-deps ${buildDeps} && \
    pip install --no-cache-dir requests && \
    apk del .build-deps && \
    rm /var/cache/apk/*

Примите внутренний зеркальный сервер для ускорения и более удобной структуры:

# 改编自 hedzr/docker-basics/golang-builder
RUN fetchDeps=" \
              ca-certificates \
            "; \
    buildDeps=" tig "; \
       cp /etc/apk/repositories /etc/apk/repositories.bak; \
       echo "http://mirrors.aliyun.com/alpine/v3.10/main/" > /etc/apk/repositories; \
       apk update \
    && apk add --virtual .build-deps ${buildDeps} \
    && apk add ${fetchDeps} \
    && echo
    && echo "Put your building scripts HERE" \
    && apk del .build-deps \
    && rm /var/cache/apk/* \

Идиомы debian apt

RUN fetchDeps=" \
    	   ca-certificates \
    	   wget nano vim.tiny net-tools iputils-ping lsof \
    	   dnsutils inetutils-telnet locales \
    	 "; \
       TZ=Etc/UTC; LOCALE=en_US.UTF-8; \
       apt update \
    && DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends ${fetchDeps} \
    && locale-gen $LOCALE \
    && cat /etc/default/locale && echo "Original TimeZone is: $(locale -a)" && date +'%z' \
    && ln -s /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ | tee /etc/timezone \
    && echo "Current TimeZone updated: $(locale -a)" && date +'%z' \
    # && apt-get purge -y --auto-remove ${fetchDeps} \
    && rm -rf /var/lib/apt/lists/*
# 时钟时区部分可以去掉
# 摘自 https://github.com/hedzr/docker-basics/blob/master/ubuntu-mod/Dockerfile

Для сценариев, использующих python pip, вы также можете сделать это:

RUN buildDeps="curl python-pip" && \
    apt-get update && \
    apt-get install -y --no-install-recommends $buildDeps && \
    pip install requests && \
    apt-get purge -y --auto-remove $buildDeps && \
    rm -rf /var/lib/apt/lists/*

Система build-essential или gcc может обрабатываться аналогичным образом:

RUN buildDeps="curl wget build-essentials flex bison make cmake autoconf automake git libtool" && \
    fetchDeps="nano wget curl"
    apt-get update && \
    apt-get install -y --no-install-recommends $fetchDeps && \
    AUTO_ADDED_PACKAGES=`apt-mark showauto` && \
    apt-get install -y --no-install-recommends $buildDeps && \
    mkdir build && cd build && cmake .. && make && make install && \
    apt-get purge -y --auto-remove $buildDeps $AUTO_ADDED_PACKAGES && \
    rm -rf /var/lib/apt/lists/*

Обратите внимание, что мы использовалиAUTO_ADDED_PACKAGESМеханизм, который является функцией памяти системы управления пакетами Debian, может быть использован для уменьшения размера.

Идиома системы yum для Centos

Точно так же допь, не повторять их

Построить в несколько проходов

Хотя мемоизация управления пакетами идеально подходит для уменьшения размера контейнера, она не лишена недостатков:

  1. вы должны быть в одном предложенииRUNЗапишите все скрипты для памяти и ликвидации памяти в контейнере.Если он разделен на несколько команд, то след ОС в контейнере все равно может быть уменьшен, но размер контейнера может не уменьшиться.

  2. если вы в одном предложенииRUNЕсли вы завершите весь сценарий сборки контейнера в команде, процесс разработки сборки будет очень болезненным, потому что длительная командная последовательность не может быть кэширована в нескольких слоях, поэтому каждое маленькое изменение приведет кdocker buildчтобы полностью восстановить ваш контейнер.

    Таким образом, уменьшение размера контейнера должно выполняться после разработки процесса сборки контейнера.

Хорошо, функция памяти немного несовершенна, но несколько проходов сборки прекрасно уравновешивают все это.

Взяв в качестве примера контейнеризацию приложений golang, ниже приведен пример многопроходной сборки:

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"]
# 摘自 https://github.com/alexellis/href-counter

Что ж, мой вариант намного сложнее, но я пока не могу его показать, а усложненная версия не годится для объяснения строения скелета.

конец

Пишите сюда, временно подходит к концу.

Вот и все о сокращении и идиомах Dockerfile. Нет ничего невозможного в том, чтобы выпустить что-то большее, но для этого может понадобиться нечто большее, чем просто знание Docker.

Результат по-прежнему разделен на главы, о моя добродетель