Каким путем запросы клиентов проходят через кластер. Как обновляется кластер
Дилетант в бэкэнде и девопс'е. Появилась очередная серия пробелов в голове, касающихся понимания работы распределенных приложений, и немного их администрирования.
Жило-было веб-приложение. например React + nginx + nodejs + (какая-то база). Долгое время успешно работало на одном сервере. В глобальном DNS числится домен приложения my.amazing.app.com, ссылающийся A-записью на ip-адрес той единственной машины. На машине установлен Nginx, отдающий статику(html + css + js + изображения), хранящий сертификат Letsencrypt для https соединений, и проксирующий запросы на бэкэнд приложение.
Однажды приложение перестало справляться с потоком запросов(или мы предсказали это) и потребовало масштабирования. Устанавливается кластер (если еще не был установлен), будь то k8s, или docker-swarm. Докупаются машины, присоединяются к кластеру, сервисы плодятся до желаемого состояния.
- Немного глупый вопрос, но все-же. Правильно ли я понимаю, что пока в глобальном DNS числится одна A-запись - все клиентские запросы продолжат проходить через первую "главную" машину, независимо от размера кластера(о котором DNS вообще не в курсе)?
- Кто первым "встречает" клиентский запрос на узле кластера? Некий агент кластера со своим балансировщиком или сервис этого узла, слушающий порт запроса(в моем случае nginx). Меня немного пугает, что если первый nginx - то получится что статику будет отдавать всегда одна машина, да и вообще все запросы проходят через него одного. И если упадет или он, или сам узел, то пиши пропало.
- Далее, каким образом nginx перенаправляет запросы на бэкэнд сервисы, которые на разных машинах, да еще и рождаются/падают/умирают? Насколько я понял, k8s использует локальный DNS и виртуальные IP для своих сервисов. И если в конфиге nginx велеть перенаправлять запросы на
nodejs-service.default.svc.cluster.localто балансировку выполняет сам кластер. Как такой-же механизм реализован в docker-swarm? Потому как его пока рассматриваю в первую очередь. - Ежели есть практика добавления А-записей некоторых более-менее постоянных, "фронтовых" машин растущего кластера, то логично что и nginx'ов будет несколько. В этом случае у всех прокси-серверов должен(?) быть один общий(?) ssl-сертификат, который периодически должен обновляться? Как это реализовать? Общий volume?
- Сколько nginx'ов вообще принято иметь в кластере? Есть какое-то правило/формула/рекомендации? Не имею никакого представления - насколько трудоемко отдавать статику и быть посредником динамических запросов.
- Насчет обновления кластера. Я понимаю, для бэкэнд приложений наиболее распространена практика сборки образа на машине разработчика или CI, пуш новой версии dockerhub и (пока не знаю какими механизмами) отправка измененного конфига кластеру, который постепенно обновит изменившиеся контейнеры без простаивания. Как реализуется подобное обновление для статического контента? Ведь должен присутствовать на каждом узле, где есть прокси-сервис.
- Какая обыкновенная практика передачи приватных данных кластера в контейнеры? Например, бэкэнд-приложение должно знать имя пользователя и пароль к базе(сам адрес базы пусть будет захардкожен). Ввиду опыта только с docker-compose кучами(stack), знаком с пробросом в контейнеры переменных окружения из env-файлов. Что-то мне подсказывает что в динамичном кластере так это не делается. Наткнулся на ключевую фразу "обнаружение сервисов" consul, etcd, zookeeper, но не смог нащупать - как и когда контейнер может обратиться к этому распределенному хранилищу, или же сам кластер прикрепляет эти данные "новорожденному" контейнеру. Был бы благодарен ссылкой на пример для docker-swarm, но не обязательно его.