Pull to refresh

Comments 75

В этом случаи теряется преимущество кеширования слоев — для образов с тяжелым рантаймом типа java придется перекачивать весь образ с этим одним слоем...

UFO just landed and posted this here
Это не обязательно говорит о проблемах. Часто надо настроить окружение для работы, и не всегда можно найти идеально подходящий образ. Вот и приходится брать наиболее близкий к тому, что надо, и докидывать туда недостоющие компоненты.
Если не нравятся простыни, то можно вынести их в отдельный образ и залить на докерхаб)) И рабочий докерфайл будет более чистым.
Ну или хотя бы в свой registry
Я думаю, что имелось в виду, что это костыль для управления слоями.
При правильно дизайне управление слоями было бы реализовано как-то по другому, например:

LAYER 1
RUN…
RUN…
COPY…

LAYER 2
RUN…
RUN…
COPY…
UFO just landed and posted this here
Там и в самой это простыне ад. curl, apt-get, gem install, bundle install… Вспоминается башорг. Только в случае докера это почему-то считается нормальным.
Да что уж там, сама по себе возможность легко получить работающее решение простым, понятным и неправильным способом − это уже проблема с дизайном.
Всё хорошо до просмотра логов. Нельзя пускать девов на ноды, пусть в сборщике логов их смотрят.
Но, есть же и локальный запуск, на компе дева.
Но, в общем я полностью согласен. Но, это бы удлинило статью. И немного, выходит за область рассматриваемой теме.
UFO just landed and posted this here
Тут не «завязывается на glibc», а собрано для glibc. Просто так взять бинарник для glibc и запустить на musl или практически любой другой реализации libc, не нацеленные на совместимость с glibc (всякие eglibc в расчёт не берём) не выйдет.
FROM ubuntu:latest


Использование тэга latest приводит к непредсказуемым последствиям.

а вот устанавливать пакеты последних версий это уже нормально, да?


apt-get -y install libpq-dev imagemagick gsfonts nodejs
Ну по факту, да пакеты тоже лучше ставить определенной версии. Тут вы правы.
UFO just landed and posted this here
Даже в случае своего registry, я не рекомендовал использовать тэг latest.

Допустим, базовый образ у вас используется в 10 микросервисах. Как только вы делаете новую версию базового образа, вам сразу же надо перетестировать все 10 микросервисов.
UFO just landed and posted this here
А зачем так усложнять? Можно же, базовый образ собирать с версией и делать рассылку, что появилась новая версия. Кому надо протестирует и обновит у себя версию тэга в dockerfile.
Нельзя. Потому что все забьют и никто ничего не будет обновлять.
Я не специалист — а можно старую версию из registry удалить?
Разумеется, после письменного уведомления.
UFO just landed and posted this here
Ну тогда и без проблем — SLO не распространяется на deprecated версии, которые, к слову, в любой момент могут быть удалены из registry из соображений целесообразности.

Наша команда с радостью поможет (покажет документацию) с апгрейдом!

Можно.
Но, по моему мнению, лучше донести до разработчиков необходимость и ценность своевременного обновления.
И это возможно, проверено))


Мне, не нравиться, любые механизмы, где что-либо происходит насильно.

> Мне, не нравиться, любые механизмы, где что-либо происходит насильно.

Это по-человечески понятно, но иногда консенсус невозможен — у какой-то команды релиз, им какая-то вещь нужна ну прям счас, и непременно на этой версии, а на апгрейд времени нет. И не было. Может, в конце года, после запуска. И вообще, у них приоритеты, что вы тут со своими апгрейдами, мы тут прибыль делаем (и дальше по списку).

Кстати, почитайте про liberum veto, к слову. Для общего, так сказать, развития.
UFO just landed and posted this here

Кажется, докеру тоже нужны свои лок-файлы...

Блин, я вот читаю такие статьи и вспоминаю, что совсем недавно вот совсем совсем недавно говорили, что цепочки вызовов команд это плохо, потому что это всё рассчитано только на успешный путь выполнения и для конфигурации системы нужно использовать ansible и идемпотентные скрипты декларативного характера.


И тут опять шелл скрипт для конфигурации системы, только в докере. Что же с нами стало? Как так вышло то? Почему это опять хорошо?

История циклична. Уверен, рано или поздно придумают "ansible для Dockerfile":)

Спасибо. Прикольно. Интересно, надо будет попробовать и протестировать.

А ведь с момента вброса идеи прошел всего час…

А тут разные ниши — Docker предполагает сборку нового артефакта, а не изменение существующего сервиса. Если что-то в цепочке падает — это повод сборке немедленно остановиться, заорать и заставить пересмотреть процесс сборки до того, как этот артефакт будет выкачен.

UFO just landed and posted this here

Можно конкретный пример, как правильный Ansible помог бы отдебажить такой плавающий баг в сравнении с правильным Docker-ом?

И "перезапустить, а потом проверять" — это правильный подход. Сначала быстро решить проблему с лежащим сервисов, потом копать причину.

UFO just landed and posted this here
UFO just landed and posted this here

Можно пример бага, пожалуйста?

UFO just landed and posted this here

Как ансибл бы решил проблему с битым пакетом в одном из зеркал?


Что значит "не успевал вытянуть зависимость" — у вас ограничение по времени на сборку докера? Или (фу-фу) зависимости подтягиваются в момент запуска контейнера? Как Ansible решил бы аналогичную проблему?

UFO just landed and posted this here

Ну вот в корневом комментарии противопоставляют Docker и Ansible — что-де опять шелл-скрипты вместо идемпотентого Ansible.


Вопрос в том, зачем здесь идемпотентность и логируемость и как она в конкретном случае иммутабельного артефакта, собираемого на CI, помогает решить проблему.


Пока ветка выглядит примерно так:


  • Ansible лучше
  • чем лучше?
  • чем Docker
    Не надо так.

По мне, тут вопрос не в том, что лучше ansible или Docker.
Это, все-таки разные инструменты. И вопрос, похож на: а что лучше помидоры или сотовый телефон.


Тут, идея, что bash портянки такое себе, и было бы круто собирать docker через yml.

было бы круто
Почему?

С мутабельными серверами и зоопарком систем — да, круто — не надо следить за исходным состоянием каждого индивидуального сервера.


Что даст дополнительный уровень абстракции в докерфайле, когда состояние гарантировано (если не делать глупости типа использования latest и apt-get update)?


Что будет точно хуже — дополнительная зависимость от версий плейбуков и отвалившееся кеширование слоев (как раз из-за того, что порядок действий не будет задан явно).

UFO just landed and posted this here

Что именно там перезапустят при упавшей сборке?

в debian-based имеджах apt-get install сам за собой чистит, отдельной команды не нужно
Сделал тесты, вы правы.
Но, все же, разработчики образа советуют выполнять: rm -rf /var/lib/apt/lists/*
lists — не то же самое, что и файлы пакетов, обновляются по apt-get update и их наличие требуется для последующего apt-get install, который с точки зрения apt может прилететь когда угодно, поэтому никто их удалять автоматически не будет.
Класс! Появилась ещё одна прослойка (я о Docker), а проблемы остались всё те же (тупенькие разрабы не вникающие в детали, потому что некогда разбираться)…
Кто-нибудь расскажет мне вообще для чего docker нужен-то?.. Это реторический вопрос админа старовера не нужно отвечать. Мне нужно просто выговориться.

Серьезно, у админа есть вопрос для чего нужен Docker? А что вы администрируете если не секрет?
Сколько у вас приложений? Предположу что Windows стек. Какой свежести у вас дистрибутивы?

Не уверен, что есть такая практика для ruby, но для дотнет обычно в одном образе билдят, а во втором запускают, предварительно скопировав артефакты:


FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build
WORKDIR /app

# copy csproj and restore as distinct layers
COPY *.sln .
COPY aspnetapp/*.csproj ./aspnetapp/
RUN dotnet restore

# copy everything else and build app
COPY aspnetapp/. ./aspnetapp/
WORKDIR /app/aspnetapp
RUN dotnet publish -c Release -o out

FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 AS runtime
WORKDIR /app
COPY --from=build /app/aspnetapp/out ./
ENTRYPOINT ["dotnet", "aspnetapp.dll"]

Не удобнее ли будет поступить так же, что бы не вычищать образ?

Для ruby, так не делают, а вот например для go, это заходит хорошо. Да и для любого языка, где на выходе вы получаете исполняемый файл.

Так же, такой подход, хорош когда надо скопировать статику на фронт.

Для тех случаев, когда продакшн-образ содержит только самое необходимое, также встречал вариант, когда существуют как минимум два образа:


1) минимальный — для запуска продакшна
2) с компилятором/исходниками/полным рантаймом/дебаггером (ненужное в зависимости от языка — вычеркнуть) — для локальной разработки

UFO just landed and posted this here
Для go у меня был такой вот Dockerfile:

FROM scratch
MAINTAINER Developer <developer@company.example>
COPY binary-artifact /
ENTRYPOINT ["/binary-artifact"]

Сам `binary-artifact` возникал в пайплайне bitbucket.
Тут, много обсуждали тэг latest. У него, есть еще одна особенность. Docker его кэширует, так же как и любой другой тэг. Как следствие, если вы соберете образ в двух местах с разными версиями кэша, то получите разные образы.
UFO just landed and posted this here
Ну и наконец, помнишь, в начале я говорил про идеологию Docker «один контейнер — один процесс»? Это означает, что supervisor не нужен. Так же не стоит устанавливать systemd, по тем же причинам. По сути, Docker сам является supervisor. И когда ты пытаешься запускать в нем несколько процессов, это как в одном процессе supervisor запускать несколько приложений.


У меня есть проект на node.js в Docker. Он запускается через pm2. Можно ли выкинуть pm2?

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

Не можно, а нужно.
Так же, как и в случае с супервизором, docker выполняет роль pm2

UFO just landed and posted this here
UFO just landed and posted this here

До тех пор, пока не пересобирать образ специально локально или в registry, меняться он не будет.

UFO just landed and posted this here

Не соглашусь с Вами. Базовый образ уменьшает гибкость, приводит к сложностям при необходимости внести изменения.
Единственное, что стоит сделать, это указать версию пакетов.
Так же, слой будет браться из кэша, до момента, пока команда RUN не будет изменена.

UFO just landed and posted this here
Sign up to leave a comment.