kubernetes

Зачем Kubernetes: когда Docker-а мало

В модуле про Docker все происходило на одном сервере: несколько контейнеров, Docker Compose описывает их в одном файле, одна команда поднимает все разом. Для пет-проекта, небольшого сервиса или внутренней утилиты этого вполне достаточно, и многие проекты на таком уровне спокойно живут годами.

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

Вопросы, на которые Docker не отвечает

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

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

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

Вышла новая версия приложения, и ее нужно выкатить на все двести контейнеров. Остановить все и запустить заново нельзя, иначе сервис ляжет на время обновления. Значит, заменять придется по очереди, после каждой замены проверяя, что новая версия живая. Руками это день монотонной работы с высокой ценой ошибки.

И последнее: копии приложения разбросаны по разным серверам и постоянно переезжают. Куда тогда направлять запросы пользователей, если адреса контейнеров меняются каждый день?

Каждая из этих задач по отдельности решаема скриптами и усилием воли. Все вместе и каждый день, без передышки, уже нет. Класс таких задач называется оркестрацией контейнеров, и Kubernetes это инструмент, который их закрывает.

Что такое Kubernetes

Если коротко, Kubernetes управляет контейнерами: он не заменяет Docker и не выполняет работу самих приложений, а решает, на каком сервере запустить контейнер, следит, что все запущенное живо, перезапускает упавшее, добавляет и убирает копии, проводит обновления. Всю ту рутину распределения и присмотра, которую при двухстах контейнерах человек уже не вытягивает, он берет на себя.

Факт. Kubernetes родился в Google в 2014 году на основе Borg, внутренней системы, которая годами управляла контейнерами в дата-центрах компании, и был отдан в open source. Название это греческое слово «кормчий», рулевой корабля. А сокращение K8s читается просто: между K и s ровно восемь букв.

Серверы под управлением Kubernetes объединяются в кластер, и это меняет саму оптику. Вы перестаете думать про «сервер 17» и «сервер 23»: кластер выглядит как один большой компьютер с общим запасом ядер и памяти, а отдельный сервер внутри него называется узлом и становится расходным материалом.

Вы общаетесь с кластером как с единым целым, а раскладку контейнеров по узлам Kubernetes держит при себе.

Желаемое состояние, но теперь непрерывно

Главный принцип Kubernetes знаком вам по модулю про инфраструктуру как код: вы описываете желаемое состояние, а не команды. Не «запусти контейнер на сервере 7», а «копий этого приложения должно быть пять». Описания пишутся в YAML-файлах, которые называются манифестами, и да, это снова YAML, после .gitlab-ci.yml и playbook закономерность уже очевидна.

Есть, однако, отличие, которое делает Kubernetes особенным. Ansible приводит серверы к описанному состоянию в момент запуска playbook: запустили, привел, закончил. Kubernetes же следит за состоянием непрерывно, круглые сутки. Сказано «пять копий», и он каждую секунду сверяет, что их действительно пять, и сам чинит любое расхождение.

Упал контейнер, копий стало четыре, Kubernetes тут же поднимает пятую. Умер целый узел, и все его контейнеры за секунды пересоздаются на оставшихся. Это свойство называется self-healing, самовосстановление, и жизнь дежурного инженера оно меняет буквально: история «алерт в три часа ночи, сонный человек с ноутбуком перезапускает сервис» превращается в «контейнер упал, был автоматически пересоздан, инженер узнал об этом утром из графика».

Масштабирование в одну строчку

Раз количество копий это строчка в манифесте, то и масштабирование сводится к правке числа. Было replicas: 3, стало replicas: 10, и Kubernetes сам запускает семь новых копий, подобрав для них узлы посвободнее.

Дальше больше: это число Kubernetes умеет менять автоматически, по нагрузке. Днем трафик растет, копии добавляются, ночью спадает, лишние убираются. Сервис переживает наплыв пользователей без участия человека, а в спокойные часы не жжет ресурсы впустую.

Обновление без даунтайма

Выкат новой версии Kubernetes проводит постепенно, и называется это rolling update. Старые контейнеры заменяются новыми по очереди: поднял новый, дождался, пока тот подтвердит, что живой и готов принимать запросы, только после этого погасил старый и перешел к следующему.

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

Честная оговорка о цене

У всего этого есть цена, и зовется она сложностью. Kubernetes большая система со своими концепциями, объектами и способами сломаться, и ее нужно учить, обслуживать и мониторить. Для пяти контейнеров на одном сервере это стрельба из пушки по воробьям, ведь Docker Compose решит ту же задачу в сто раз проще. Kubernetes окупается там, где есть масштаб, требования к отказоустойчивости и частые выкаты, и заголовок стоит читать буквально: K8s нужен тогда, когда Docker-а действительно стало мало, а не потому, что он есть у всех. К этому разговору мы вернемся отдельным шагом в конце модуля.

В вакансиях DevOps-инженера при этом Kubernetes стоит в первой тройке требований вместе с Linux и Docker, потому что компании с масштабом это как раз те, кто нанимает девопсов. Работа с ним выглядит знакомо по предыдущим модулям: YAML-манифесты в Git, деплой в кластер через пайплайн, и весь стек, что прошли, смыкается в одну картину.