Pull to refresh

Не куб, а кубик: kubernetes для не-highload

Level of difficultyEasy
Reading time11 min
Views18K

Может ли kubernetes сделать жизнь админов небольших и средних компаний проще или же это шайтан-машина для кровавого enterprise и оголтелых стартапов?

Сейчас Kubernetes раскатывают все, кому не лень, для всего, что только может прийти в голову. Чаще всего там, где ему не место, но он развёрнут и используется, причина довольно прозаичная: обучение за счёт работодателя проектов. Все хотят получать больше, а для этого нужно соответствовать критериям из вакансий, где практически везде написаны эти 3 волшебных символа: K-8-S.

Основная проблема кубера - громоздкость. В целом это не проблема, когда он managed в каком-то облаке с автоскейлом и нодагруппами. Когда же всё это разворачиваешь руками и тем боле bare-metal, то начинаешь задумываться над своей адекватностью (и не безосновательно). Даже если развернёшь, то поддерживать такое прям совсем не хочется. Если бы не такая лютая сложность, то можно было бы столько всего развернуть в отказоустойчивом режиме с масштабированием и мониторингом. Столько статей пестрят helm'ами, операторами и разными "вкусностями".

Мало-помалу все приходят в итоге к какому-то инструменту для автоматизированного деплоя и снова впадают в отчаяние, потому что он зачастую не проще, а иногда даже сложнее. Собственно, ребята с Rancher Labs видимо задолбались в поддержке и решили сделать свой кубер, который будет проще, быстрее, легче, а главное его будет проще доставить. Так появился k3s - неприхотливый, простой как булыжник младший брат k8s. А с учётом того, что далеко не для всего нужен весь комбайн, то это неплохой вариант для тех, кому нужны некоторые возможности kubernetes, но без лютого хайлоада и катастрофоустойчивости.

Что это за зверь?

K3s - это полностью (по заверению разработчиков) совместимый дистрибутив кубера, с некоторыми улучшениями:

  • Это всего один бинарь, который можно легко положить куда угодно и просто запустить как сервис.

  • Они переписали хранилище на Sqlite (недавно перешли на Dqlite) и добавили ещё несколько драйверов для SQL баз и etcd3.

  • Добавили "батарейки": балансировщики там всякие, сети и т. п.

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

Чтобы его установить, достаточно просто запустить скрипт на целевой машине: curl -sfL https://get.k3s.io | sh - и можно начинать работу. Скрипт автоматически выкачает бинарь по нужному пути и поднимет все необходимые сервисы (systemd). Скрипт также подтянет все необходимые инструменты для работы, такие как kubectl, crictl и скрипты для удаления ноды или кластера. Вес самого бинаря на данный момент около 63мб. При желании можно доработать скрипт и разместить все необходимые файлы в локальной сети. Если очень сильно хочется, то можно самостоятельно реализовать установку, выгрузив нужные бинарники на хост, создав сервисы и запустив их. На момент написания статьи, поддерживается версия кубера 1.26.

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

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

Но мы же хотим отказоустойчивость. Такой вариант подразумевает несколько master-нод. В этом плане k3s выигрывает у старших собратьев, потому как может работать с двумя мастерами, вместо трёх. Этот вариант крайне не рекомендован, но возможен. При этом есть три пути:

  1. Развернуть несколько master'ов со встроенной БД и отдельно подключить некоторое количество worker'ов, на которых будут работать непосредственно развёрнутые сервисы. Такой вариант лучше всего подходит для случаев, когда "железок" очень много и они мелкие (например, кластер на базе Raspberry Pi). Тут подробная документация как это делать правильно.

  2. Развернуть кластер БД отдельно, а к нему подключать некоторое количество нод, которые могут быть как мастерами, так и worker'ами. Такой вариант подходит для более консервативного набора серверов и, особенно хорошо, если уже присутствует кластер БД в сети (совместимость только с MySQL/MariaDB и Postgres). База данных при нечастых манипуляциях довольно скромно нагружается, поэтому вполне может ужиться с 1С базой параллельно. В некоторых организациях практикуют подход "единой СУБД", когда есть большой кластер БД и все сервисы подключаются к нему, все бэкапы завязаны на нём и т. п. Если такое уже есть, то это отличный вариант. В противном случае, можно сделать Gallera/Percona SQL на трёх нодах и на этих же нодах развернуть кластер. Но в этом случае нужно заранее планировать нагрузки, чтобы не навредить БД другими сервисами (и наоборот). Для тех, кому нужна отказоустойчивость (всякие там перезагрузки "на горячую", сгоревший сервер и т.п.), - это наиболее оптимальный вариант, работа продолжится даже при отключении части серверов. Здесь можно прочитать, как создать кластер с внешней базой данных.

  3. Поднять только один master и подключать к нему дополнительные ноды только как worker'ы по мере увеличения нагрузки. В 90% это подходящий вариант. Если сервисы не хранят в себе данных, которые не имеют резервных копий, то такой вариант вполне себе может работать годами в небольших компаниях. Порой split brain приносит больше боли, чем такая архитектура. Если кластер будет стоять на окошке в кабинете директора (или CTO в отделе одного-двух сотрудников), то этот вариант более чем подходящий, а порой и предпочтительный.

При любом из этих вариантов архитектуры добавление новых нод для увеличения ресурсов кластера под рабочие нагрузки будет практически одинаковым (для нескольких мастеров, нужно будет создать общий Virtual IP, чтобы ноды подключались по нему). С учётом того, что в данной статье рассматривается не highload, то этого будет вполне достаточно. Если от простоя в 1 час компания не понесёт многомиллионные убытки (в реальном, а не "упущенном" варианте), то это 100% ваш вариант.

Установка ещё проще

Казалось бы, куда уже проще? Но одному человеку оказалось и этого много, поэтому он написал бинарь, который раскатывает кластер в одну строку. Проект называется "Кетчуп" и пока что показывает себя довольно неплохо. Всё, что ему нужно, - доступ к хосту по SSH.

k3sup был создан не для того, чтобы один раз развернуть кластер, но вполне себе для этих целей пригоден. Это бинарный исполняемый файл, который содержит в себе модуль ssh. Им он подключается к удалённой машине (виртуалке, "малинке" или bare-metal хосту) и выполняет все те же самые действия, что пришлось бы проделать нам вручную. По сути это просто удобная обёртка для установки новых кластеров.

Вот пример, как можно быстро раскатать кластер на bare-metal из мастера и двух дополнительных воркеров:

  • Сеть 172.16.0.0/16.

  • Физические серверы располагаются на 172.16.100.202 (master+worker) и 172.16.100.203-204 (workers).

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

# Генерим ключ
ssh-keygen -t ecdsa -f ~/.ssh/id_rsa
# Раскидываем его по хостам
for i in 20{2..4}; do ssh-copy-id -i ~/.ssh/id_rsa.pub -f ubuntu@172.16.100.$i; done
# Поднимаем мастер ноду (без некоторых сервисов, которые можно потом руками более гибко поднять)
k3sup install --ip 172.16.100.202 --user ubuntu --k3s-extra-args '--disable servicelb,traefik,local-storage --flannel-backend=none --cluster-cidr=10.10.0.0/16 --disable-network-policy'
# Подключаем полученный конфиг
export KUBECONFIG=$(pwd)/kubeconfig && kubectl config set-context default
# Катим canal (у него очень удобное межхостовое взаимодействие и куча всяких других плюшек)
kubectl create -f kubectl replace -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/tigera-operator.yaml
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/custom-resources.yaml
# Добавляем ноды
for i in 20{3..4}; do k3sup join --ip 172.16.100.$i --user ubuntu --server-ip 172.16.100.202 --server-user ubuntu; done
# Катим metallb, без которого bare-metal нормально не завести
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/namespace.yaml
cat <<EOF > metallb_values.yaml
configInline:
  address-pools:
   - name: default
     protocol: layer2
     addresses:
     - 172.16.100.221-172.16.100.229
EOF
helm upgrade metallb metallb/metallb -f metallb_values.yaml --install --wait --timeout 600s --namespace metallb-system
# Катим ингресс на базе nginx
helm upgrade --install ingress-nginx ingress-nginx   --repo https://kubernetes.github.io/ingress-nginx --namespace ingress-nginx --create-namespace
# Можно сразу сделать его дефолтным
kubectl annotate ingressclasses.networking.k8s.io nginx ingressclass.kubernetes.io/is-default-class="true"

На такую установку, в зависимости от канала в интернет, уйдёт от 5 до 15 минут. Технически сервера могут располагаться и во внешней сети. Но тогда нужно внимательно прочитать документацию на предмет открытых портов и заморочиться фаэрволом. Metallb также поддерживает BGP, что могло бы помочь держать серверы внутри, а балансировщик сразу выставить наружу, но это выходит за рамки данной статьи. Также я бы рекомендовал развернуть какое-то хранилище для Persistent Volume Storage. Для этих целей очень хорошо подойдёт Longhorn (может помочь очень гибко управлять хранилищем, есть даже GUI).

В целом довольно просто развёрнутый кластер - это цель всех инструментов деплоя. Так что не сказать, что это прям что-то инновационное. Но в данном случае мы получим ещё и удобно обслуживаемый кластер. Если хосты достаточно мощные, то можно для личного удобства поверх всего этого развернуть Rancher, который не только предоставит GUI для управления кластером, но и позволит управлять, разворачивать и обновлять другие.

Крутая фича в такой интеграции

Rancher официально в своей документации заявили, что кластера развёрнутые на базе k3s можно обновлять прям из интерфейса. Вместе с интерфейсом для раскатки приложений - это сводит всю работу над кластером в кликание мышкой, в лучших традицией "свидетелей Гуя". Не сказать, что я большой поклонник такого подхода, но это может быть очень удобно для команд разработки, которые будут буквально по клику получать нужный им сервис. REST API так же добавляет комфорта в интеграции.

В целом сама фича очень полезная и избавляет от кучи головной боли, связанной с поддержкой кластера и приложений в нём.

Про балансировку

Вариант установки выше подразумевает, что кластер живёт за NAT'ом и имеет полноправную связь между нодами не фильтрованного L2 трафика. В этом случае, при создании Service с типом LoadBalancer у кластера будет появляться Virtual IP, на который можно смело "заворачивать" трафик из внешней сети с нужным портом. Так, например, если вы развернёте по инструкции выше, то у nginx ingress сервиса будет IP 172.16.100.221 (самый первый) и открыты порты 80 и 443. Посмотреть список сервисов в формате имя_сервиса=ip можно командой:

kubectl get svc --all-namespaces -o=jsonpath='{range .items[?(@.status.loadBalancer.ingress)]}{.metadata.name}{"="}{.status.loadBalancer.ingress[0].ip}{"\n"}{end}'

Есть вариант сложнее, в котором можно поднять BGP с маршрутизатора на кластер в metallb. Он требует больше "телодвижений" и выделенной подсети от провайдера. Для небольших кластеров зачастую это overhead. Можно подробнее почитать здесь и здесь.

Ещё один интересный вариант предложил @Heggi в комментариях: развернуть ingress как DaemonSet с network: host для контроллера. Таким образом все ноды будут выполнять роль балансировщика и можно добавлением нескольких A/AAAA-записей реализовать отказоустойчивость. Конечно мы за это платим ресурсами, но такой вариант весьма неплох для небольших кластеров. Важно убедиться, что остальные порты кластера надёжно защищены фаерволом. Но у такого варианта есть некоторые плюсы: отказоустойчивость полностью коррелирует с количеством нод, производительность входящих соединений, полный контроль портов через Ingress.

Как обновлять вручную

При каждом запуске k3sup будет выполняться загрузка актуальной версии k3s. Если нужно зафиксироваться или обновиться на какую-то конкретную то используется ключ --k3s-version с указанием релиза k3s из Github.

Если следовать примеру, то надо просто повторить команды из строк 6 и 13 в точности как они были написаны (за исключением указания версии k3s).

Удобный не-highload

Проект изначально был рассчитан на то, чтобы развернуть в нём сам Rancher, а уже потом плодить новые кластеры как кроликов. Т. е. он не был рассчитан на миллионы запросов в секунду, с десятками тысяч контейнеров, SLA с 5 девятками после запятой и т.п. Если к этому относиться спокойно и без иллюзий, то получается вполне себе удобный инструмент для администратора. Что же может быть полезного в таком кластере?

Внутренние сервисы

Какие сервисы можно было бы установить и сделать жизнь относительно небольшой организации проще:

  • Локальное S3 хранилище на базе Minio (чарт). Довольно приличное количество сервисов умеют хранить данные в S3, удобно управлять доступом, шарить какую-то статику (вплоть до образов дисков). Может выступать как gateway для облачных S3-сервисов. Довольно полезный инструмент для многих задач. При грамотном деплое сможет масштабироваться дальше вместе с кластером. Здесь можно хранить бэкапы, конфиги, технически можно хранить образы для PXE и многое другое. Зачастую этот сервис самый нужный и удобный. Его легко можно заменить простым Nginx, но не будет такого гибкого управления доступом + хранилище будет ограничено либо одной нодой, либо должно лежать где-то в отказоустойчивом хранилище. Ещё S3 хранилища довольно удобно и быстро синхронизируются между собой с помощью различных утилит. Бэкап такого хранилища можно организовать с помощью CronJob в любое другое и быть спокойным за свои данные.

  • Pi-Hole (чарт) - небольшой инструмент для блокировки рекламного трафика. Пусть вас не смущает "PI" в названии, потому что инструмент заточен для домашних экспериментов на "малинке". Но вполне себе может послужить и в корпоративной среде.

  • Gitea (чарт) может стать локальным хранилищем для исходников и наработок внутри компании. Более того, он вполне может стать коллектором инцидентов и трекером задач. Технически можно развернуть целый комбайн в виде Gitlab (чарт), но очень часто для небольших организаций достаточно и Gitea.

  • В зависимости от размеров любви к метрикам, можно развернуть Prometheus Operator (чарт) или VictoriaMetrics Operator (чарт). Если ко всему этому аккуратно прикрутить ещё и AlertManager, то в принципе можно сделать свою работу тихой и безмятежной на долгие месяцы, а иногда и годы. Более того, можно собирать данные с различных устройств вроде Mikrotik или Cisco, что позволит ещё и анализировать качество канала и трафика.

  • Мне лень было подбирать чарты, но к предыдущему сервису логично так же прибавить и ELK-стек, чтобы собирать логи отовсюду, а затем внимательно их изучать. Это может очень понравиться не только разработчикам и админам, но и заскорузлым безопасникам, которые захотят отслеживать какие-то действия на рабочих станциях сотрудников (взгляд неодобрения).

  • Postfix релей (чарт) я бы не стал разворачивать (больше за использование Proxmox Mail Gateway, который сильно больше вещей может предложить), но некоторым может пригодиться.

Сервисы для сотрудников

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

  • Nextcloud (чарт) - удобный комбайн для управления файлами внутри компании. По сути это "облако" в привычном понимании пользователей. Можно поставить клиент на телефон, на PC и синхронизировать их между собой. Практически "из коробки" идёт плагин Talk для корпоративной связи (чат + звонилка). Так же есть куча плагинов, которые изрядно облегчат обслуживание файлов и документов. Хорошо интегрируется с S3 хранилищами, а значит можно установить в качестве хранилища внутренний S3.

  • Collabora Online (вариант чарта) - не сказать что прям замена MS Office, но хороший помощник для редактирования документов онлайн. В сочетании с Nextcloud, можно развернуть буквально "облачный офис" (если вся работа сотрудников ведётся в документах). Как альтернативу можно посмотреть OnlyOffice (чарт), несмотря на довольно урезанную версию Community.

  • Wordpress (чарт) - при достаточно хорошем канале, вполне можно разместить корпоративный сайт или интернет-магазин. Почти вся работа с движком осуществляется через плагины и базу с контентом, поэтому довольно удобно будет управлять масштабированием. Разработчиков под этот движок очень много, а переезд куда-то за пределы офиса осуществить будет в дальнейшем не очень сложно. В качестве альтернативы или дополнения есть форум phpBB (чарт) и магазинчик от OpenCart (чарт). Тут уж на вкус, цвет и задачи.

  • Кому-то может понадобиться CRM от SuiteCRM (чарт). Хотя есть (частенько печально) известный Bitrix24 (магия).

  • Корпоративную базу знаний вполне можно разместить на MediaWiki (чарт). Даже если компания небольшая, онбординг новых сотрудников может заметно ускориться с помощью подобных сервисов.

  • Если вдруг Nextcloud Talk будет недостаточно, то на помощь может прийти Rocket.Chat (чарт) или Mattermost (чарт). Такие вот хорошие альтернативы Slack в локальной среде. Оба поддерживают внутренние звонки.

  • Есть случаи, когда люди поднимают даже 1С Web-сервис в кластере. Не одобряю, но и не осуждаю.

Вместо итога

В целом всё это можно поместить вне Kubernetes, организовать на виртуалках нужные сервисы и поддерживать их. Всё можно сделать иначе и это тоже будет правильно. Лично мне проще сделать свою работу так, чтобы я мог за довольно ограниченный промежуток времени полностью повторить инфраструктуру с нуля. Возможности helm позволяют мне это сделать и сохранить описание инфраструктуры в git (например, стороннем). При грамотном подходе, какая-то сервисная или аутсорс компания могла бы развернуть на своих мощностях несколько похожих окружений для своих клиентов, предлагая это как услугу. С учётом минимального оверхеда и более удобного управления лимитами ресурсов, это может быть сильным инструментом в руках Ops'ов.

Ко всему прочему такие навыки несколько сгладят переход системных администраторов из среднего и малого бизнеса в корпоративный сектор. Они будут иметь уже довольно приличный набор навыков, опыт в обслуживании компонентов кубера и приобретут необходимый опыт с менее крутой "кривой развития".

Поэтому не бойтесь кубернетиса в своих инфраструктурах. Пусть лучше он боится вас!

Only registered users can participate in poll. Log in, please.
Чем (пробовали) разворачивали Kubernetes?
7.52% Deckhouse (Флант)10
24.81% Rancher (Suse + Rancher Labs)33
48.87% Kubespray65
3.01% Juju (Canonical)4
9.02% OpenShift (IBM)12
47.37% Managed в облаке63
16.54% Свой вариант написал в комментариях22
133 users voted. 71 users abstained.
Tags:
Hubs:
Total votes 48: ↑47 and ↓1+46
Comments32

Articles