В этой статье я расскажу как можно запустить kubernetes master внутри LXC-контейнера.
Этод метод работает вполне неплохо с Proxmox и может быть рассмотрен как альтернатива классическому развертыванию kubernetes с несколькими мастерами.
Почему proxmox?
Потому что proxmox из коробки предоставляет множество полезных функций.
Proxmox включет в себя функции обеспечения высокой доступности, миграцию, автоматические бекапы, контроль доступа и все это доступно через простой графический интерфейс.
Вы также можете развернуть простейшую конфигурацию kubernetes с одним мастером, высокая доступность будет обеспечена самим proxmox.
Этот способ отлично подойдет для развертывания тестовых или небольших кластеров.
Для более масштабных развертываний, рекомендуется вынести etcd в отдельные контейнеры которые будут использовать быстрые локальные диски и объединить их в кластер.
Тем не менее сам kubernetes-master может по прежнему оставаться обычным ha-контейнером, ему не обязательно иметь быстрое хранилище.
В дополнение, если вы читаете эту статью, я предполагаю что в большинстве случаев вы уже имеете какую-то инфраструктуру на Proxmox, и возможно вы хотите иметь единый интерфейс для управления вашими сервисами.
Почему LXC?
Kubernetes без проблем запустится внутри обычной виртуальной машины. Но LXC-контейнеры предоставляют ту гибкость которая не доступна при использовании обычных виртуальных машин.
По сути LXC-контейнеры не предоставляют полной изоляции контейнеров от хоста, наоборот все процессы внутри контейнеров запускаются как обычные хостовые процессы, просто в отдельном для них неймспейсе.
Этот метод дает вам хорошую производительность но накладывает некоторые ограничения в нашем случае.
Об этих ограничениях и как справиться с ними я и расскажу в этой статье.
Конфигурация
Так как по умолчанию контейнерам не разрешено самостоятельно загружать модули ядра, вы должны настроить их загрузку непосредственно на гипервизорах.
Мы будем использовать overlay
драйвер для docker, так что это все что нам нужно:
echo overlay >> /etc/modules
Теперь нам нужно добавить больше привилегий для нашего контейнера, что бы разрешить ему запускать другие контейнеры внутри, добавьте эти строки в конфиг вашего контейнера:
lxc.apparmor.profile: unconfined
lxc.cap.drop:
lxc.cgroup.devices.allow: a
lxc.mount.auto: proc:rw sys:rw
Начиная с версии v11.0 kubelet требует shared mode для всех mounts с хоста.
Этот грязный хак позволит вам достичь этого, внутри LXC-контейнера запустите:
echo '#!/bin/sh -e
mount --make-rshared /' > /etc/rc.local
Это действие добавит команду mount --make-rshared /
в /etc/rc.local
и будет запускать ее каждый раз при загрузке контейнера.
Также если вы планируете использовать HA-manager в proxmox, знайте что на данный момент есть неприятный bug#1842, который принудительно убивает процессы контейнера во время миграции, что может породить зомби-процессы или даже заблокировать ваше хранилище.
Это не есть хорошо, к счастью есть простое решение:
sed -i 's/forceStop => 1/forceStop => 0/' /usr/share/perl5/PVE/HA/Resources/PVECT.pm
В дополнение можно добавить следующие опции для вашего docker:
--storage-driver overlay2
--iptables=false
--ip-masq=false
Скопируйте docker.service
из /lib
в /etc
для переопределения его параметров:
cp /{lib,etc}/systemd/system/docker.service
Теперь добавьте эти опции в ExecStart
секцию.
На этом все, после этих шагов стандартная kubeadm установка должна отработать без проблем.
divanikus
Меня смутило что оно работает только если полностью убрать все cap_drop, пробовал отключать по одному, нужны именно все иначе никак. Как-то по мне немного теряется изоляция.
past
В данном случае мы просто режем помельче хост proxmox и за счет этого получаем возможность запустить множество нод кубернетеса для преодоления ограничений архитектуры. Таких, как 110 подов на ноду, например. Выключая капабилити, мы не теряем в безопасности по сравнению как если бы просто запустили ноду на железе.
divanikus
Но теряем по сравнению как если бы запустили что-то в LXC — вот в чем вопрос.
kvaps Автор
Все верно. В данном случае LXC используется просто как запускалка контейнера, изоляция здесь отсутствует.
kvaps Автор
Если честно, я бы не стал использовать данный способ для запуска обычных нод с рабочей нагрузкой, если для контроллеров и etcd это еще имеет смысл: ha, бэкапы и простота развертывания. То для обычных нод я почти не вижу в этом смысла.
для решиния этой проблемы уже достаточно давно предусмотрен флаг
--max-pods
для kubeletpast
Конечно, Вы можете выставить там 65535, но это не даст Вам возможности запустить там 64к подов.