Комментарии 41
Неудобно смотреть логи в контейнере
1. Sentry
2. stdout + сборщик логов
3. logspout
4. Filebeat
5. Fluentd
Так вот, когда у меня был МК-61
ЕГГОГ :-)
http://xn--b1aph9d.xn--p1ai/biblioteka/cartochki/0019.htm держите. Я в детстве часами за этой книгой сидел.
Очков Валерий Федорович, Хмелюк В. А.
1990 год
эквм.рф/biblioteka/cartochki/0003.htm
Docker в первую очередь даёт унифицированный интерфейс взаимодествия с любым приложением, что позволяет значительно повысить надёжнось и снизить стоимость поддержки ops.
Ни один из пакетных менеджеров не решает эту задачу.
Что Вы имеете ввиду под унифицированным интерфейсом взаимодействия с любым приложением?
Еще докер сам следит за работоспособностью процесса как супервизор. И не нужно лепить костыли.
Концептуально — можно паковать не в докер, а в rpm/deb + systemd юниты — по идее почти тоже самое, но это реально сложнее + можно налететь на проблемы зависимостей.
Не соглашусь с Вами только по поводу того, что rpm/deb + systemd — это сложнее
Нет, нет и еще раз нет. rpm сложнее. Т.к. нужно, во-первых, собирать под несколько операционных систем (el6, el7, opensuse etc.). Во-вторых, rpm не решает проблему с зависимостями типа python пакетов. В третьих, есть еще в манифестах системные зависимости. Ну, там от libqt, внешних утилит (openssl, openssh?) и пр. И никто, никто, черт побери, не прописывает их нормально. Например, в убунте эти зависимости обычно идут как «я завишу от пакета XXX версии не младше YYY» (см., например, ntp). А то что пакет XXX версии ZZZ (ZZZ>YYY) все сломает — пофиг.
Докер в этом отношении идеален, т.к. образ — это по сути слепок операционной системы со всеми необходимыми пакетами, причем протестированными с конкретной версией приклада. Да — в минусах размер. Да — проблема с тем, что если есть какая-либо уязвимость, то нужно пересобирать и перескачивать все уязвимые образы.
И здесь на сцену выходит Docker, эдакая смесь виртуализации, разграничения ресурсов и способа поставки. Это сейчас модно, молодежно, но нужен ли он для всего? Панацея ли это?
В какой-то момент к нам начали приходить свежеиспеченные мидлы, бурлящие идеями и бредящие докером. Что ж, флаг в руки — делаем! Было две попытки. Обе неудачных — скажем так, из-за больших амбиций, но недостаточности реального опыта. Надо ли было форсировать и доделывать любыми силами? Вряд ли — коллектив должен эволюционно дорасти до нужного уровня [..]
С другой стороны, чем Spring-сервис в виде jar-архива хуже деплоить через тот же deb? Реально ли нужна изоляция ресурсов? Стоит ли лишаться удобных инструментов операционной системы, запихивая сервис в сильно урезанный контейнер?
Как показала практика — в реальности это не нужно, deb-пакета хватает в 90% случаев.
При этом перечисленные вами проблемы при использовании контейнеров — это либо признаки не совсем правильного использования контэйнеризации (в плане логов или шелла внутри контейнера), либо «какие-то частные непонятные проблемы», в суть которых, видимо, никто не углублялся (проблемы с сетью, странные зависания ElasticSearch), либо понятные и по-разному решаемые особенности докеризации, которые, по сути, и есть та компромиссная часть trade-off, на которую мы смотрим решая допустимо ли перевести систему на docker (размеры контейнеров, скорость сборки).
Да, докер не панацея и, чем у'же убласть, тем больше поводов смотреть на частные и альтернативные решения. Однако, чем шире мы смотрим на индустрию, тем в лучшем свете представляется докер, ведь он хорош своим движением в сторону универсализации и унификации.
Квинтесценция манипулятивности и некоторой нелогичности вашей статьи на мой взгляд в этой цитате:
По моим наблюдениям, очень часто Docker предлагается не как разумный выбор, а просто потому, что об этом, с одной стороны, говорят в сообществе, и те, кто предлагают, только его и знают. С другой стороны, о старых добрых системах упаковки по большей части молчат — они есть и есть, свое дело делают тихо и незаметно.
Я там наподчёркивал то, что меня, прям, покоробило. Тут и отсылка к личному опыту, и странное обобщение, будто бы о докере говорят исключительно те, кто лишь его только и знает…
Лично я, когда такое читаю, сразу задумываюсь о предвзятости мнений и о направлении причинно-следственных связей. Почему об одном молчат, а о другом кричат? Если бы вы нейтрально рассмотрели плюсы и минусы без манипуляций, то как по-вашему, статья стала бы менее объективной? Может быть она дала бы читателям лишнюю возможность сделать неверные выводы? Ну не знаю…
Вы только не обежайтесь, уважаемый автор. Я постарался внести конструктивную критику вашей статьи. Из моих тезисов, конечно, не следует, что вы не правы по существу, что докер в вашем юзкейсе более верное решение, и даже что в сторону докера нет излешнего перекоса в среде хипстеров от девопса=).
И то, что я видел, что люди используют докер не потому, что он реально нужен, а потому что это нынче популярно — это реальный кейс, с которым пришлось столкнуться. Отнюдь не все так делают, конечно же нет, и мы сами используем докер, я хотел лишь подчеркнуть в статье два основных момента:
1. Докер надо использовать там, где он реально нужен, а не везде вообще
2. Не надо забывать про хорошие системы упаковки, про которые сейчас мало говорят, но они есть и успешно работают и не надо их бояться
если не увидит выгод для себя
Т.е. это опять ситуация, когда локальный оптимум (i.e. разрабу не нужно учить ничего нового, он эффективен в своей зоне комфорта) абсолютно не попадает в глобальный оптимум (i.e. эффективность всей организации). Извините, что так сложно изъясняюсь.
Но если копать глубже, но я в статье как раз и озвучивал ситуацию про смену поколений, и поколение приходящих студентов, не зная прошлых наработок и не имея достаточно опыта, реализует деплой в виде простых скриптов или вообще вручную. Посмотрите на результаты опроса: деплой через FTP или самописными скриптами отнюдь не на последнем месте. Т.е. все делается, на самом деле, с минимумом усилий. И чтоб сделать качественный скачок — нужны мотивированные люди и опыт.
Проблемы с сетью в режиме bridge
Неудобно смотреть логи в контейнере (если они никуда не вынесены отдельно в файловую системы хост-машины)
Периодически странное зависание ElasticSearch внутри контейнера, причину так и не установили, контейнер официальный
Нудобно пользоваться шеллом внутри контейнера — все сильно урезано, нет привычных инструментов
Большой размер собираемых контейнеров — дорого хранить
Проблемы с сетью — используйте балансировщик (nginx, traefik, envoy или вообще внешний). Или host mode сеть.
Неудобно смотреть логи? Не верю (с). Наоборот — через docker logs удобнее смотреть логи, чем бегать по 100500 файлов в файловой системе. Единственное, что docker лучше сразу настроить на драйвер journald, т.к. остальные (кроме дефолтного json file) не сохраняют локальные логи и тогда действительно команда docker logs не работает. А хранить логи в контейнере — ССЗБ.
Эластик запускать внутри контейнера — такое себе удовольствие, но почти наверняка уверен, что это не проблема самого докера или образа. Т.к. у нас все работает. К тому же, рекомендую graylog, а не elk, т.к. это более законченное решение (если, конечно, Вы не готовые эластику отвалить 1****** $$$ за ёлку под ключ).
Шелл внутри докера? Чего там не хватает? Если что-то нужно, то всегда можно доустановить быстро утилиты для диагностики проблемы. А вообще — меньше программ в образе — меньше размер — меньше поверхность атаки и меньше проблем.
Большой размер образов — ну, так нужно их уметь собирать… И в общем случае размер артефакта в разумных пределах не является проблемой.
Из-за большого размера контейнеров сложно поддерживать множественные версии
Более длительная сборка, в отличие от других способов (скрипты или deb-пакеты)
это вообще пять. Про первое я уже сказал. Кстати, docker registry позволяет дедупликацию данных, поэтому два образа по 5ГиБ скорее всего займут сильно меньше, чем 2*5=10ГиБ. Второе — да, есть нюанс, но она более длительная не на порядок, а раза в два и все равно можно ее оптимизировать. Идеальный вариант сборки — имеется базовый образ с java и туда попросту инжектируется уже собранный jar или war файл. Тогда и сборка получается максимально быстрая, и размер итогового образа минимальный.
Шелл внутри докера? Чего там не хватает?
Не хватает возможности нормально отлаживать контейнер, если с ним творится что-то нехорошее. При использовании полноценной машины там обычно есть достаточно инструментов для мониторинга, в случае же контейнера, как Вы сами заметили, есть желание урезать его по максимуму со всеми вытекающими последствиями.
имеется базовый образ с java и туда попросту инжектируется уже собранный jar или war файл.
А чем хуже иметь полноценный сервер, куда так же просто раскладывается jar?
Тем более что сам jar — это уже готовый контейнер, а java-машина и так управляет ресурсами (на то она так и называется Java Virtual Mashine, JVM)? Зачем вообще в такой связке нужен докер? Мне кажется, что это просто лишний слой.
Не хватает возможности нормально отлаживать контейнер, если с ним творится что-то нехорошее. При использовании полноценной машины там обычно есть достаточно инструментов для мониторинга, в случае же контейнера, как Вы сами заметили, есть желание урезать его по максимуму со всеми вытекающими последствиями.
У Вас есть strace на хостовой машине, htop на хостовой машине и пр. Они прекрасно показывают процессы внутри контейнера, и, да, strace к процессу внутри контейнера прекрасно подцепляется. Поэтому вопрос — НУЖНО ли тащить внутрь контейнера весь этот лишний пейлоад?
А чем хуже иметь полноценный сервер, куда так же просто раскладывается jar?
Тем более что сам jar — это уже готовый контейнер, а java-машина и так управляет ресурсами (на то она так и называется Java Virtual Mashine, JVM)? Зачем вообще в такой связке нужен докер? Мне кажется, что это просто лишний слой.
Не Mashine, а Machine :-) И, да, Вы правы, что JVM сама заведует ресурсами. Тут вопрос в другом, что если Вы едете в какой-нибудь унифицированный стек для управления ресурсами (тот же кубернетес), то проще всех загнать под единую гребенку. А именно — паковать все в докеры. Тем более, что это позволяет разработчикам проводить множество экспериментов у себя на системе, не захламляя ее серверами приложений Java (а они прям проникают во все уголки хостовой системы).
Когда мы начинали стартап, то тоже была идея взять кубер, но денег и ресурсов было мало, потому развернули всё на обычных VDS с обычным деплоем через Octopus Deploy. Эта штука позволяет делать довольно навороченные сценарии и заменяет самописные скрипты.
Докер для него — действительно не то место, где он себя будет хорошо чувствовать.
Мне кажется, что проблема в другом.
ES в каком-то тестовом виде можно развернуть в докерах. Но смысла, кроме быстрого обновления версии, это не имеет. Потому что под ES в идеале нужно давать выделенные ноды — будь то аппаратные сервера или виртуальные машины. И в случае с докером — ES нужно «правильно» готовить. А зачем, если можно сделать проще, а, следовательно, и надежнее.
Кстати, знаете, чем закончится запуск штатного стека через docker-compose? Такой или такой. Первый — точно упадет по памяти рано или поздно. Второй — а зачем, позвольте, две ноды эластика запускать на одной машине? Это только, чтобы кластер зеленый хелсчек показал? А в остальном это создает проблемы: от конкуренции за процессор и память между обеими нодами эластика, вплоть до того, что отказоустойчивости по факту никакой. Вот и угадай, чем они думали, когда рекомендовали такой конфиг…
www.elastic.co/guide/en/elasticsearch/guide/master/heap-sizing.html#_just_how_far_under_32gb_should_i_set_the_jvm
So if your machine has 128 GB of RAM, run two nodes each with just under 32 GB. This means that less than 64 GB will be used for heaps, and more than 64 GB will be left over for Lucene.
К тому же, две дата-ноды на одном хосте требуют грамотного микроменеджмента разделов диска и т.п.
Чего вы пристали к человеку? Просто не получилось у него осилить докер. Как сам и сказал "дорастёт команда" и будет им счастье (не сразу конечно, через грабли) но будет ;)
Выпускается версия С/С++/Java/Python/NodeJs/Go приложения — миллионы строк и 800 человек разработчиков. Поддержка из коробки 15 лет, но её частенько расширяют.
Нужно гарантировать на всём протяжении существования продукта:
* неизменную среду разработкии и исполнения(железо или любой клауд, любая втртуализация github.com/weldpua2008/deployer) — в обычной убунте с помощью alternatives, .bash_*, /opt/ я создавал кастомный build toolchain: g++/make/Shared objects/Kernel headers/ld_library_path и т.д. Которые таким же макаром создавались пакеты(rpm/deb) или архивы.
* не важно сколько раз пробежит билд — это всегда будет одна и та же версия. И если при сборки версии 1.1.1 пробегал скрипт и создавал неправильную конфигурацию в CI и потом мы это исправили, то для версии 1.1.2 этих изменений не будет существовать.
Мы версиировали систему сборок (https://github.com/weldpua2008/compage).
Мы использовали всевозможные стандартные системы распространения ПО: rpm, deb, pipe, npm, maven репозитории, Artifactory. Почти всегда есть следующая ситуация: следующий билд на может найти тот или иной пакет или его версию. Я помню как в 2015 фиксировал версию requests для Python, потому что между минорными версиями были глобальное изменение.
Все вышесказанное кристаллизировать у меня следующее:
* если вы не выпускаете коробки/виртуальную машину со своим кодом, то вы должны фиксировать версию ваших прямых зависимостей и их зависимостей. (Желательно у себя, иначе условная Cloudera сломает репозиторий и вы не сможете обновлять /устанавливать в облаке новые машины): AMI, созданные через packer образы VM, LXC, частный docker репозиторий.
* Chef/Ansible и другие представители CM — сами могут падать из-за обновлений и нужно уметь откатывать версии.
* разработчики могут вставить в код всевозможные вещи, которые вас пригвоздят к конкретной машине, среде запуска или же пользователю.
Версионирование системы сборки — это огонь. К сожалению, современные продукты типа Дженкинса и Гитлаба предоставляют очень ограниченные возможности для этого. Это и понятно — они заточены на релиз продуктов типа веб-приложения, которое существует в одном инстансе и последней, крайней версии. Так что пайплайн месячной давности уже особой ценности не представляет. Все-таки разработка коробочного продукта с длинным жизненным циклом (LTS) — это вообще другой мир.
Касательно баш-сборщика — ну, что ж, Вы — молодец. В очередной раз проиллюстрировали, что все, что есть, можно собрать на баше. Другой вопрос — а нужно ли? Стоимость поддержки баш-фреймворка не очень большая получается?
Эволюция средств поставки, или размышления о Docker, deb, jar и прочем