Dockerfile Idioms
Распространение контейнеров меньшего размера — это поведение, которое следует рекомендовать.
Контейнеры меньшего размера, более быстрый запуск, более быстрое распространение, более быстрое повторное использование… Для жизни быстрота — это отношение, которое означает, что ваше время более ценно: экономить время всегда правильно.
Несколько лет назад я действительно хотел написать об уменьшении контейнера, но в то время alpine не воспринимали всерьез, и его было сложно использовать отдельно, поэтому мы больше исследовали, как уменьшить окончательный размер на таком большом парне, как ubuntu. .
Отрадно, что принципы, которыми пользовались, всегда были верными.Хотя мир и эта экология меняются, принципы не изменились.
Сейчас есть много статей и много вопросов и ответов на тему уменьшения размера контейнера.
Но я все еще намерен написать один. Писатель, всегда чувствуй, что содержание написано немного, логично, со словом в одну точку, закрой лицо, ограничь язык. и т.п.
Однако в этот раз я напишу это вскользь и не планирую организовывать логику.
Checklist
Чтобы уменьшить окончательный размер контейнера, сначала рассмотрите следующий контрольный список:
-
Принять меньший пакет тестов
- В подавляющем большинстве случаев альпийский — лучший выбор.
- Distroless можно использовать в крайнем случае, но следствием является отсутствие оболочки и невозможность зайти в контейнер
- Иногда вы можете использовать busybox
-
Выберите наиболее подходящий пакет тестов.
- Для сервисов голанг,
alpine:latest
это лучший выбор- Но если вам нужны операции сборки golang, то
golang:alpine
может быть прав
- Но если вам нужны операции сборки golang, то
- Для серии Java это хороший выбор:
- anapsix/alpine-java
- frolvlad/alpine-java
- openjdk
- Они также могут относиться к:
- В любом случае, это огромный.
- После добавления SpringCloud это 2B.
- Выбор 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
Точно так же допь, не повторять их
Построить в несколько проходов
Хотя мемоизация управления пакетами идеально подходит для уменьшения размера контейнера, она не лишена недостатков:
-
вы должны быть в одном предложении
RUN
Запишите все скрипты для памяти и ликвидации памяти в контейнере.Если он разделен на несколько команд, то след ОС в контейнере все равно может быть уменьшен, но размер контейнера может не уменьшиться. -
если вы в одном предложении
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.
Результат по-прежнему разделен на главы, о моя добродетель