Как стать автором
Обновить

Комментарии 48

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

Вы сейчас описали типичного девопс-инженера с перекосом в сторону "дев" :)

Сам (как админ) с тухлятиной внутри контейнеров не сталкивался, но легко представляю описанный вами процесс - когда разработчики залочили версии библиотек и радостно кодят, потому что у них ничего не падает. Надо пинать, да, проводить ревизию и всё такое.

Я с автором не согласен в главном вопросе.

Ведь также можно залочить версии в каком-нить сборщике, загнать 3rd party джарники прямо в репозиторий и жить, пока не пнут аудитом - и докер тут еще окажется довольно доступным местом для контроля "снаружи".

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

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

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

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

Обновит как-нибудь раз, получит крэш из-за каких-нибудь новых или починенных старых багов — ему не понравится, и делать так он перестанет.

Дык если не разработчик обновит и разработчик получит крэш из-за каких-нибудь новых или починенных старых багов, то кто будет эти баги фиксить?


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

Обновляется легко - но захочет ли это делать разработчик?

А его спрашивать не надо. Сборка производится на автоматическом инструменте, который контролирует админ. Базовые образы берутся или из локального хранилища (которые контролирует админ или ответственная группа) или из глобального docker реестра, который тоже обновляется. Не заработало с новой сборкой - задача разработчика починить.

А вот попробуй заставить разработчика регулярно следить за всем что в pom.xml, например?

так дело как раз в том что разрабы не дают обновлять базу. Об этом есть в статье - они зафризили окружение, все, точка.

Так это проблема того, что инфраструктура завязана на девелоперов.

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

Зафризить окружение - они себе сделали свой базовый образ и никого к нему не пускают?

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

Придет "бизнес" и скажет, что из-за прихотей админа недополучаем вагон денег.

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

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

Админ в данном случае - исполнитель требований сверху, а не инициатор.

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


Проблема как была, так и осталась, но её решать должен CTO через введение политик (делегируя это, конечно же). И с докером это сделать сильно проще, так как повышается видимость проблемы.


Опсы (секьюрити отделы) только инициируют необходимость обновления через политики и систему алертов. Но выполняют девелоперы. При этом обновляются не только зависимости рантайма (openssl, к примеру), но и библиотеки. И получившийся артефакт проходит полное тестирование, прежде, чем быть задеплоенным.

Главная проблема докера в том, что разрабы не хотят понимать и разбираться, как что устроено, а то, что они тяп-ляпают в докер попадает в продакшн, а контейнер позволяет весь этот ад хоть как-то запускать. Т.е. основное преимущество становится недостатком. А де-факто, надо эти контейнеры адекватно пересобирать, или давать правильно сконфигурированные заготовки.

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

А чего мы ожидаем, если 100% курсов так и учит кодеров, обещая им золотые горы? В идеале, DevOps культура как раз и решает эту проблему, но из-за непонимания того, что на самом деле DevOps, в конторах админов дефективные менеджеры переименовывают в DevOoops'ов, запаковывают всё в контейнеры и ходят довольные, хайпуя потом на конференциях.

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

Автор упоминает очень старую проблему: фиксация зависимостей vs использование системных библиотек. В том же линуксе есть AppImage и snap пакеты, которые дают аналогичные докеру решения.
Не могу сказать про все команды, но очень часто докерфайлы небольшие и не имеют жёстких фиксаций версий внутри себя. Если это Python приложение, то оно собирается из стандартного базового образа, там устанавливаются зависимости, какая-то настройка и всё. Системные библиотеки (типа libssl) обновляются вместе с базовым образом. Для их обновления достаточно сделать пересборку, что и так регулярно происходит на CI/CD пайплайнах.
Аргумент автора про проблемы с большими докерфайлами разумен, но, обычно, эти большие докерфайлы уже собираются с привлечением девопсов/сисадминов, которые могут на него повлиять. Но тут лично я встречался с ними редко, мне казалось это плохой практикой.
Обновление же библиотек уровня приложения с докером не связано. Мы, например, делаем это в рамках регулярного сокращения техдолга.

Так snap — это и есть «докер для десктопных приложений», и появился он совсем недавно.

Системные библиотеки (типа libssl) обновляются вместе с базовым образом

и кто-то должен его обновить. Кто? Разработчику это в общем-то ненужно. Об этом вся статья и есть — разработчику нужно взять что-то, и дописать к этому своё, новое. Заниматься обновлениями, поддержкой — это не его. И devops как практика был придуман именно для расширения спектра задач программиста, но в итоге всё равно есть ops'ы и они этим всем занимаются, вот только бывают разные перекосы: может быть много разрабтчиков и мало админов, и те не успевают следить за всем. Может быть такой подход в компании, что «вы тут делайте как программистам надо — они фичи пишут, которые бизнесу еще вчера нужны, отстаньте со своими проблемами, они неважные».
snap — это и есть «докер для десктопных приложений», и появился он совсем недавно

Появились они примерно в одно время. Согласно вики, docker появился в 2013, а snap в 2014. AppImage на 10 лет раньше, в 2004. Тут моей целью было показать, что есть разные уровни фиксации окружения у приложений. Ещё раньше были портативные приложения (знаменитый PortableApps), которые имеют те же плюсы/минусы: использование системного окружения vs использование своего окружения.


кто-то должен его обновить. Кто?

Популярные базовые образы обновляются достаточно часто и хорошо самим сообществом. В этом им можно доверять почти всегда. То есть ответ на ваш вопрос: "оно обновляется само". Образ Python на DockerHub: последнее обновления 5 часов назад, огромное количество вариантов на любой вкус. И благодаря этому системная (на уровне системы) поддержка почти не требуется.


вот только бывают разные перекосы

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

То есть ответ на ваш вопрос: «оно обновляется само»

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

FROM …:latest и при каждом билде само обновится

И благополучно сломается при очередном билде в самый удачный момент. У нас нынче reproducible builds в моде. Подобная практика считается вредной и везде рекомендуется лочить версии на конкретные. Плюс latest совсем не означает, что будет скачана последняя версия. Это всего лишь тэг, который ничего не значит.

Есть latest, но есть и теги для стабильных версий типа stable. Он должен ломаться реже. А даже если и сломается, то у нас есть предыдущая версия на которую можно откатиться даже автоматически. Когда мы выбираем часто обновлять базовый образ, то на этот риск мы подписываемся добровольно.

Это все равно ничего не гарантирует, т.к. stable все равно один тэг, который постоянно меняется. Это ломает reproducible builds, это может привести к проблемам, когда кэш кто-то не почистил. В CI может быть оно и будет настроено, но захочет человек сам на машине собрать контейнер и получит непредсказуемое поведение, т.к. неизвестно какой образ будет подтянут.

Тем более что я изначально не особо понимаю смысла этой борьбы за частоту обновлений. Может в плюсовых каких-то программах, которые зависят от тучи библиотек внутри образа, это может еще актуально, но полно других языков, которым, по сути, нет никакого дела до окружения внутри контейнера. Им достаточно голого alpine, а порой и scratch вполне справляется. Наружу все равно же торчит какой-нить REST сервис и больше ничего — никаких ssh ничего больше нет как на полноценных хостах было бы. TLS делается либо библиотеками самого языка, либо внешним прокси, который и можно обновлять часто.
То есть ответ на ваш вопрос: «оно обновляется само»
«само» версию поправит во всех строчках FROM докерфайлов? Или по крону чистить все кэши образов каждую ночь, чтобы latest был и правда latest?

Чем плох вариант чистить кеш образов? Это же все равно происходит на CI/CD пайплайне, где этот кеш должен быть максимально актуален.

Это не кажется слишком сложным даже для компаний с перекосом по сисадминам

А почему бы и не чистить кеши? Вдобавок во многих случаях и чистить не надо. latest - то, что нужно

И вот лежит у тебя в кэше latest уже год, а тем временем latest уже 100500 раз обновился там, в интернете.

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

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

Иногда приходится кардинально менять путь в артифактори при мажорных обновлениях (java 1.8 -> java11), тогда рассылается уведомление на всю компанию, что вот есть новый образ, кто уже готов - меняйте FROM.

Вообще, честно говоря, я даже не очень понимаю о каком кэше идет речь.

А зачем вы тогда вообще эту дискуссию завели, если не понимаете о чем речь? oO Вы в артифактори не кэшируете базовые образы? Куплен аккаунт на докерхаб, чтобы не попадать на лимиты? Машина, на которой происходит сборка, очевидно выкачивает к себе всё, чтобы эту самую сборку осуществить, соответственно там тоже можно хранить потом это как кэш, ну а можно конечно и не хранить.

А зачем вы тогда вообще эту дискуссию завели, если не понимаете о чем речь?

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

Вы в артифактори не кэшируете базовые образы?

Мы их в артифактори создаем и храним, и именно в артифактори и обновляем.

Куплен аккаунт на докерхаб, чтобы не попадать на лимиты?

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

Машина, на которой происходит сборка, очевидно выкачивает к себе всё

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

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

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

Ну вот, если у вас артифактори настроен, что при запросе latest тэга базового образа он принудительно идет в докерхаб и перекачивает его - вы попадаете на лимиты докерхаба. Если он так не делает - вот он ваш кэш

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

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

Ну я давно юзаю systemd-timers и кронджобы в k8s, но всё равно проще говорить "по крону", разве нет?

Был и сисадмином, и разработчиком... и геморрой обновлений с позиции разработчика - вполне очевиден. Как и опасность "протухших" компонентов системы с позиции админа. Хорошего решения тут нет. Но можно хотя бы принять правильное: с позиции администратора должен быть список ОБЯЗАТЕЛЬНЫХ обновлений (неизбежный минимум), без которых страдает безопасность, с позиции разработчика - без разговоров эти обновления накатить и решить все возникающие в результате проблемы с ПО. Это адекватное соглашение.

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

У нас безопасники просто воткнули проверку на CVE в пайплайн. К счастью, только для master. Таким образом если находится уязвимость, то весь процесс деплоя на прод останавливается пока её не исправят разработчики (и я один из них). Все понимают важность безопасности, так что я не видел, чтобы кто-то возмущался.

Круто, прямо жирный плюс такой компании!

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

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

В руки безопасников или админов. А разработчиков просто ставить перед фактом. Следующий релиз собирается вот из этого. Все другое упадет на тестах в CI. Проблема решена. На крайний случай всегда можно захотфиксить прошлый релиз. Случаи разные бывают.

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

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

Надо мотивировать разработчиков. И платить премии не только за новые фичи в проде, но и за обновление, рефакторинг и тому подобные вещи.

К сожалению, во всех IT-процессах присутствует этот фактор , который один мой друг грубовато, но метко охарактеризовал крылатой фразой "некогда объяснять, суй в ж** огурец".
Это, безусловно, проблема, но все зрелые компании приходят к разумному балансу между тем, чтобы давать возможность техническим специалистам возможность сокращать технический долг и потребностями бизнес-подразделений. Все понимают, что с гнилью в потрохах jar-архивов, с кодом, залатанным-перезалатанным ради совместимости с диким легаси, которое кто-то притащил ещё на заре проекта (ведь тогда-то оно было ещё вполне актуально) - компания не сможет быстро реагировать на необходимость изменений, адаптации под те же требования к производительности.
Здесь больше вопрос в том, насколько руководство той или иной компании способно осознать, что именно её тормозит, почему изменения становятся болезненной процедурой и почему вдруг для проекта, начинавшегося как стартап "людей со взором горящим" вдруг здоровый консерватизм стал ключевой ценностью. Не все могут отличить консерватизм от ни чем объективно не подкреплённой аксиоматики, построенной на банальном страхе что-либо менять. Отсюда эта набившая оскомину "Мы пишем под JDK 1.6, потому что так нам завещал Господь". Если встречается что-то подобное - это верный признак того, что технический долг внутри проекта стремительно растёт и грозит утопить проект в постоянных подпиливаниях меняющегося реального мира под требования локальной экосистемы, в которой застывшие навечно в нелепых положениях костыли и палки стали частью действующего механизма получения прибыли. Никто не думает о том, что есть конкуренты, что прибыль могла быть выше, что можно было бы не платить разработчикам за безумные танцы с бубном и не возводить в ранг святых тех, кто "стоял у истоков и понимает, как вся эта мура работает". Всех заботит сохранение статус-кво и в лучшем случае экстенсивный рост. Отсюда и отсутствие стремление к совершенствованию IT-процессов. Но в общем-то у многих это со временем проходит. Ну либо компания деградирует со всеми вытекающими.

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


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

Управление зависимостями - касается информационной безопасности и того, что принято называть manageability, способности компании управлять своими активами. В крупных компаниях, у которых есть на это деньги, не только IT-специалисты сами по себе не склонны тащить в проект специфические зависимости исключительно потому что, они очень удобны и помогают сделать всё "вчера", как того хочет бизнес. Есть ещё и IT-аудит, который диктует нобходимость контролировать зависимости не на уровне самих разработчиков, а на уровне devops-инженеров и системных администраторов. То есть по сути то, что используют крупные игроки - это не свалка docker-контейнеров с неконтролируемым содержимым внутри, это docker-экосистема, в которой только самый верхний уровень ("слой") отдан на откуп разработчикам.
Поэтому ответ: сисадмин. Но вместе с разработчиками. Потому что devops, it-security и системные администраторы - это не business prevention подразделения, их задача - помогать разработчикам превращать порождаемый ими творческий хаос в стабильно работающие, безопасные, управляемые бизнес-активы компании.

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

Люди делятся на два типа :))

Хипстеры и луддиты. Не важно, разработчики они или сисадмины, или кто-то ещё :) По каждую из сторон баррикад есть и те, и те.

П.с. Хипстеры 4евер! ​

А серьезна ли эта проблема? Большая часть уязвимостей, из-за которых нужно регулярно обновлять ОС, это уязвимости линуксовых сетевых сервисов, шелла, какая-то эскалация привилегий...


В контейнере же, несмотря на полный набор системных библиотек, наружу торчит только само приложение.


Допустим, у меня в проде есть контейнер на 12-й убунте, в котором крутится java приложение, отвечающее по REST. И как древность дистрибутива тут поможет хакеру?

Бывает и так, но статья про случай что например сертификат в докере не обновился из за старой версии бота letsencrypt и вот клиент по 443 зайти поэтому не может, а на 80 где все отлично работает не ходит новый google chrome! Сисадмин помоги! А как ему серт обновить если он у кого? У разраба, блин.

Как так? Я сделал образ letsencrypt 5 лет назад и он до сих пор работает без нареканий.
Плюс, в такой ситуации это не проблема сисадмина. Не он настраивал, не ему чинить. Тем более, странно выглядит "мегаконтейнер", который и приложение, и nginx, и letsencrypt. Обычно это все-таки 3 разных контейнера

У вас перевод приближен к разговорному стилю, так что Неологизм "скриптикидис" ~= https://ru.m.wikipedia.org/wiki/%D0%A1%D0%BA%D1%80%D0%B8%D0%BF%D1%82-%D0%BA%D0%B8%D0%B4%D0%B4%D0%B8 ? лучше перевести по смыслу, не изобретая. Вроде " Даже мамкины хакеры, смогут атаковать этот контейнер."

Читать очень трудно.

Считаю, что обновлением фрагментов программного обепечения должен заниматься разработчик, а не админ.

Админ в состоянии обновить целиком весь пакет ПО, а не его части. Причем я не имею ввиду плагины или модули, которые конструктивно вынесены отдельно. Речь идет о зависимостях, которые являются частью основного ПО.

И никаких протухающих зависимостей в контейнерах быть не может. Это как раз возможность сохранить ПО в неизменном виде. И это требование большинства крупных заказчиков, кстати.

Не вижу здесь никакой "глобальной проблемы", ибо вопрос решается использованием широко известных best practices:
1) мультистейджинг образа
2) минимальный набор зависимостей для работы приложения
3) не привилегированный запуск процесса внутри образа
4) один под/образ - один функциональный сервис

Мультистейнджинг позволит отделить мух от котлет - базовый образ и системные бибилиотеки обновляются с периодичностью, достаточно чтобы закрывать большинство проблем с безопасностью/багами и прочим
Не надо тащить в сервисное окружение тулзы для всякого рода дебаггинга и прочей ерунды - для этого существуют уровни логгирования и отдельные сборки management-образов (с tcpdump-ами, телнетама и прочей мишурой.

Не выдумывайте на ровном месте то, чего не существует - лучше доверьте CI/CD толковым инженерам, а не отделу разработки.

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