Чому зображення контейнерів Docker такі великі?


177

Я зробив просте зображення через Dockerfile від Fedora (спочатку 320 Мб).

Додано Nano (цей крихітний редактор розміром 1 Мб), а розмір зображення збільшився до 530 МБ. На додаток я додав Git (30 МБ), а потім розмір мого зображення-ракети з неба до 830 МБ.

Хіба це не божевільно?

Я намагався експортувати та імпортувати контейнер, щоб видалити історію / проміжні зображення. Ці зусилля заощадили до 25 Мб, тепер розмір мого зображення становить 804 Мб. Я також намагався запустити багато команд на одній RUN, але все одно я отримую ті ж початкові 830 МБ.

У мене виникають сумніви, чи варто взагалі використовувати Докера. Я маю на увазі, що я ледве нічого не встановив, і я забивав 1 Гб. Якщо мені доведеться додати якісь серйозні речі, такі як база даних тощо, у мене може не вистачити місця на диску.

Хтось страждає від смішного розміру зображень? Як ти з цим справляється?

Якщо мій Dockerfile жахливо невірний?

FROM fedora:latest
MAINTAINER Me NotYou <email@dot.com>
RUN yum -y install nano
RUN yum -y install git

але важко уявити, що тут може піти не так.


Де і як ви вимірюєте розмір свого контейнера? Чи впливає yum clean allякийсь розмір?
xeor

2
Очікуйте, що зображення буде хорошого розміру, оскільки це накопичення зображення, батьківських зображень та базового зображення. Крім того, yum встановлює не тільки зазначені додатки, але і їх залежності. docs.docker.com/terms/container
rexposadas

2
Ну і моє "вимірювання" - це виконання, docker imagesяке в останньому стовпчику повідомляє про здорові 830 Мб. Я, можливо, не знаю, що таке фактичний розмір мого зображення, оскільки команда docker images зазначає, що цей 830MB - це віртуальний розмір. Але знову ж таки, який фактичний розмір зображення?
Дзен

Відповіді:


118

Як сказав @rexposadas, зображення включають усі шари, і кожен шар включає всі залежності для того, що ви встановили. Важливо також зазначити, що базові зображення (як fedora:latestправило, є дуже голими. Ви можете бути здивовані кількістю залежностей від встановленого програмного забезпечення.

Я зміг зробити вашу установку значно меншою, додавши yum -y clean allдо кожного рядка:

FROM fedora:latest
RUN yum -y install nano && yum -y clean all
RUN yum -y install git && yum -y clean all

Важливо зробити це для кожного RUN, перш ніж шар буде здійснено, інакше видалення фактично не видаляє дані. Тобто, у файловій системі об'єднання / копіювання на запис чистка в кінці насправді не зменшує використання файлової системи, оскільки реальні дані вже присвячені нижчим шарам. Щоб обійти це, потрібно очистити кожен шар.

$ docker history bf5260c6651d
IMAGE               CREATED             CREATED BY                                      SIZE
bf5260c6651d        4 days ago          /bin/sh -c yum -y install git; yum -y clean a   260.7 MB
172743bd5d60        4 days ago          /bin/sh -c yum -y install nano; yum -y clean    12.39 MB
3f2fed40e4b0        2 weeks ago         /bin/sh -c #(nop) ADD file:cee1a4fcfcd00d18da   372.7 MB
fd241224e9cf        2 weeks ago         /bin/sh -c #(nop) MAINTAINER Lokesh Mandvekar   0 B
511136ea3c5a        12 months ago                                                       0 B

1
Дякую за ваші зусилля з розслідування справи, і так, я зміг зменшити розмір свого зображення приблизно до 635 МБ (це значення, представлене як розмір віртуального зображення після виконання docker images). Чи можливо видалити / видалити / знищити ці старі шари? Якщо бути більш конкретним: я хотів би повністю видалити (спираючись на ваш приклад) зображення: 172743bd5d60, 3f2fed40e4b0, fd241224e9cf, 511136ea3c5a з історії, щоб розмір мого віртуального зображення був більш-менш таким, як кінцевий розмір зображення, тут ~ 260 МБ .
Дзен

(Занадто довго для 1 коментаря) Якщо розмір віртуального зображення не має нічого спільного з фактичним розміром зображення на жорсткому диску? Якщо це так, то як / де перевірити фактичний розмір моїх зображень?
Дзен

Ви могли б docker exportі потім docker importзнову. Це дозволило б згладити шари. Я не думаю, що це зменшить розмір, але я можу помилитися.
Енді,

10
Так, але експорт не дуже економить. Тим не менш, я зміг прочитати через Інтернет, що те, що я можу спостерігати в докер, - це розмір віртуального зображення. Фактичний розмір жорсткого диска здається для мене загадкою, оскільки щодо офіційної інформації docker ps -sпоказує реальний розмір на жорсткому диску, який у моєму випадку був -1B. Це звучить розумно, мінус 1 байт . Я отримав трохи місця на HDD ... здається, законним.
Дзен

@Zen Вибачте, я не стежу за цим. Отже, віртуальний розмір і розмір диска - це дві різні речі? Що саме вимірює віртуальний розмір?
Джейсон

63

Образи докера не великі, ви просто створюєте великі зображення.

scratchЗображення 0B , і ви можете використовувати, щоб упакувати свій код , якщо ви можете скомпілювати код в статичний бінарний. Наприклад, ви можете скласти свою програму Go і упакувати її зверху,scratch щоб зробити повністю придатне для використання зображення розміром менше 5 Мб.

Головне - не використовувати офіційні зображення Docker, вони занадто великі. Scratch - це не все так практично, тому я б рекомендував використовувати Alpine Linux в якості базового зображення. Це ~ 5 Мб, тоді додайте лише те, що потрібно для вашої програми. Ця публікація про мікроконтейнери показує, як створити дуже маленьку базу зображень на Альпійському.

ОНОВЛЕННЯ: офіційні зображення Докера базуються на альпійській мові, тому їх добре використовувати зараз.


2
Чудове рішення !, Це так важливо, щоб зупинити відходи та бути безпечнішими ---> менше коду -> менше турбуватися.
Ран Давидовиц

1
На щастя, зображення Docker Official також переходять на альпійську базу, тому все більше і більше ви можете використовувати звичайні зображення, а не залежно від версій iron.io. Дивіться brianchristner.io/docker-is-moving-to-alpine-linux
Martijn Heemels

@Travis R, схоже, ваше посилання на повідомлення про мікроконтейнери перенесло кудись ще. Є чи це пост ви хотіли посилання?
Олександр Ф.

@AlexanderF. Виправлені посилання, дякую, що повідомили мені.
Тревіс Редер

28

Ось ще кілька дій, які ви можете зробити :

  • Уникайте кількох RUNкоманд, де можете. Покладіть стільки, скільки можливо, в одну RUNкоманду (використовуючи &&)
  • очищення непотрібних інструментів, таких як wget або git (які вам потрібні лише для завантаження чи складання матеріалів, але не для запуску процесу)

Завдяки цим І рекомендаціям від @Andy та @michau я зміг змінити розмір свого зображення nodejs від 1,062 ГБ до 542 МБ.

Редагування: Ще одна важлива річ: "Мені знадобилось певний час, щоб зрозуміти, що кожна команда Dockerfile створює новий контейнер з дельтами. [...] Не має значення, чи rm -rf файли в наступній команді; вони продовжують існувати в якомусь проміжному шарі ". Так що тепер мені вдалося поставити apt-get install, wget, npm install(з GIT залежностей) і apt-get removeв одній RUNкоманді, так що тепер моє зображення має тільки 438 МБ.

Редагувати 29.06.17

З Docker v17.06 з'являються нові функції для Dockerfiles: Ви можете мати кілька FROMзаяв всередині одного Dockerfile, і лише те, що останнє, FROMбуде в остаточному зображенні Docker. Це корисно для зменшення розміру зображення, наприклад:

FROM nodejs as builder
WORKDIR /var/my-project
RUN apt-get install ruby python git openssh gcc && \
    git clone my-project . && \
    npm install

FROM nodejs
COPY --from=builder /var/my-project /var/my-project

Це призведе до того, що зображення має лише базове зображення nodejs плюс вміст з / var / my-project з перших кроків - але без ruby, python, git, openssh та gcc!


22

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

Я зробив образ Ubuntu, який насправді мінімальний (на відміну від інших так званих "мінімальних" зображень). Він називається textlab/ubuntu-essentialі має 60 Мб.

FROM textlab/ubuntu-essential
RUN apt-get update && apt-get -y install nano

Наведене вище зображення становить 82 Мб після встановлення нано.

FROM textlab/ubuntu-essential
RUN apt-get update && apt-get -y install nano git

У Git є ще багато необхідних умов, тому зображення стає більшим, приблизно 192 МБ. Це ще менше, ніж початковий розмір більшості зображень.

Ви також можете подивитися на сценарій, який я написав, щоб зробити мінімальний образ Ubuntu для Docker . Ви можете, можливо, адаптувати його до Fedora, але я не впевнений, скільки ви зможете видалити.


13

Наступне мені дуже допомогло:

Після видалення невикористаних пакетів (наприклад, звільнено Redis 1200 mb) всередині мого контейнера я зробив наступне:

  1. експорт докера [контейнер ID] -o контейнер.tar
  2. docker import -m "тут зробити повідомлення", ім'я зображення image.tar: тег

Шари вирівнюються. Розмір нового зображення буде меншим, оскільки я видалив пакунки з контейнера, як зазначено вище.

На це знадобилося багато часу, щоб зрозуміти це, і саме тому я додав свій коментар.


Ви можете поєднати обидва етапи в один крокdocker export <CONTAINER ID> | docker import - some-image-name:latest
Ануй Кумар

8

Для кращої практики слід виконати одну команду RUN, оскільки кожна інструкція RUN в Dockerfile записує новий шар у зображенні, і кожен шар вимагає додаткового місця на диску. Щоб мінімізувати числові шари, будь-які маніпуляції з файлами, такі як встановлення, переміщення, вилучення, видалення тощо, в ідеалі повинні проводитися в рамках однієї інструкції RUN

FROM fedora:latest
RUN yum -y install nano git && yum -y clean all

4

Докер сквош - це справді приємне рішення цього питання. ви можете $packagemanager cleanна останньому кроці замість кожного рядка, а потім просто запустити докер сквош, щоб позбутися від усіх шарів.

https://github.com/jwilder/docker-squash


0

Так, система шарів досить дивно. Якщо ви маєте базове зображення і збільшуєте його, виконуючи наступні дії:

# Test
#
# VERSION       1

# use the centos base image provided by dotCloud
FROM centos7/wildfly
MAINTAINER JohnDo 

# Build it with: docker build -t "centos7/test" test/

# Change user into root
USER root

# Extract weblogic
RUN rm -rf /tmp/* \
    && rm -rf /wildfly/* 

Зображення має абсолютно однаковий розмір. Це по суті означає, що вам доведеться вводити в свої кроки RUN багато магії витягування, встановлення та очищення, щоб зробити зображення такими ж маленькими, як встановлене програмне забезпечення.

Це значно ускладнює життя ...

У dockerBuild відсутні дії RUN без комісій.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.