Moby: Сбросить свойства, унаследованные от родительского изображения

Созданный на 6 янв. 2014  ·  153Комментарии  ·  Источник: moby/moby

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

Это более общее решение для # 2210, которое касается только expose .

arebuilder kinenhancement statuneeds-attention

Самый полезный комментарий

Я определенно хотел бы иметь способ удалить точки VOLUME, унаследованные от родительских изображений.

Например, предположим, что у меня есть основной образ для приложения, которое использует внешнюю точку монтирования для постоянных данных, но мне также нужен образ на его основе, который вместо этого был предварительно заполнен тестовыми данными. Как есть, я не могу этого сделать, если родительский образ использовал VOLUME, потому что любые изменения / дополнения в этих каталогах, даже если эти изменения были внесены во время сборки докера, теряются при фиксации.

Все 153 Комментарий

Приветствуются предложения по синтаксису.

Лучшее, что я могу придумать, - это соответствующие команды, такие как UNVOLUME или, в более общем смысле, -VOLUME (но это добавило бы больше путаницы и, возможно, даже создало бы заблуждение, что +VOLUME должно работать, и должен работать иначе, чем просто VOLUME ).

Я очень определенно хочу такую ​​вещь (особенно для VOLUME). Также немного дезориентирует то, что такие вещи, как VOLUME, применяются к следующим строкам RUN, а такие вещи, как ENTRYPOINT - нет. Иногда это очень полезно, а иногда нет, но общая «отключить предыдущую инструкцию X» может довольно хорошо решить проблемы, связанные с этим.

Есть ли пока обходной путь для этого? Я расширяю изображение с помощью ENTRYPOINT (https://github.com/jagregory/pandoc-docker/blob/master/Dockerfile), и мне нужно отключить точку входа. Я пробовал использовать в своем Dockerfile следующее:

FROM jagregory/pandoc
ENTRYPOINT [] # this basically gets ignored (bug?)

FROM jagregory/pandoc
ENTRYPOINT [""] # this will make docker try to exec '' (the empty string)

FROM jagregory/pandoc
ENTRYPOINT ["/bin/sh", "-c"] 
# this will only work if docker run args are quoted:
#   docker run dergachev/pandoc "echo a b c"

Спасибо!

Я определенно хотел бы иметь способ удалить точки VOLUME, унаследованные от родительских изображений.

Например, предположим, что у меня есть основной образ для приложения, которое использует внешнюю точку монтирования для постоянных данных, но мне также нужен образ на его основе, который вместо этого был предварительно заполнен тестовыми данными. Как есть, я не могу этого сделать, если родительский образ использовал VOLUME, потому что любые изменения / дополнения в этих каталогах, даже если эти изменения были внесены во время сборки докера, теряются при фиксации.

Просто чтобы обновить комментарий @dergachev , CMD [] и ENTRYPOINT [] работали в последний раз, когда я их недавно тестировал, и все еще должны работать (все остальное было бы готово для регистрации ошибок).

Вы можете сбросить все команды с одним параметром через

ENTRYPOINT []
CMD []
USER 0
WORKDIR /

Это должно оставить оставшиеся, не сбрасываемые метаданные, как ENV , VOLUME , EXPOSE и, возможно, ONBUILD .

(Это из # 8709)

Если бы я открыл сокеты 9000-9002 в родительском элементе, но нужно было бы не раскрывать 9001 в дочернем, тогда мне пришлось бы писать в стиле "unsetting"

РАЗОБЛАЧАТЬ
EXPOSE 9000
EXPOSE 9002

который будет работать, но

UNEXPOSE 9001

выглядит лучше.

Преимущество состоит в том, что это не влияет на какие-либо EXPOSE, расположенные дальше по цепочке наследования, которые я, возможно, захочу добавить позже.

+1 @ codeon-nat

Это обсуждалось в # 8177, мы закрываем это из-за отсутствия реальных вариантов использования.

Почему это закрывается? Здесь комментировали 9 человек. Я думаю, это было бы действительно полезно. В реальных сценариях использования можно с легкостью использовать существующие образы. Иногда вы хотите добавить свойство, иногда вы хотите его удалить. Это нормально.

Я согласен, например, я расширяю изображение nginx для загрузчика SSL и хочу UNEXPOSE 80 но оставляю 443 .

Возможность не раскрывать порты очень важна, если вы хотите запустить несколько экземпляров, например, nginx.

Неважно, это была просто плохая конфигурация с моей стороны.

(15 апреля: «Нет реальных вариантов использования», я удивлен, что вы не можете вообразить хотя бы один и закрыли это)

У меня есть базовый образ, который предоставляет тома или порты для дополнительного программного обеспечения, а затем из него в другом Dockerfile, чтобы создать образ, который не должен открывать то, чего он не хочет, или даже вещи, которые он удалил из предка. Почему мы НЕ хотим удалять эти настройки?

У меня тоже есть вариант использования для этого. Я хочу иметь возможность создать изображение, содержащее моментальный снимок базы данных, но для всех пакетов mysql установлено значение VOLUME /var/lib/mysql . Было бы неплохо иметь возможность отключить громкость, чтобы изменения в базе данных, сделанные в моем Dockerfile, остались с изображением.

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

Добавление дополнительного варианта использования - я наследую от официального образа RabbitMQ, но я хочу открыть только порты веб-сокетов (80 и 443), а не порт AMQP по умолчанию (5672). Кажется, это должно быть вполне разумным поступком?

Добавление еще одного варианта использования. Я хочу создать тестовую среду git с использованием образа gogs, но сохранять данные утомительно, поскольку все они хранятся в томе. Было бы здорово, если бы я мог просто УМЕНИТЬ том и построить свой образ после настройки среды.

+1

наследуется от официального php и вы хотите использовать сокеты вместо портов, поэтому необходимо удалить открытый порт 9000

Любой, кто использовал Docker в нетривиальных целях, обнаружит эти ограничения в унаследованных контейнерах.

@shykes @icecrime, как это сейчас закрыто? Это слишком сложно решить с использованием текущего синтаксиса и необходимости обратной совместимости? Какой план?

+1 - здесь реальный вариант использования переопределения EXPOSE.

Учитывая, что это происходит уже более 3 лет (обнаружена проблема с 2013 года), когда мы сможем удалить открытые порты?

+1. необходимо иметь возможность "РАСКРЫТЬ" порты nginx по умолчанию 80 и 443.

Для тех, кто здесь просит UNEXPOSE ; EXPOSE утверждение дает лишь намек , какие порты подвергаются контейнером, но на самом деле не _expose_ этих портов; вам нужно _опубликовать_ эти порты ( -p / -P ), чтобы открыть их на хосте. Другими словами; исключение оператора EXPOSE из файла Docker не оказывает _no_ прямое влияние на изображение (вы все равно можете, например, достичь «порта 80» контейнера).

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

Верно, но если вы используете -P (чтобы открыть все порты) и ваше базовое изображение предоставляет порт, который вы больше не хотите открывать, то вы застряли. Вам нужно будет переключиться на использование -p и перечислить все остальные порты.

@thaJeztah , это полезно знать. Тем не менее, какой вред в добавлении UNEXPOSE? Это было бы полезно и для меня, даже если бы это было только для более документированных контейнеров.

@kgx без вреда (кроме возможного раздувания функций), но хотел объяснить, что невозможность «не раскрывать» не является проблемой безопасности (у некоторых людей такое впечатление). UNVOLUME (или UNSET VOLUME ) все еще в моем личном списке желаний. :-)

Я удивлен, что столкнулся с этой проблемой в первые 72 часа работы с докером. Каждая конфигурация или язык для любого другого основного инструмента, который я использую, который имеет какой-либо вид наследования, имеет возможность типа «переопределить родительский».

Вот пример использования: я использую образ докера по умолчанию для go-ethereum, и мне нужно иметь возможность настроить тестовую версию, которая абсолютно никогда не будет подключаться к внешнему миру. Мне нужно подключиться к нему с хоста и других контейнеров. Самый безопасный способ сделать это - изменить порты, потому что программа с нетерпением пытается подключиться к одноранговым узлам. Мне также нужно иметь возможность переопределить CMD и ENTRYPOINT, чтобы создать версию образа «для настройки базы данных», которую я запускаю один раз для создания правильного тома. Все это чрезвычайно сложно реализовать в Dockerfile.

Вы можете назначить его другому IP-адресу ... Или привязать другой порт хоста. Позже о переопределении точки входа и cmd нужно просто переопределить их.

--- Отправлено из Boxer | http://getboxer.com

20 февраля 2016 года в 08:57:00 по Гринвичу barkthins [email protected] написал: Вот пример использования: я использую образ докера по умолчанию для go-ethereum, и мне нужно настроить тест версия, которая абсолютно никогда не будет подключаться к внешнему миру. Мне нужно подключиться к нему с хоста и других контейнеров. Самый безопасный способ сделать это - изменить порты, потому что программа с нетерпением пытается подключиться к одноранговым узлам. Мне также нужно иметь возможность переопределить CMD и ENTRYPOINT, чтобы создать версию образа «для настройки базы данных», которую я запускаю один раз для создания правильного тома. Все это чрезвычайно сложно реализовать в Dockerfile. - Ответьте на это письмо напрямую или просмотрите его на GitHub.

CMD и ENTRYPOINT можно переопределить во время выполнения; docker run --entrypoint=foo myimage mycmd . Вопрос в том, полезно ли иметь другое изображение с другой точкой входа / cmd во время тестирования, поскольку вы не будете _тестировать_ фактическое изображение, которое будет запускаться в производственной среде. (просто примечание)

из этих ответов кажется, что dockerfile устарел в пользу параметров командной строки, по крайней мере, в отношении точки входа, cmd, expose и, возможно, некоторых других. Командная строка уже выполняет то, что Dockerfile не может сделать, так что, похоже, это направление. Если это намерение, то я перенесу как можно больше информации Dockerfile во время мгновенного создания, чтобы уменьшить путаницу. Это намерение?

@barkthins нет, Dockerfile не является устаревшим. Использование Dockerfile по-прежнему является обычным способом создания образа. Кроме того, вы можете переопределить CMD и ENTRYPOINT в унаследованных изображениях. Мой пример должен был показать, что в определенных случаях (например, при выполнении альтернативной команды на вашем изображении) вы можете переопределить их во время выполнения.

На странице руководства Dockerfile:

     -- EXPOSE <port> [<port>...]
     The EXPOSE instruction informs Docker that the container listens

на
указанные сетевые порты во время выполнения. Docker использует эту информацию для
соединять контейнеры с помощью ссылок и _для настройки порта
перенаправление на host_

  • система.*
    [...]
    ИСТОРИЯ
    * Май 2014 г., составлено Заком Дувером (zdover at redhat dot com) на основе
    в документации Dockerfile на docker.com. * Февраль 2015 г., обновлено Брайаном Гоффом (
    [email protected])
    для удобства чтения * сентябрь 2015 г., обновлено Салли О'Мэлли (
    [email protected])

[мой курсив] кажется вводящим в заблуждение (или, по крайней мере, двусмысленным), если то, что вы говорите,
истинный.

В чт, 28 января 2016 г., в 6:43, Себастьян ван Стейн <
[email protected]> написал:

Для тех людей, которые здесь просят НЕИСПОЛЬЗОВАНИЯ; только заявление EXPOSE
дает _hint_, какие порты доступны для контейнера, но не
фактически _expose_ эти порты; вам нужно _опубликовать_ эти порты (-p / -P)
выставить их на хосте. Другими словами; исключение оператора EXPOSE
из Dockerfile не имеет _не_ прямого воздействия на изображение (вы можете
все же, например, добраться до «порта 80» контейнера).

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

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/docker/docker/issues/3465#issuecomment -176012915.

В настоящее время соавтор книги о Docker: получите скидку 39% с кодом 39miell
http://manning.com/miell/?a_aid=zwischenzugs&a_bid=e0d48f62

thaJeztah Моя точка зрения, и я думаю, что точка зрения этой ветки заключается в том, что наследование несовместимо. Да, вы можете переопределить ENTRYPOINT и CMD, но EXPOSE добавляет экспозицию, вы не можете заменить родительскую экспозицию, кроме как в командной строке. Я не исследовал другие команды, чтобы увидеть, есть ли третье поведение. Также не задокументировано, какие команды расширяют или заменяют родительскую команду.

@thaJeztah нам нужно НЕРАЗБЫВАНИЕ

Есть несколько решений, которые считывают метаданные контейнера и обеспечивают дополнительную конфигурацию восходящего потока. Например; с HAPROXY мне нужно установить EXCLUDE_PORTS=8080 чтобы заблокировать его попытки динамически предоставить доступ к этому порту в моих приложениях Tomcat.

Разработчики смотрят на открытые порты и делают предположения о поведении контейнера. Например, у меня есть базовый образ, расширяющий Tomcat (EXPOSE 8080), но в образе используется порт, отличный от порта по умолчанию (EXPOSE 8888). Если вы добавляете веб-сервер в составной образ (например, запускаете NGINX и Tomcat), вы обслуживаете контент через HTTP (EXPOSE 80 и EXPOSE 443).

В последнем примере вы можете получить изображение, которое само документирует как экспонирование 8080, 8888, 80 и 443, где только 80/443 имеет значение.

Это реальные проблемы, о чем свидетельствует тот факт, что я должен постоянно объяснять вещи разработчикам в нашем сообществе, несмотря на очень конкретную документацию; Кому нужна документация, когда можно просто посмотреть на изображение? <- каждый, когда изображение самодокументирует не то.

Есть обходные пути для этой проблемы, но они есть обходные пути. Это серьезная архитектурная проблема? Почему Docker не может найти более элегантное решение этой реальной проблемы.

Каков статус по этому поводу?

Статус @BillBrower заключается в том, что они закрыли проблему без объяснения причин, по которым они считают, что это не проблема. Ясно, что для многих из нас это по-прежнему проблема реального мира, от которой страдает наша повседневная жизнь;)

@modius @BillBrower, даже если он закрыт, все всегда можно пересмотреть; в основном «нет - временно», но «да - навсегда» при объединении / реализации функций, поэтому, если есть сомнения по поводу функции, правильным выбором для сопровождающих будет сказать «нет».

PR, реализующий это, был закрыт, потому что некоторые сопровождающие не были уверены в этой функции и искали более актуальные примеры ее использования; https://github.com/docker/docker/pull/8177#issuecomment -93587164

Мы закрываем это, поскольку мы в основном не согласны, но, пожалуйста, не стесняйтесь доказывать, что мы неправы, в комментариях, и мы можем пересмотреть

Это было больше года назад, так что, возможно, все изменилось; Я снова открою эту проблему и подниму ее на следующей сессии сопровождающих. (Обратите внимание, что из-за DockerCon и ожидаемого выпуска 1.12 это может занять немного больше времени, чем обычно)

Спасибо, @thaJeztah. В этом есть большой смысл. Я признателен за то, что вы объяснили причину первоначального решения и обрисовали в общих чертах, что вам нужно увидеть, если мы хотим, чтобы это произошло.

Один вариант использования для запроса _UNVOLUME_

Тем более, что в настоящее время, когда вы используете настраиваемый драйвер тома, он применяется ко ВСЕМ объемам данного контейнера.

У меня был случай с драйвером тома EFS: отлично работает, когда я указываю привязку тома при запуске. Если я не устанавливаю привязку, это не удается, потому что он пытается смонтировать общий ресурс NFS из автоматически сгенерированного UUID. Это означает, что я должен предоставить привязку ко всем своим томам, даже к тому, который мне не важен, например, созданному родительским образом.

Единственный обходной путь прямо сейчас - привязать при запуске весь том, который мне не нужен, к пустой подпапке для мусора того же общего ресурса EFS.

Примечание: я не могу использовать команду docker volume, потому что все это запускается Marathon и должно использоваться в одной команде запуска docker.

Требуется +1 UNEXPOSE

+1 за UNEXPOSE

+1 за UNEXPOSE

+1 за UNEXPOSE

+100 за UNEXPOSE

+9000 за UNEXPOSE

+ ∞
Например, я использую официальный репозиторий nginx (ОТ nginx: stable) , который содержит в Dockerfile:

EXPOSE 80 443

Но я хочу удалить порт 80 на другой уровень. Например:

UNEXPOSE 80

Пожалуйста!
Добавьте эту функцию !!!!

@frekele , если бы я был твоей матерью или отцом, ты бы не получил. ни за что.

НЕПРЕРЫВНЫЙ +++
Очень нужная фича!

Пожалуйста, вам не нужно спамить всех остальных уведомлениями по электронной почте, и вам определенно не нужно загромождать обсуждение всеми этими комментариями «+1». Вы можете просто отреагировать с помощью 👍 на описание проблемы, чтобы выразить свое согласие.

@underyx, это оффтоп, но я
См. Https://github.com/isaacs/github/issues/9#issuecomment -195120703 (весь поток хорош, но это примерно то время, когда GH добавил реакции).
А теперь не будем загромождать обсуждение;)
/offtopic .

Мы обсуждали этот вопрос на собрании сопровождающих, и в целом, мы готовы снова начать работать над этим.

@duglin , возможно, тебе интересно поработать над этим?

Не знаю, есть ли у меня еще время, но просто подведу итоги .... на основе приведенных выше комментариев я считаю, что требуется обеспечить, чтобы люди могли очистить / отключить следующее:

EXPOSE  (all or specific one)
ENV  (specific - not sure we need to clear all yet)
LABEL  (ditto)
VOLUME  (all or just specific paths? probably both)
CMD  (possible but only using the json format)
ENTRYPOINT  (possible with json format)

Я что-нибудь пропустил?

+10000 для UNVOLUME

@duglin Я думаю, что EXPOSE , VOLUME ). Я не видел много просьб о других (но не против).

Первоначальный PR использовал UNSET <SOMETHING> , но позже был изменен на UN<SOMETHING> . Мне лично_ понравился первый (более общий), но @shykes предпочел UN<SOMETHING> , не уверен, что это изменилось.

UNVOLUME было бы неплохо.

Мой вариант использования: я использую изображение mysql и хочу зафиксировать свою базу данных, содержащуюся в каталоге /var/lib/mysql в новый образ, но не могу, потому что он объявлен томом в родительском Dockerfile.

@thaJeztah Я считаю, что UNSET <something> легче читать и не так странно; не нужно начинать придумывать слова. Это также знакомо людям, пишущим скрипты. Можно также сделать

UNSET  EXPOSE VOLUME LABEL

Мой пример,

Настраиваю установку dokuwiki. На выбранном мной изображении были показаны все потенциальные объемы конфигурации. Что я хотел бы сделать, так это настроить свою установку из этого базового образа. Поскольку тома открыты, я не могу изменять файлы конфигурации PHP во время сборки образа.

Я могу изменить базовый образ, чтобы ОБЪЕМ эти тома, но тогда мне нужно будет поддерживать этот образ вечно ... волшебство использования «последнего» исчезло :(

+1 за UNEXPOSE :)

+1 за UNVOLUME или еще лучше UNSET VOLUME.

+1 за UNVOLUME. Это могло быть полезно для меня прямо сейчас. Также может быть полезно в университетских сценариях, где студенты раскручивают, не беспокоясь о необходимости монтировать тома.

не беспокоясь о монтировании томов.

Не думаю, что для этого понадобится; определение VOLUME в Dockerfile автоматически создает «анонимный» том из содержимого в этом месте изображения.

@duglin , ты уже над этим работаешь? Если нет, я бы взял и начал с наиболее востребованных (ГРОМКОСТЬ и ЭКСПОЗИЦИЯ). Дай мне знать.

@runcom дерзай - пока не нашел времени.

В качестве напоминания следует отметить, что команда UNENV прежнему будет полезна для выборочного сброса переменных среды (например, для сопоставления с объемом, который одновременно равен UNVOLUME d). Неустановленная переменная - это не то же самое, что переменная, для которой установлено пустое значение, особенно при использовании с set -ue в оболочке.

Было бы возможно удалить VOLUME и EXPOSE из официальных изображений, если
они проблема.

28 января 2017 г. в 21:23 "henryptung" [email protected] написал:

Напоминаем, что команда UNENV по-прежнему может быть полезна для
выборочно сбрасывать переменные среды (например, чтобы они соответствовали
объем, который одновременно ОБНОВЛЯЕТСЯ). Неустановленная переменная не является
То же, что и пустая переменная, особенно при использовании с set -ue в
оболочка.

-
Вы получаете это, потому что подписаны на эту беседу.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/docker/docker/issues/3465#issuecomment-275875623 или отключить звук
нить
https://github.com/notifications/unsubscribe-auth/AAdcPAKP1tii706MY-8MxVPSFLTFme8Dks5rW7HggaJpZM4BXt2-
.

+1 за UNVOLUME

+1 за UNVOLUME

Мой вариант использования UNVOLUME:

Использование образа библиотеки / worpress в сценарии S2I, где исходный код веб-сайта копируется в / var / www / html

VOLUME подавляет это, устанавливая пустую файловую систему на получившееся изображение. -> нельзя использовать библиотеку / wordpress.

@groulot На самом деле, если вы не монтируете том явно с помощью --volume над ним, содержимое изображения будет скопировано в том при создании контейнера.

Команда docker run инициализирует вновь созданный том любыми данными, которые существуют в указанном месте в базовом образе.

https://docs.docker.com/engine/reference/builder/#/volume

Существует хакерский обходной путь с использованием docker save / load, см. Http://stackoverflow.com/q/42316614/808723

+1 за UNVOLUME

Я хочу повторить объяснение @modius возможности UN-EXPOSE. Одна из первых вещей, на которые разработчики цепляются при изучении докеров, - это набирать docker ps чтобы увидеть, что происходит с их контейнерами. Они увидят, что стандартный порт указан как доступный. Разработчики привыкли к стандартным портам для вещей из своих локальных или тестовых сред, которые они настроили в мире до Docker, поэтому внедрить Docker сложно, потому что они видят стандартный порт и полагают, что он будет работать, но на самом деле они не подключается к док-контейнеру.

+1 для UNVOLUME, UNEXPOSE, UNENV, ...

Похоже, это было открыто какое-то время. Есть ли здесь тяга?
Я также хочу использовать официальный образ PHP fpm alpine и сокеты UNIX вместо TCP-порта 9000.
Невозможно переопределить EXPOSE от родителя, и не хотелось бы строить это изображение только для того, чтобы избавиться от EXPOSE.

+1

+1

Хотелось бы иметь возможность отключить команду ГРОМКОСТЬ. Официальный образ Wordpress принудительно выгружает свою полную кодовую базу в том - я бы предпочел иметь только том для каталога wp-content / uploads, чтобы остальная часть кодовой базы могла быть встроена в изображение.

При развертывании образа в кластере kubernetes, который ограничивает корневой доступ, доступ к каталогам VOLUME невозможен, решением будет перезапись томов, определенных в родительском образе.

+1 от меня

Пример использования UNEXPOSE

Предположим, у меня есть четыре хоста докеров, и я хочу запустить 16 контейнеров maven tomcat, которые по умолчанию используют внутренний порт 8080.

Теперь представьте, что я использую регистратор с CNI владельца ранчо, который блокирует меня до внутреннего порта.
https://github.com/gliderlabs/registrator/issues/541#issuecomment -305012416
Это означает, что я могу запустить только один внутренний порт 8080 на хост. (Поскольку мне нужно выполнить сопоставление портов 8080: 8080)

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

Джулиан, я не знаю, как у вас есть сопоставление 1 к 1. Для меня регистратор как
не имеет ничего общего с маршрутизацией трафика, он просто регистрирует и отменяет регистрацию
запущенные контейнеры. Например, я использую его так, как регистратор будет поддерживать
экземпляр Etcd, поместив выделенный Docker IP и открытый порт в
там. Затем с помощью confd он будет наблюдать за экземпляром Etcd и обновлять nginx
config в собственном контейнере.
В субботу, 17 июня 2017 г., в 04:06, Джулиан Гэмбл [email protected]
написал:

Пример использования UNEXPOSE

Предположим, у меня есть четыре хоста докеров, и я хочу запустить 16 maven tomcat
контейнеры, которые по умолчанию используют внутренний порт 8080.

А теперь представьте, что я использую регистратор с владельцем ранчо CNI, что блокирует меня.
к внутреннему порту.
gliderlabs / registrator # 541 (комментарий)
https://github.com/gliderlabs/registrator/issues/541#issuecomment-305012416
Это означает, что я могу запустить только один внутренний порт 8080 на хост. (Поскольку у меня
сделать 8080: сопоставление портов 8080)

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

-
Вы получили это, потому что прокомментировали.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/moby/moby/issues/3465#issuecomment-309189149 или отключить звук
нить
https://github.com/notifications/unsubscribe-auth/ABrq2QGgY81wbePOBKbkTSjpUSoPIocuks5sE0LCgaJpZM4BXt2-
.

Привет Брэдли,

Спасибо, что посмотрели на это. Я использую регистратор в сочетании с ipsecurity, встроенной в Rancher. Как видно по ссылке здесь:
https://github.com/gliderlabs/registrator/issues/541#issuecomment -305012416
Возможность просмотра внешних портов в регистраторе в запланированных контейнерах ранчера была ограничена. Это означало, что вы могли использовать только внутренние порты.

Вы можете видеть, что некоторые пользователи нервничают в поисках решения здесь:
https://forums.rancher.com/t/do-you-kill-registrator/5152

И предлагаемое решение здесь:
https://github.com/cabrinoob/rancher-registrator
(Что было невыполнимо для некоторых людей).

Вы можете найти больше, если вы введете в Google поиск "владелец ранчо регистратора".

Они рекомендуют вам запускать регистратор во «внутреннем» режиме, когда вы сопоставляете внутренние порты 1: 1 с внешними портами. Это приводит к проблеме с UNEXPOSE - быстро заканчиваются внутренние порты.

Я хочу сказать, что ipsecurity, используемая для внутрихостовой сети контейнеров докеров, может привести к варианту использования, когда вы заблокированы во внутренних портах, сопоставленных 1: 1 с внешними портами в докере. Для этого вам понадобится команда UNEXPOSE .

Спасибо, что посмотрели на это.

Ваше здоровье
Юлиан

Прошло 3,5 года, а прогресса в этом вопросе нет? ...

+10086 для UNEXPOSE. иногда родительский образ может быть неофициальным, он использует неофициальные порты, у нас должна быть возможность перезаписывать порты.

@ pumba-lt
Бьюсь об заклад, причина отсутствия разрешения в том, что они не знают, как это сделать технически.

Это также усложняет язык Dockerfile, когда есть четкие обходные пути. Не помещайте слишком много конфигурации в родительский Dockerfile и вместо этого оставьте if для наследующих изображений. (также известный как: прекратить поиск случайных изображений в Docker Hub: D)

Начиная с docker 17.05, появился новый способ делать многоступенчатые сборки, который устраняет большую часть необходимости в этой проблеме (это один Dockerfile ):

# First import the original image
FROM nginx AS source-image

# Second step of the build, start with an empty image
FROM scratch
# Copy the data from the original image
COPY --from=source-image / /
# Re-define all the config
EXPOSE 80
STOPSIGNAL SIGTERM
CMD ["nginx", "-g", "daemon off;"]

РЕДАКТИРОВАТЬ: Забыл сказать, второе решение раздавливает все предыдущие слои. Я не думаю, что это имеет большое значение, но это полезно знать.

@zimbatm - Это

Бьюсь об заклад, причина отсутствия разрешения в том, что они не знают, как это сделать технически.

Само изменение не слишком сложное; реализацию можно найти в этом PR; https://github.com/moby/moby/pull/8177. В то время консенсуса не было, но если вы последуете за моим январским комментарием; https://github.com/moby/moby/issues/3465#issuecomment -247405438, все изменилось, и (если с тех пор люди не передумали) мы примем участие в реализации этого.

Что касается того, почему его еще нет; просто потому, что никто не успел начать над ней работать, но если кому-то интересно, скорее всего, она будет принята.

@zimbatm да, ваш пример решит прямую проблему, просто имейте в виду, что он также создает другой слой и сглаживает все слои изображения. Хотя в некоторых случаях это может уменьшить размер изображения, это также приводит к тому, что эти слои больше не используются совместно с изображениями, которые используют nginx качестве родительского, что может привести к необходимости загрузки большего количества изображений. Например;

Исходный образ nginx:

$ docker inspect nginx -f '{{json .RootFS.Layers}}' | jq .

[
  "sha256:54522c622682789028c72c5ba0b081d42a962b406cbc1eb35f3175c646ebf4dc",
  "sha256:1c3fae42c5007fd0e70309b5b964eb5d49046562bd425424da734784098894e7",
  "sha256:87823f21b7939eac6e099fa878871a806c1904a7698793edb63bf6e5f5371e1f"
]

И созданный вами образ nginx;

$ docker inspect nginx2 -f '{{json .RootFS.Layers}}' | jq .
[
  "sha256:9a71ba430225d4f24e0d57837a71b6b2b68bf88ca7530c0a89c98783c98531b5"
]

Спасибо за обновление @thaJeztah

Могу я повторить свое предложение использовать

UNSET XXXX

вместо того, чтобы придумывать новые и необычные словарные слова (например, UNVOLUME).

Таким же образом мы могли бы отключить несколько свойств в одной строке.

UNSET VOLUME EXPOSE LABEL

Я лично не против делать UNSET делать то или другое, вероятно, не будет большим изменением, поэтому я оставлю это для процесса проверки, когда прибудет PR.

Привет, даже если использовать FROM во второй раз, как мне сохранить все из родительского образа, но не открывать некоторые из портов, представленных в родительском образе докера? есть ли какое-либо официальное решение по этому поводу, давайте либо примем это и поработаем, либо отклоним

давайте либо примем это и работаем, либо отклоним

@rajiff см. мой комментарий выше https://github.com/moby/moby/issues/3465#issuecomment -313549657 вклады приветствуются

Само изменение не слишком сложное; реализацию можно найти в этом PR; № 8177. В то время консенсуса не было, но если вы последуете за моим январским комментарием; # 3465 (комментарий), все изменилось, и (если с тех пор люди не передумали) мы примем участие в реализации этого.

Итак, если консенсус мог измениться, почему бы просто не открыть заново # 8177 ?

Итак, если консенсус мог измениться, почему бы просто не открыть заново # 8177?

Этот PR был открыт более трех лет назад; код больше не применяется

Вместо того, чтобы специально использовать команду UNsomething,
почему бы не улучшить команду FROM и сделать возможным перечисление того, что мы действительно хотим унаследовать?

Мы могли бы использовать что-то вроде:
ИЗ базового изображения (ГРОМКОСТЬ, ЭКСПОЗИЦИЯ, ПОРТ, ..)
или если вы действительно этого хотите с отрицанием:
ИЗ baseimage (*, -VOLUME, -EXPOSE)
или лучше синтаксис;)

Мне кажется, что все это в первую очередь должно быть частью команды FROM.

Изменение тома из Dockerfile: если какие-либо шаги сборки изменяют данные в томе после того, как он был объявлен, эти изменения будут отменены.

Это не совсем правда. Вы все еще можете сделать это:

VOLUME /avolume/subdir
WORKDIR /avolume
COPY ./Dockerfile /avolume/subdir

Я не знаю, можно ли его использовать для отмены тома.

Переопределение родительского изображения / контейнера ENTRYPOINT не работает в последних версиях.

17.09.1-ce версия

$ docker run --name=experiment --entrypoint=/bin/bash ubuntu:16.04
$ docker inspect experiment --format "{{.Config.Entrypoint}}"
[/bin/bash]
$ IMAGE=$(docker commit -c "ENTRYPOINT []" experiment)
$ docker inspect $IMAGE --format "{{.Config.Entrypoint}}"
[]

поскольку 17.10.0-ce версия

$ docker run --name=experiment --entrypoint=/bin/bash ubuntu:16.04
$ docker inspect experiment --format "{{.Config.Entrypoint}}"
[/bin/bash]
$ IMAGE=$(docker commit -c "ENTRYPOINT []" experiment)
$ docker inspect $IMAGE --format "{{.Config.Entrypoint}}"
[/bin/bash]

UNSET ENTRYPOINT тоже не работает.
Это ошибка?

@ alexey-igrychev, можно отдельную тему для этого? Проблема, которую вы комментируете, - это _feature request_ для реализации инструкций UNSET xx в Dockerfile. (Инструкция UNSET еще не реализована, так что это ожидается.)

В качестве обходного пути для этой проблемы, похоже, работает использование [""] вместо [] для точки входа;

IMAGE=$(docker commit -c "ENTRYPOINT [\"\"]" experiment)
docker inspect $IMAGE --format "{{.Config.Entrypoint}}"
[]

Мне также нужен способ сбросить громкость, чтобы я мог создать образ базы данных, предварительно загруженный таблицами и данными.
К сожалению, базовый образ является частным (оракул), и поэтому я даже не могу скопировать базовый файл докеров, поскольку у меня нет к нему доступа. Могу только растянуть изображение.
В этом выпуске перечислено множество +1 и реальных случаев использования, и было сделано несколько PR, но все же PR были закрыты. Итак, что нам нужно сделать, чтобы получить эту функцию?

@veqryn с тех открыта , никто не начал работать над запросом на

См. Мои предыдущие комментарии; https://github.com/moby/moby/issues/3465#issuecomment -247405438

Мы обсуждали этот вопрос на собрании сопровождающих, и в целом, мы готовы снова начать работать над этим.

@duglin , возможно, тебе интересно поработать над этим?

И https://github.com/moby/moby/issues/3465#issuecomment -313549657

Что касается того, почему его еще нет; просто потому, что никто не успел начать над ней работать, но если кому-то интересно, скорее всего, она будет принята.

Мой вариант использования исходит из docker-compose.yaml: я хотел бы иметь файл компоновки для разработки с переопределениями для производства, которые добавляют обратный прокси TLS, репозиторий Maven, берет на себя ПОРТ 80/443, не раскрывает порт 80 и 5432, который файл создания компоновки раскрывает. Или создать файл для производства с переопределением разработки.

Унаследованные от Dockerfiles файлы компоновки слоев только надстройки усложняют проектирование системы. Было бы действительно здорово, если бы некоторые параметры можно было отозвать, или если бы я просто построил другой контейнер с активными переопределениями. Я не разборчив в том, как это работает под капотом docker-compose.

Спасибо @thaJeztah - не могли бы вы указать нам на строку кода, которая, по вашему мнению, является местом, с которого нужно начать читать, чтобы посмотреть, как исправить это с помощью запроса на перенос?

Я сам мало работал над кодом компоновщика, но изменения, скорее всего, должны быть в пакете https://github.com/moby/moby/tree/master/builder .

Этому выпуску уже 3 года! Неужели так сложно договориться о такой базовой функции, или я что-то упускаю?

@caruccio да, вам чего-то не хватает: прокрутите 4 комментария вверх https://github.com/moby/moby/issues/3465#issuecomment -356988520

У меня также есть несколько вариантов использования (один для личного проекта, а второй - для рабочего), в которых я хочу перегрузить операторы VOLUME , EXPOSE и ENTRYPOINT из оператора родительский образ.

Хотя у меня есть обходной путь для ENTRYPOINT , просто установив новую пустую точку входа с помощью ENTRYPOINT [] , и я, вероятно, могу научиться жить с игнорированием EXPOSE , ... Я остаюсь царапины моя голова о том, как не наследовать определения VOLUME .

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

Есть временное решение.

Вы всегда можете docker save image -o image.tar , распаковать этот архив, отредактировать метаданные и перепаковать его для получения docker load -i image2.tar . Таким образом можно создать image2, в котором нет ни одного из предыдущих объявлений VOLUME.

Поскольку мне приходится делать эти шаги довольно регулярно, я создал небольшой скрипт, который поможет с очисткой стороннего образа. Взгляните на docker-copyedit

Фантастическая работа @gdraheim ! Работоспособное решение на <250 строках Python.

@gdraheim вау, это здорово! Из README:

Желание УДАЛИТЬ ВСЕ ОБЪЕМЫ возникло из-за того, что я действительно хотел загрузить протестированное изображение для локальных тестов, где часть данных также должна быть сохранена в истории, чтобы вернуть как программу, так и данные в определенное состояние, чтобы другой тестовый запуск начнется с той же контрольной точки.

Это и наш вариант использования.

Я расширил docker-copyedit, чтобы охватить все записи метаданных изображения, поэтому он может работать со всеми унаследованными свойствами даже за пределами проблемных случаев списков EXPOSE и VOLUME. Это будут настройки user, workingdir, label, env для часто встречающихся вещей. Копирование ENTRYPOINT в CMD - это тоже модификация, которую я делаю довольно часто. Больше не нужно делать промежуточный этап сборки докера, просто перейдите на docker-copyedit . ;)

Времени, затраченного командой Docker на отслеживание и неоднократное игнорирование этой проблемы, вероятно, было бы достаточно, чтобы исправить ее.

Можем ли мы теперь снова открыть это после того, как, очевидно, тонна пользователей запросила это ...
или, по крайней мере, дать разумный аргумент против этого, а не просто игнорировать все варианты использования (я тоже хочу не раскрывать порт и только для того, чтобы получить более чистый вывод docker ps без чертовски (80/80 / tcp) bevore, я создам свой собственный образ .. .. (что сложнее для файлов Docker без открытого исходного кода)

Вопрос все еще открыт; Это открытый исходный код; взносы приветствуются https://github.com/moby/moby/issues/3465#issuecomment -356988520

Правильно ли я думаю, что теперь это будет исправлено в moby / buildkit ? Я вижу там большую часть инфраструктуры команд Dockerfile .

Я тоже фанат UNSET , вроде

UNSET EXPOSE 9000

или

UNSET LABEL foo

Итак, я смотрю на команды, которые имеют формы подкоманд, такие как форма HEALTHCHECK CMD и я замечаю, что HEALTHCHECK уже имеет неустановленную форму ...

HEALTHCHECK NONE

Это интересный выбор, но HEALTHCHECK также определяет только 1 конфигурацию (и заменяет самую новую), он не позволяет определять несколько, например LABEL , EXPOSE , и VOLUME do.

Мне просто интересно, как они должны взаимодействовать, и есть ли какая-то другая форма NONE которая может работать.

Какой-то способ удалить открытые порты действительно необходим для управления тем, что открывается при использовании сети хоста.

+1 EXPOSE []

Итак .... за 5 лет работы команды Docker, которая не смогла реализовать оператор UNSET, фантастика

Как сказал @AnthonyMastrean , следует ли переместить эту проблему в проект moby/buildkit ?

Существует также PR, хорошо задокументированный и протестированный, но не объединенный, стоит ли нам перемещать / переустанавливать и этот PR?

Эта функция была бы очень полезна и решила бы проблему с изображениями на основе nginx в Azure.

UNSET , CLEAR , RESET , OVERRIDE , IGNORE было бы нормально - я бы избегал UNxxx потому что это Дублирую список зарезервированных ключей для поддержки и документирования.

Что игнорировать / сбросить также можно указать при использовании FROM , например

FROM nginx:1.13 IGNORE EXPOSE, ENTRYPOINT

Предлагаю еще один обходной путь - использовать многоступенчатые сборки.
Он скопирует все файлы из исходного изображения в новое изображение, но без метаданных.

FROM postgres as orig

FROM alpine:3.8 as postgres
COPY --from=orig / /
ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 5432
CMD ["postgres"]

Не могу поверить, что не подумал об этом. Это действительно неплохо @kotofos. Вы теряете слои вышестоящего контейнера, но это не большая потеря.

@kotofos Почему не FROM scratch as postgres ?

@farcaller хороший улов. царапина определенно будет лучше, так как вы перезаписываете всю файловую систему

Последнее, что я тестировал, COPY --from=xxx ... не сохранит файловую систему
владение, так что вы можете быть осторожны с этим обходным путем.

@tianon Вы правы, хотя для однопроцессных контейнеров это не должно быть проблемой, поскольку вы можете использовать флаг --chown чтобы установить пользователя, которого вы выполняете, как в контейнере

https://docs.docker.com/engine/reference/builder/#copy

Это восходит к 2014 году. Прошло 5 лет, и похоже, что в ближайшем будущем не будет общего «сброса» или «сброса» для всех свойств. Я также предпочитаю общий подход, но есть еще много вещей, которые следует учитывать, и на самом деле: это произойдет не в ближайшее время.

Итак: можем ли мы, по крайней мере, получить «UNEXPOSE», чтобы закрыть все эти открытые порты, или получить, по крайней мере, такое же поведение, как для CMD и ENTRYPOINT (последний из них побеждает)? Это свойство «unset» наиболее востребовано и представляет потенциальную угрозу безопасности для пользователей, не подозревающих о (не интуитивно понятном) поведении, учитывая поведение «побеждает последний» от других команд.

Предлагаю еще один обходной путь - использовать многоступенчатые сборки.
Он скопирует все файлы из исходного изображения в новое изображение, но без метаданных.

FROM postgres as orig

FROM alpine:3.8 as postgres
COPY --from=orig / /
ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 5432
CMD ["postgres"]

Я хотел игнорировать том докера, на который указывает PGDATA чтобы его содержимое могло быть связано с изображением, а не как том.
Более легким решением для меня было просто изменить значение PGDATA :

FROM postgres:11.2-alpine
ENV PGDATA /var/lib/postgresql/test-data

# stuff that will create all my schemas
COPY create-scripts /docker-entrypoint-initdb.d/

# a weird way to trigger the entrypoint script to run the stuff in docker-entrypoint-initdb.d but not hang after starting postgres
RUN /docker-entrypoint.sh postgres --version

Есть ли вообще какая-то польза от наличия EXPOSE и VOLUME в файлах докеров? В конце концов, вы можете легко определить их в docker run (и в docker-compose файлах), с помощью --expose (или -p ) и именованных томов или привязки монтирования. Меня укусили из-за них более одного раза, и нет возможности их сбросить (создание нового файла докеров не очень жизнеспособно, особенно при расширении официальных образов или образов, созданных с помощью файлов makefile). Я считаю их антипаттерном и думаю, что было бы лучше отказаться от них.

@lucasbasquerotto EXPOSE используется такими инструментами, как gitlab-runner, для определения того, открыты ли порты, указанные в изображении, на самом деле. Я согласен с тем, что это должно быть скорее обязанностью HEALTHCHECK, чтобы определить, готов контейнер или нет, но наличие списка объявленных портов действительно может быть полезно для автоматизации.
VOLUME необходим для обеспечения удобной остановки / запуска контейнера и автоматического сохранения данных. Опять же, я думаю, что это можно решить каким-то другим способом, но наличие проверяемых данных полезно для инструментария (и для людей тоже в этом случае).

ps не защищая синтаксис Dockerfile, я просто указываю, что анти-шаблоны не вызваны самими ключевыми словами, а скорее потому, что экосистема не продвигается вперед для решения проблем, которые могут возникнуть в общем случае использования, таком как этот, или например, предоставление изображения с объявленным объемом и некоторыми начальными данными в томе (например, изображение mysql с предварительно загруженной схемой)

@zarelit Я не знаю точно, как работает gitlab-runner , но я думаю, что должен быть способ указать порты, которые нужно проверять за пределами Dockerfile (я обнаружил проблему, которая, вероятно, связана с этим, потому что MySQL предоставляет 2 порта, но он должен проверять только порт 3306: https://gitlab.com/gitlab-org/gitlab-runner/issues/4143). Насколько я понимаю, он также использует только открытый порт последнего Dockerfile.

Что касается VOLUME , вы можете сохранить данные с отслеживанием состояния, используя именованные тома, или смонтировать их с помощью -v в существующий каталог (если вы хотите сохранить данные при воссоздании контейнера). Я также думаю, что было бы лучше использовать этот подход, потому что VOLUME внутри dockerfile является непонятным для тех, кто расширяет этот dockerfile, и если вы не знаете, что он там, вы можете подумать, что ваш контейнер воспроизводится в разных средах и что вы можете изменять версии без побочных эффектов, только чтобы позже вас укусили, потому что он использует постоянные данные под капотом.

Он также не позволяет вам перемещать файлы в этот каталог во время сборки (при условии, что вы не хотите использовать его как том, но наследует Dockerfile, который определяет каталог как том, например wordpress, который определяет /var/www/html/ как VOLUME, и мне нужно было использовать некоторые хаки, чтобы использовать другой каталог).

Используя -v вы явно заявляете, что вам нужен объем, и избегаете нежелательных сюрпризов из-за черной магии VOLUME в Dockerfile.

Кроме того, это может привести к созданию большого количества анонимных томов:

Определение объема внутри изображения указывает докеру, что эти данные следует хранить отдельно от остальной части контейнера, даже если вы не определяете объем при раскручивании контейнера. Docker сохраняет эти данные путем создания локального тома без имени. Само имя представляет собой длинную уникальную строку идентификатора, которая не содержит ссылки на изображение или контейнер, к которому оно прикреплено. И если вы явно не укажете докеру удалить тома при удалении контейнера, эти тома останутся и вряд ли когда-либо будут использоваться снова.

Источник: https://boxboat.com/2017/01/23/volumes-and-dockerfiles-dont-mix/

@lucasbasquerotto Я в основном согласен с вами, есть все давние проблемы, я думаю, что устаревание должно следовать по пути, по которому они не становятся недействительными, они становятся информативными, как ... предлагаемые пути, которые вы могли бы включить в том, предложил порты, которые сервер может прослушивать.

Я думаю, что значительная часть пути Docker теперь воплощена в стандарте OCI, и поэтому мы должны писать новые инструменты, которые не имеют всего этого наследия на плечах.

Для всех, кто сочтет это полезным, смело используйте образы докеров tugboat.qa . Они являются расширениями нескольких официальных образов докеров с удаленными томами. Минимально документированный репозиторий GitHub здесь, где выполняется тяжелая работа: https://github.com/TugboatQA/images

Есть ли вообще какая-то польза от наличия EXPOSE и VOLUME в файлах докеров? В конце концов, вы можете легко определить их в docker run (и в docker-compose файлах), с помощью --expose (или -p ) и именованных томов или привязки монтирования. Меня укусили из-за них более одного раза, и нет возможности их сбросить (создание нового файла докеров не очень жизнеспособно, особенно при расширении официальных образов или образов, созданных с помощью файлов makefile). Я считаю их антипаттерном и думаю, что было бы лучше отказаться от них.

В настоящее время многие поставщики предоставляют свои приложения в виде простого образа контейнера и вместе с ним предоставляют файлы докеров.
Наличие в этих файлах EXPOSE и VOLUME позволяет использовать простые приложения с простым docker run в каталоге приложений. Вам не нужно ничего знать о том, какие параметры ожидает приложение, оно работает со всеми значениями по умолчанию, указанными в файле dockerfile.
Так что да: хотя у нас есть лучшие, большие пушки, такие как compose или k8s для сложных приложений, для простых локальных приложений dockerfiles по-прежнему отлично подходят. А наличие по умолчанию, которые просто работают, делает использование удобным.

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

Вместо docker run some_image вы можете легко запустить docker run --expose 3000 -v my_volume:/container/dir some_image и иметь четкое представление о портах, доступных хосту, и томам, которые будут сохраняться даже после уничтожения контейнера.

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

Если он находится в файле докеров, это может затруднить понимание того, что происходит, и вызвать неожиданные сюрпризы в долгосрочной перспективе, когда том сохраняется, а вы не знаете (особенно если файл докеров унаследован от другого, вы можете не знать заранее, что объем определен, если вы не исследуете более глубоко, что он делает). Так что я бы посчитал VOLUME и EXPOSE плохими, даже если эта проблема будет решена.

Кроме того, хотя эта проблема не решена (и я не знаю, сколько лет потребуется, чтобы ее решить, учитывая, что она открыта более 5 с половиной лет), у меня просто НЕТ ПУТИ для сброса их .

Есть ли вообще какая-то польза от наличия EXPOSE и VOLUME в файлах докеров? В конце концов, вы можете легко определить их в docker run (и в docker-compose файлах), с помощью --expose (или -p ) и именованных томов или привязки монтирования. Меня укусили из-за них более одного раза, и нет возможности их сбросить (создание нового файла докеров не очень жизнеспособно, особенно при расширении официальных образов или образов, созданных с помощью файлов makefile). Я считаю их антипаттерном и думаю, что было бы лучше отказаться от них.

В настоящее время многие поставщики предоставляют свои приложения в виде простого образа контейнера и вместе с ним предоставляют файлы докеров.
Наличие в этих файлах EXPOSE и VOLUME позволяет использовать простые приложения с простым docker run в каталоге приложений. Вам не нужно ничего знать о том, какие параметры ожидает приложение, оно работает со всеми значениями по умолчанию, указанными в файле dockerfile.
Так что да: хотя у нас есть лучшие, большие пушки, такие как compose или k8s для сложных приложений, для простых локальных приложений dockerfiles по-прежнему отлично подходят. А наличие по умолчанию, которые просто работают, делает использование удобным.

Я бы сказал, что поставщики, которые так поступают, делают это по незнанию. Непонимание проблем, которые это вызывает у людей, которые хотят использовать свой продукт в производственной среде. Конечно, это помогает кому-то выдержать тестовый / демонстрационный экземпляр продукта. Но теперь, если я хочу запустить его по-настоящему, мне нужно git clone / sed их Dockerfile или создать свой собственный, чтобы получить рабочий образ.

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

Вместо docker run some_image вы можете легко запустить docker run --expose 3000 -v my_volume:/container/dir some_image и иметь четкое представление о портах, доступных хосту, и томам, которые будут сохраняться даже после уничтожения контейнера.

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

Если он находится в файле докеров, это может затруднить понимание того, что происходит, и вызвать неожиданные сюрпризы в долгосрочной перспективе, когда том сохраняется, а вы не знаете (особенно если файл докеров унаследован от другого, вы можете не знать заранее, что объем определен, если вы не исследуете более глубоко, что он делает). Так что я бы посчитал VOLUME и EXPOSE плохими, даже если эта проблема будет решена.

Кроме того, хотя эта проблема не решена (и я не знаю, сколько лет потребуется, чтобы ее решить, учитывая, что она открыта более 5 с половиной лет), у меня просто НЕТ ПУТИ для сброса их .

Согласованный. Итак, давайте определим стандартный способ сообщить, какие параметры требуются.
Если его нет, мы просто получим тот же беспорядок, что и в старых приложениях: документы конкретных поставщиков и форматы документации. Некоторые говорят вам, какие порты открывать, некоторые - нет. Некоторые говорят вам только половину, некоторые говорят неправильные порты. Некоторые говорят вам только номер порта, но не протокол и так далее.

Dockerfile - отличный способ стандартизировать этот беспорядок.

@ m451 Я согласен с вами в этом, но хорошо учитывать, что простое раскрытие порта не дает полезной информации. Какие данные / соединения ожидает открытый порт? Если есть несколько портов, что делает каждый порт?

Если вы хотите сохранить данные, вы хотите, чтобы они монтировались на именованный том или в какое-то место на хосте, VOLUME в этом не поможет. Если вы хотите, чтобы временные данные хранились с большей производительностью, тогда VOLUME поможет (это единственный случай, когда VOLUME может быть полезен). Запись в контейнер происходит медленнее, поскольку он использует стратегию копирования при записи . Но опять же, сопоставление тома при запуске докера также позволяет избежать CoW (вам не нужен VOLUME), единственным недостатком является то, что ваша инструкция длиннее, и вам нужно знать путь (но это только в том случае, если у вас снижена производительность из-за в CoW).

Использование VOLUME и EXPOSE в качестве типа документации не оправдывает плохую (или отсутствие) документации . И это также может (и, вероятно, будет) навредить некоторым потребителям изображения.

@ m451 Я согласен с вами в этом, но хорошо учитывать, что простое раскрытие порта не дает полезной информации. Какие данные / соединения ожидает открытый порт? Если есть несколько портов, что делает каждый порт?

Правильный. Идея отверстий портов из сек. перспектива устарела. Тем не менее: здесь мы пытаемся определить, какие порты должны быть открыты и какие порты могут оставаться закрытыми, а также понять, какие данные передаются через каждый порт. HTTPS сегодня стал оболочкой практически для всего, и, кроме автора кода, обычно нет никого, кто точно знает, какие данные передаются через определенный порт. И даже тогда это может меняться с каждым обновлением.

В RL вам все равно, какие данные / информация передаются через какой порт, кроме того, что вы в конечном итоге устраняете неполадки в приложении. Вы решили доверять приложению. Так что, если приложение открывает порты X и Y, вы тоже доверяете ему.
Для стандартных повседневных операций хорошо просто запустить приложение, и оно будет работать сразу после установки (предполагаются безопасные настройки по умолчанию).
Контейнеры стали формой упаковочных приложений, которые позволяют им работать сразу же.

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

Мой кусок пирога.

Использование VOLUME в Dockerfile бесполезно . Если пользователю требуется постоянство, он обязательно предоставит отображение тома при запуске указанного контейнера. Было очень сложно отследить, что моя проблема с невозможностью установить право собственности на каталог (/ var / lib / Influxdb) была связана с объявлением VOLUME в файле Dockerfile InfluxDB. Без параметра типа полного избавления от него я не могу изменить что-либо, относящееся к указанной папке. Это далеко не идеально, особенно когда вы осведомлены о безопасности и желаете указать определенный UID, под которым изображение должно запускаться, чтобы избежать случайного пользователя с большим количеством разрешений, чем необходимо, для запуска программного обеспечения на вашем хосте.

Должен быть способ переопределить эти директивы VOLUME при расширении изображений для пользовательской настройки. На данный момент мое единственное решение - полностью воссоздать изображение самостоятельно, сделав весь _Dockerfile FROM_ динамическим бесполезным.

ОТ nginx: последний
после развертывания на heroku порт 80 был открыт nginx, но это не разрешено heroku, так что я могу сделать? скопировать весь файл dockerfile из nginx и удалить EXPOSE 80?

Я не буду писать ничего нового ... но было бы очень хорошо переопределить директиву EXPOSE.

Совместное использование - https://github.com/gdraheim/docker-copyedit/blob/master/docker-copyedit.py (не мое творение, чтобы было ясно, спасибо @gdraheim!)

Это помогло мне удалить том из контейнера postgres, который был установлен в файле докеров с помощью команды:

python docker-copyedit.py FROM postgres:11.5-alpine INTO postgres:11.5-alpine remove volume /var/lib/postgresql/data

Кажется, что выполнила работу без повреждения контейнера, взяла исходное изображение, адаптировала его, создала новое изображение без тома (в соответствии с запуском docker inspect на контейнере, созданном из настроенного изображения), а не использовал его для чего-то еще, но git README позволяет выполнять множество операций, т. е.

 ./docker-copyedit.py FROM image1 INTO image2 -vv \
     REMOVE PORT 4444
 ./docker-copyedit.py FROM image1 INTO image2 -vv \
     remove port ldap and rm port ldaps
 ./docker-copyedit.py FROM image1 INTO image2 -vv \
     remove all ports
 ./docker-copyedit.py FROM image1 INTO image2 -vv \
     add port ldap and add port ldaps

LABEL - еще одно «свойство» (еще не упомянутое), которое может использовать возможность «сбросить»

Как упоминалось в этом сообщении SO: https://stackoverflow.com/questions/50978051/how-do-i-unset-a-docker-image-label

Другой вариант использования для сброса / удаления VOLUME из изображений восходящего потока:

Я работаю над расширением образа базы данных Oracle, но его объем /opt/oracle/oradata . В образе оракула по умолчанию база данных создается при запуске контейнера и записывается в этот том. Но это приводит к тому, что контейнеру требуется 25 минут для первого запуска, что неприемлемо. Итак, я работаю над изображением, в котором база данных создается при сборке изображения, но для этого мне нужно удалить VOLUME /opt/oracle/oradata потому что моя база данных создается, но когда я запускаю контейнер, файловая система /opt/oracle/oradata пуста снова, и моя база данных не запускается.

Я работаю над расширением образа базы данных Oracle, но его объем /opt/oracle/oradata .

Тоже мой вариант использования. Я хотел бы создать заранее выделенную подключаемую базу данных, которую другие могут извлечь из нашего частного реестра докеров ... но том отсутствует. Мне придется копнуть глубже и выбрать наименее уродливый обходной путь.

Я решил это следующим образом:

Я использовал docker-copyedit для удаления тома, затем я написал сценарий bash для создания базы данных (вы можете посмотреть сценарии запуска из oracle, чтобы увидеть, как это делается). Теперь с предварительно настроенной PDB требуется всего 25 секунд для запуска контейнера из образа. Но изображение становится действительно большим.

Было бы лучше расширить существующую спецификацию докеров, включив в нее концепцию липких переменных env / опции переопределения, например:

например, мой проект, основанный на образе Tomcat из восходящего потока:

--ENV CATALINA_HOME / some / other / path
ОТ tomcat: 8.5.54-jdk8-openjdk
...

Если ENV объявлен с - он должен быть повышен до липкого статуса и удерживать объявленное значение / переопределить любое значение, обнаруженное для этой переменной позже в цепочке обработки Dockerfile.

--ENV = с этого момента в Dockerfile.

Следовательно, это можно использовать в начале файла Docker, если вы хотите, чтобы он имел приоритет над любым дальнейшим обнаружением той же переменной, например, в многоступенчатых сборках. Это также обеспечит гибкость в зависимости от того, где в Dockerfile он был размещен, чтобы ссылки выше в файле были независимыми.

Тогда не потребуется UNVOLUME, поскольку правильным подходом будет объявление VOLUME со ссылкой на ENV, которую может переопределить кто-то другой.

например

ENV PROJ_VOL / некоторые / путь
VOLUME $ PROJ_VOL

Похоже, что ENTRYPOINT [] и ENTRYPOINT [""] оба аннулируют кеш для каждой сборки, если BuildKit не используется. Простой Dockerfile для демонстрации:

FROM jrottenberg/ffmpeg:4.3-alpine311 as base

ENTRYPOINT []

RUN echo "HERE!"

Шаги 2 и 3 _ никогда_ не будут использовать кеш. Это мой обходной путь:

FROM jrottenberg/ffmpeg:4.3-alpine311 as base

ENTRYPOINT ["/usr/bin/env"]

RUN echo "HERE!"

Я не могу воспроизвести сбой кеша на вашем первом шаблоне:: confused:

$ cat Dockerfile
FROM alpine:3.12
ENTRYPOINT []
RUN echo 'HERE!'

$ docker build .
Sending build context to Docker daemon  17.25MB
Step 1/3 : FROM alpine:3.12
 ---> a24bb4013296
Step 2/3 : ENTRYPOINT []
 ---> Running in d921be2e563d
Removing intermediate container d921be2e563d
 ---> 7801c649d895
Step 3/3 : RUN echo 'HERE!'
 ---> Running in 9e2ca2cf1f9f
HERE!
Removing intermediate container 9e2ca2cf1f9f
 ---> d398fdd442b1
Successfully built d398fdd442b1

$ docker build .
Sending build context to Docker daemon  17.25MB
Step 1/3 : FROM alpine:3.12
 ---> a24bb4013296
Step 2/3 : ENTRYPOINT []
 ---> Using cache
 ---> 7801c649d895
Step 3/3 : RUN echo 'HERE!'
 ---> Using cache
 ---> d398fdd442b1
Successfully built d398fdd442b1

Я думаю, вам нужно использовать изображение, которое определяет ENTRYPOINT . Попробуйте использовать то же изображение, что и я, или mysql .

О, интересно - я могу воспроизвести, используя mysql:8.0 . Сплошной баг! : +1:

Была ли эта страница полезной?
0 / 5 - 0 рейтинги