Комментарии 28
Жаль не срослось у нас с вами, когда общались насчёт проекта с прошлой работы — наше руководство не хотело платить за обслуживание, только за внедрение по какой-то разумной часовой ставке специалиста, а обслуживать и развивать дальше своими силами. Одной из причин сменить работу это стало.
Уже из спортивного интереса пара вопросов не раскрытых, которые могут кого-то сподвигнуть на переход:
- есть динамическое создание неймспейсов (стэков в терминах swarm) при появлении ветки в git и удаление при удалении или таймауту, с автоматическим же созданием DNS-имён для каждого сервиса в каждой ветке?
- локальное разворачивание всего проекта или отдельных контейнеров (минимум двух — клиента и сервера, с привязкой к остальным к какому-нибудь контуру на сервере) на машинах у разработчиков с отражением правок на хосте сразу в контейнере без билда
Также хочу отметить для читателей, что сложности по переводу PHP-приложения в стейтлесс многими сильно преувеличиваются, считается необоснованно, что объём работы очень большой. Для сессий часто достаточно настройку в php.ini сменить, а для пользовательских или генерируемых приложением файлов — примонтировать nfs/smb шару в контейнеры, если слова типа "(например, Amazon S3 или хранилища файлов от Selectel) или вариантами с хранилищем на серверах клиента, реализованным на minio или Ceph (S3/Swift API)" вас пугают, как меня. Основная сложность по моему опыту — конфигурирование приложения, передача ему значений конфигов в зависимости от окружения, которые нельзя просто поместить в репозиторий или аргументом занести в контейнер при билде. В идеале приложение должно быть спсобно все динамические параметры принимать через env переменные или же оркестратор должен генерировать конфиги и пробрасывать в контейнеры в нужном приложению формате.
VolCh, спасибо за вопрос!
Жаль не срослось у нас с вами, когда общались насчёт проекта с прошлой работы — наше руководство не хотело платить за обслуживание, только за внедрение по какой-то разумной часовой ставке специалиста, а обслуживать и развивать дальше своими силами. Одной из причин сменить работу это стало.
Тут нам есть над чем поработать. С 2008-го года мы продавали, фактически, одну единственную услугу — это полное обслуживание инфраструктуры "под ключ". Не всем компаниям это подходит. Мы прямо сейчас запускаем другой вид услуг — именно консалтинг плюс внедрение. Такой формат гораздо лучше подходит компаниям, у которых уже есть своя сильная команда эксплуатации и им нужно просто быстрей получить опыт. Второй момент — сейчас все очень быстро меняется. Новая версия Kubernetes выходит раз в 3 месяц и с выходом каждой версии появляются возможности, меняются best practice, за этим нужно постоянно следить и переделывать. А кроме новой версии, и у нас и у всего DevOps комьюнити появляется опыт и экспертиза, как более эфеективно решать какие-то вопросы. Мы каждую неделю находим что-то и переделываем сейчас во всех проектах. Вот кроме услуги "консалтинг + внедрение" думаем продавать некоторую "подписку" (там будут текующие best practice, чеклисты по обновлению, проверенные нами helm и пр., а так же возможность задавать нам вопросы).
есть динамическое создание неймспейсов (стэков в терминах swarm) при появлении ветки в git и удаление при удалении или таймауту, с автоматическим же созданием DNS-имён для каждого сервиса в каждой ветке?
Да. Достаточно подробно рассказывал об этом позавчера на Highload: http://www.highload.ru/2017/abstracts/3073. Видео будет через некоторое время.
локальное разворачивание всего проекта или отдельных контейнеров (минимум двух — клиента и сервера, с привязкой к остальным к какому-нибудь контуру на сервере) на машинах у разработчиков с отражением правок на хосте сразу в контейнере без билда
Пока что можно только развернуть полную-полную копию локально в minikube. Такой вариант слабо подходит для проектов с микросервисной архитектурой, но вполне приемлем для других.
Основная сложность по моему опыту — конфигурирование приложения, передача ему значений конфигов в зависимости от окружения, которые нельзя просто поместить в репозиторий или аргументом занести в контейнер при билде. В идеале приложение должно быть спсобно все динамические параметры принимать через env переменные или же оркестратор должен генерировать конфиги и пробрасывать в контейнеры в нужном приложению формате.
На самом деле это не является блокером, есть вполне жизнеспособный workaround. Если переделывать конфигурацию приложения на ENV нет времени, можно без проблем сделать простейший shell-скрипт, который при запуске приложения сгенерит ему конфиг (из переменных окружения).
docs.docker.com/engine/admin/volumes/volumes
Три основных варианта, вроде.
- Прибиваем гвоздями инстансы к конкретным хостам с локальными томами. Теряем много плюсов от контейнеризации.
- Инстансы подключаются к сетевому хранилищу, прибиваясь к нему. Часто сильно снижает скорость работы БД, но могут быть нюансы, например, если и так логические диски на хостах физически каким-нибудь SAN с доступом по сети являются.
- Настраиваем сложный кластер с хранением данных в локальных томах, с автоматическим подключением нового инстанса к кластеру, догонянием инстанса кластера (лучше от переиодически снимаемого снэпшота, а не с ноля, но от базы зависит) и переключением в режим полноценной ноды. Самый сложный вариант, сильно зависящий от конкретной базы, может потребовать доработки клиентов, но полностью использует преимущества контейнеризации и кластеризации
СУБД выделены в отдельную сущность, так как они в большинстве случаев находятся за пределами Kubernetes
На сколько я могу понять — БД не для контейнеров? По крайней мере в текущей реализации
БД не для оркестрации контейнерами.
То есть запустить на одном хосте локально в контейнере БД с пробросом папки на хост все еще можно. У вас так же остается возможность версионировать через образ и прочее.
А для кластеров на кубе вроде юзают такие штуки: https://coreos.com/operators/
Если вы в k8s поднимете mysql в StatefulSet с одним инстансом и PersistentVolumeClaim для хранилища — это фактически ничем не будет отличаться от mysql вне k8s.
В самой простой ситуации вы прибиваете Volume на каталог хост машины и получаете 1:1 ту же надежность как и вне кластера (машина умерла — БД умерла с ней).
Как это можно улучшить уже средствами k8s? Можно использовать сетевое хранилище для PVC, например ceph rbd, aws ebs, iscsi или даже nfs. Таким образом при потере машины, рабочая нагрузка мигрирует на другую, а хранилище перемонтируется. Это не гарантирует отсутствие даунтайма, и потенциально медленнее (сетевое хранилище хуже чем локальный SSD).
Дальше в дело вступает репликация. Если ваша БД может комфортно работать в режиме master-master, то вы просто поднимаете N реплик тем же StatefulSet и потеря любой из них не будет вас волновать, мастера догонятся друг от друга. В таком случае можно использовать эфемерное хранилище (тот же локальный диск), т.к. потеря данных одной ноды не критична.
Наконец, можно делать R/W + R/O реплики (для mysql это, наверно, оптимальный вариант для быстрого чтения и наименьшего простоя). У k8s прямо в доках есть пример для mysql. Тут первая реплика это R/W с персистентным хранилищем, а последующие — R/O с эфемерным и они догоняются от реплики N-1. Падение машины с первой репликой дает вам даунтайм на запись (пока mysql запускается на другой ноде), потеря R/O реплик полностью незаметна, плюс R/O реплики читают с локального быстрого диска.
TL;DR: БД отлично работают в контейнерах, просто надо понимать где вы выигрываете, и что теряете.
На Highload за 2 дня у меня спросили раз 40. Было два вида вопросов — почему мы (Флант) считаем, что базу стоит ставить в контейнер/kubernetes (это же опасно!!!) и почему мы считаем, что базу НЕ стоит ставить в контейнер/kubernetes (это же удобно). Это означает, что мы всех запутали. Чтобы распутать — наверное напишем отдельный пост на хабре. Но отвечу кратко:
- Все базы кроме прода — решительно да!
- Прод — зависит от:
- Если ваш сетевой сторедж позволяет переваривать ваш объем данных и количество IOPS'ов, и вы в нем уверены, — да,
- Если это slave (который сам может bootstrap'аться с master) — да,
- Если ваша база это горизонтально масштабирующийся мультимастер (cassandra, mongo, galera, etc), и вы не боитесь — может быть да,
- Если… (и тут я понял, что все таки надо это систематизировать и писать статью).
Итог — мы рекомендуем загонять в Kubernetes все НЕ продовые базы, но пока мы не можем рекомендовать это делать во всех в проде. Думаем, что через 1-4 месяца ситуация может измениться (со стабилизацией local storage).
Вы и сейчас запутываете :(
Все базы кроме прода — решительно да!
Что да то? Стоит или не стоит?
Из продолжения, конечно, становится понятно, но это всё равно не дело.
Простите. Хочется аж прямо минуснуть свой же комментарий.
Лучше просто исправьте его.
Кстати, хотелось бы услышать про то, как у вас устроен бэкап.
Про бэкап невозможно ответить кратко. Но тем не менее. Сейчас borgbackup в отдельном контейнере или поде. Мечтаем сделать operator или admission controller, который будет делать бекап borgbackup'ом согласно аннотациям в pod'ах.
Спасибо за статью!
Интересует а как вы обновляете кластера кубернетес, особенно которые на квм\бареметал? А также существует ли регулярная процедура\полиси апдейта? используете ли tectonic ?
Спасибо за статью!
Мы рады, что вас заинтересовало.
Интересует а как вы обновляете кластера кубернетес, особенно которые на квм\бареметал? А также существует ли регулярная процедура\полиси апдейта? используете ли tectonic ?
Пока руками обновляем, как бы это не казалось странно. Ждем поддержки bare metal в kops. С 1.6 на 1.7 обновились прекрасно. На следующей неделе, вероятно, будем обновляться до 1.8. На четкий полиси обновления самого kubernetes пока не вышли, это цель на начало следующего года. Пока ждем дозревания инструемнтов.
используете ли tectonic ?
Коллега выше забыл написать, что Tectonic (и прочие аналоги) не используем — работаем с upstream-дистрибутивом Kubernetes.
Т.е. если докер для разработки мы используем и хотели бы автоматизировать деплой также с использованием контейнеров. Но пока что на один сервер и только в будущем масштабироваться. Тоже Kubernetes?
А что посоветуете для тех, кто только недавно понял, что контейнеризация и, в частности, Docker — это круто, хотел бы в новом проекте сразу заложить масштабируемую архитектуру, но для кого сразу заказывать N серверов у вас — дорого и неразумно, ведь все сервисы пока что спокойно уместятся на одной виртуалке?
IMHO — всячески стараться ничего не делать на вырост, акцентируя максимум внимания на фичах, которые позволят проекту вырасти. По нашему опыту, доделать приложение до минимального соответствия https://12factor.net/ обычно сильно проще, чем кажется. Я бы даже не советовал заморачиваться с правильным хранением файлов (в S3 like), пока вы влезаете в одну виртулку. Самые большие проблемы, обычно, возникают с latency до базы / redis / memcached. Пока проект живет на одной виртуалке и ходит по localhost — можно без существенных проблем отправлять по 500 запросов в memcached (базу, etc) с одного входящего запроса юзера. Но как только начинаешь такой проект растаскивать по отдельным инстансам (виртуалкам или железкам — не важно), появляется сетевой latency, и эти 500 запросов, раньше занимавших 10мс, начинают занимать несколько секунд. И эти несколько секунд, при любых флуктуациях в сети, могут легко превращаться и в 10 секунд. Но всем известно, что несет с собой преждевременная оптимизация, так что — лучше просто об этом не думать.
Т.е. если докер для разработки мы используем и хотели бы автоматизировать деплой также с использованием контейнеров. Но пока что на один сервер и только в будущем масштабироваться. Тоже Kubernetes?
Я бы категорически не рекомендовал делать свою инсталляцию Kubernetes. Надо понимать, что у нас в компании больше 50 человек, из которых как минимум 20 каждый день по 8 часов занимаются чем-то связанным с Kubernetes. Команде из нескольких человек это просто не потянуть. Как вариант — использовать hosted Kubernetes (в Google и Asure уже есть, в AWS должно вот-вот появиться). Если нужно остаться на этой одной виртуалке — вам, наверное, в сторону docker compose.
Начните с docker-compose, когда натолкн'тесь на ограничения — попробуйте docker swarm кластер из одной ноды. И только когда и в нём станет тесно, тогда смотрите в сторону других решений.
Инфраструктура с Kubernetes как доступная услуга