Pull to refresh

Comments 24

спасибо за статью и упоминания Светлячка
а у нас сервера носят названия из Star Wars
А не пробовали CoreOS для управления докерами?
Да, и спасибо за статью.
Не пробовали, и вряд ли это имеет для нас смысл. OpenStack выбран с перспективой, что вскоре добавим поддержку полноценных виртуалок, например, на KVM. Могут быть нужны для создания более сложных упражнений, которые выходят за рамки возможностей контейнеров. Например, задания по настройке сети, туннелей, каким-нибудь махинациям с ядром.
В таком случае мы добавим новые compute-ноды с гипервизором KVM в наше облако и автоматом по тому же OpenStack API сможем запускать и контейнеры, и нормальные виртуалки.
1. Какие были причины для перепиливания tty-сервера? Какие были проблемы/нестыковки со штатным (кроме транспорта)?
2. Осуществляется ли миграция запущенных контейнеров в случае потери хоста?
3. На диаграмме показано, что zoe общается с докер-хостами по ssh. Какие причины были на то, чтобы не запускать свою собственную zoe на каждом докер-хосте?

А вообще, архитектурка аккуратная получилась, вполне неплохо.
1. Одна из причин — нежелание внедрять в проект еще одну нанотехнологию в лице node.js (docker'а с openstack'ом пока хватает более чем). Вторая причина — все равно ведь пришлось бы адаптировать штатный: нужен механизм аутентификации клиентского терминала, получение инфы о терминале от сервиса Mal, механизм подключения к tty контейнера (штатный, если я не ошибаюсь, поддерживает только tty сессию с локально запущенными процессами).
2. Миграция контейнеров не осуществляется. Пока нет родных средств миграции docker-контейнеров. Предполагаю, что можно извратиться и мигрировать контейнер с помощью CRIU, т.к. по сути контейнер — это обычный процесс, запущенный в необычном окружении. А вообще оно и не критично сейчас: ну издох сервер, ну упали текущие решаемые задания, да, грусть и печаль, но не смертельно.
3. На диаграмме показано, что Zoe общается по ssh с docker-контейнерами, не хостами. Эта связь нужна для выполнения удаленных команд в контейнере. На данный момент ssh оказался самым простым и доступным способом проверки состояния контейнера, в частности файловой системы. Если с контейнерами еще можно играться через хостовую систему, то с полноценной виртуалкой сложно что-то похожее сделать с гипервизора. Для виртуалок, видимо, ssh тоже будет самым простым способом пошариться во внутренностях машинки.
Т.е., zoe заходит по ssh именно в контейнер? Понял, спасибо.

PS: Просто на мой взгляд, испекция содержимого контейнера и инспекция содержимого виртуалки — две большие разницы. Мне как-то в первую очередь подумалось о том, чтобы (в случае именно с докером), находясь на докер хосте, просто запускать процесс-чекер в целевом контейнере. И не держать sshd без лишней надобности. Но, в принципе, тут уже дело личных предпочтений.
Да, вы все верно разобрали: в каждом контейнере помимо bash запускается еще sshd. Согласен, что есть оверхед с демоном ssh, запросто можно инспектировать контейнер и без него с docker-хоста. Но в этом случае нужно разрабатывать инструментарий, чтобы этим пользоваться. В случае с ssh, запустили демон и сразу имеем кучу тулов, которые с ним работают, в нашем случае библиотека fabric на python. В общем, иногда лучше добавить небольшой оверхед, чтобы снять с себя другие проблемы, эффективное решения которых не так и важно.

Интересно, а какой у вас опыт использования контейнеров?
Мы около года назад начали использовать докер для доставки релизов бэкенд-части сервиса. Тоже микросервисная архитектура, но микросервисов около 50 вместо трех. Плюс требования к масштабируемости и доступности. Сервисы преимущественно на эрланге.

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

Для управления baremetal-хостами сначала пытались приспособить openstack, но потом отказались (я как-то упустил этот момент, не участвовал в этом проекте). Потом мучались с mesosphere. Это был кромешный ад, на эту тему я могу материться очень долго =) Сейчас пробуем coreos. Привыкаем, но вопросов много.
Если будет возможность, напишите, пожалуйста, статью о подводных камнях, то хвалебных од много, а описания проблем — не очень (хотя, в issues, конечно, прилично).

Я сейчас мигрирую одно приложение (совсем не микросервисы, но 10-12 компонент) в докер. В принципе, всё более-менее работает, доставка через registry (на s3), пока собираю шишки.

В качестве хостов пока centos 6 и 7, т. к. не всё смигрированно, да и btrfs на coreos смущает (с учетом того, что развертывание системы может происходить и на 1 хосте).

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

Кроме того, data volume (device mapper'овский) прилично загаживается (в особенности актуально на dev-машине с небольшим ssd). Это несмотря на регулярное удаление ненужного барахла (старых образов). Правда, на btrfs тоже ругаются в этом плане.
К сожалению, не думаю, что это будет в ближайшее время. Конкретно сейчас мы висим в промежуточной стадии между mesosphere и coreos, а конкретно проектом по coreos я не занимаюсь. Поэтому, поделиться опытом я смогу только тогда, когда оно уже окажется в реальном продакшоне.
Никогда не поздно, тем более, что могут вылезти новые интересные corner cases.

Вы, кстати, какое-либо решение используете для создания оверлейной сети между docker-хостами?
Пытались наколдовать свой велосипед на openvswitch, потом решили, что оно нам тупо нафиг не нужно =) Все контейнеры вполне удовлетворительно чувствуют себя в одной сети, поэтому пока что не тратим силы.
У нас тоже пока без особых изяществ и вкусностей насчет сети: все пользовательские контейнеры в одном L2 сегменте и одной 10.16.0.0/12 сети. Пока серьезных проблем с безопасностью не видится, возможно, позже допиливать будем nova-docker драйвер для поддержки floating network.
Да, хорошо мирантис написали. Типа пул публичных ip адресов. Если взять для примера amazon ec2, то там для инстенса выделяют 10.x.x.x адрес (приватный) и floating (публичный), по которому инстенс доступен из интернетов.
Не уверен, что это именно то, что нам будет нужно, может, приватные сетки для разных заданий лучше создавать. Хорошо бы еще по vlan'ам рассовать их разным. Вообще, были какие-то попытки сделать поддержку neutron (SDN controller) для докера в openstack'е, не в курсе, как там успехи.
В ближайшее время в конфигурации сети точно ничего не буду глобального менять.
А, кстати, зачем вам могут понадобиться разные сетки и vlan'ы? (я просто не спец в сетях)

Не смотря на то, что у нас достаточно большое количество контейнеров, а некоторые (особенно во время рынка) генерят достаточно большой объем трафика, у нас даже подозрений ни разу не было, что надо делать сеть более продвинутой (именно с точки зрения производительности сети).

А что касается группировки сервисов — все сервисы организуются в кластера на более высоких уровнях. В основном, приложения внутри контейнеров сами несут ответственность за то, чтобы обнаруживать свои зависимости (через zookeeper или etcd, например). Они же сами обнаруживают изменения в составе кластера, переподключаются куда-либо при необходимости. Конечно, всегда есть вероятность, что сервис полезет куда-нибудь не туда. Но на практике такого никогда не возникало.

Какие еще могут быть показания для этого?

UPD: Это что касается управления baremetal-хостами. В amazon-е все более или менее распилено по vpc. Но там другие соображения, другие задачи.
Сервисы и все остальное (базы, message queue) тоже деплоим в контейнерах. Довольно сыро еще в этой области, вроде как docker совсем недавно начали активно это направление развивать blog.docker.com/tag/orchestration/.
Все хостовые системы у нас CentOS 7. Пока часть сервисов деплою с помощью Geard. Достаточно хорошо работает, особенно подходит для версий docker, когда в которых еще плохо работал механизм авторестарта контейнера (geard использует systemd). Еще geard'шные link'и мне понравились больше, чем встроенные в docker (geard разруливает линки с помощью iptables nat в сетевом неймспейсе контейнера).
Другую часть сервисов попробую деплоить уже без systemd, со встроенным авторестартом с помощью ansible. Не всем удовлетворил меня docker модуль для ansible. К примеру, нет возможность сделать docker pull нового имаджа с реестра. Можно передеплоить контейнер с предварительным pull'ом, но тогда получается даунтайм сервиса на время скачивания нового образа.
Ух ты! Вот geard я вообще упустил из вида. Большое спасибо за наводку. Мы в деплойментах, не использующих systemd, раскатываем puppet-ом контейнеры на хостах.
Я даже не в курсе, есть ли у puppet-модуля проблема аналогичная той, которую Вы описали. Вернее, я не уверен, что правильно понял смысл фразы

>> К примеру, нет возможность сделать docker pull нового имаджа с реестра.

У нас в допустимо нормальное одновременное сосуществование нескольких версий одного и того же сервиса. Т.е., мы имеем возможность поднять новую версию контейнера рядом со старой, а потом, убедившись, что она работает корректно, просто потушить старую версию. Нюансы, конечно, есть. Но жить с ними можно.
А как вы следили за живностью контейнеров и рестартовали их, если они подыхали, на docker версиях до 1.2.0 (до добавления restart policy blog.docker.com/2014/08/announcing-docker-1-2-0/)?

Еще интересно, как вы организуете версионирование образов контейнеров (названия, тэги)?

Правильно я понял, что ваша архитектура позволяет делать апдейты без даунтайма? Т.е. выкатываете новую версию контейнера, она уже входит в работу одновременно со старой, потом тушите старую. Балансировщики какие-то есть?
Изначально (я кажется выше вскользь упоминал) мы пытались использовать mesosphere. Раскатыванием контейнеров по хостам (и слежением за ними) должна была заниматься вот эта хрень github.com/mesosphere/marathon. Оно перезапускало остановленные контейнеры, и в случае потери хоста, перетаскивало контейнеры на другие живые хосты.

Мы жрали этот кактус более полугода, и докер 1.2 вышел еще тогда, когда мы не бросили mesosphere. Тем не менее, мы и сейчас не используем коробочный рестарт докера — за контейнерами следит, например, upstart. Функцию свою выполняет, острой необходимости что-то менять пока не было.

С версионированием пока что бардак.
1. Cо всякой инфраструктурой (проксики, zookeeper'ы и всякие прочие rabbitmq) все элементарно. Имя сервиса — и есть имя образа. Если образ собран из мастер-бранча, ему автоматически каждый раз лепится тэг latest. Если из какого-то постороннего бранча — в тэге просто выставляется имя бранча и номер сборки. Все потребности такая схема покрывает.
2. С эрланг-сервисами (которые мы сами разрабатываем) все уже чуть печальнее. Для каждой сборки задается отдельное имя образа (что-то типа "${BRANCH_NAME}_${BULD_ID}"), в качестве тега — уже конкретное имя сервиса (например, те же mal, zoe, kaylee).

Насчет апдейтов — да, все верно поняли. Не уверен, что точно понял, какие балансировщики вы имеете в виду, но попытаюсь.
1. Во-первых, на уровне клиентских web-socket'ов, мы по разным датацентрам раскидываем запросы dns'ом.
2. В каждом датацентре может быть поднято несколько одновременно функционирующих кластеров, дублирующих друг друга (например, на случай факапа при апдейтах). В каждом кластере (если он предназначен для вебсокет-клиентов, разумеется) одновременно работает ферма веб-серверов. Все они регистрируются в zookeeper (или etcd, не важно). По этим записям конфигурятся проксики (ngxin, либо haproxy) и именно они раскидывают клиентов по вебсерверам в пределах датацентра.
3. Для взаимодействия сервисов между собой у нас есть собственный самопальный мессаджинг (брат-близнец zeromq). Причины ухода со стандартного erlang distribution — отдельная обширная тема. Там тоже балансировщик уровня сообщений (самопальный) с некоторым уклоном в предметную область (и отчасти в legacy).

В плане апдейтов без даунтайма мы оставляем себе достаточно большой простор для действий. Все сервисы мы разрабатываем так, чтобы в любой момент они могли потерять свое состояние без каких-либо последствий. Поэтому, для нас вполне доступен даже самый простой вариант «выключить контейнер, сходить покурить и потом включить новый» (утрирую, конечно). Вполне работоспособна (и часто применяется) схема, про которую я упоминал выше — запустить новую версию сервиса, убедиться, что она работает, потушить старую. Чаще всего, все-таки, обновляемся целыми кластерами.
А, и кстати, еще вопрос. Пользователь внутри контейнера видит все 100500 Гб RAM и столько же ядер с хоста? Ну, например, если запустит htop. Ну и загрузку CPU и памяти он увидит именно хостовую? Или вы как-то справляетесь с этим? Если не секрет — как?
В начале статье есть ссылка на первое задание из курса, можете сами посмотреть, запустить top, извините, htop не поставил :)). Да, пользователь видит все хостовые ресурсы, как есть, никак не справляемся с этим. Docker-хосты, кстати, — это KVM виртуалки. Сейчас задача стоит донести пользователям максимум нашего опыта, показать, как и что можно делать с платформой, собрать фидбек и двигать в правильном направлении. Можно, конечно, с головой закопаться в вопросах безопасности, стараемся находить некий компромисс.
Да насчет компромиссов — это понятно ) Мне просто было интересно, может вы как-то случайно зацепили этот вопрос в процессе исследований.
Sign up to leave a comment.