В этой статье я расскажу как можно запустить 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 установка должна отработать без проблем.

Комментарии (6)


  1. divanikus
    23.08.2018 15:04

    Меня смутило что оно работает только если полностью убрать все cap_drop, пробовал отключать по одному, нужны именно все иначе никак. Как-то по мне немного теряется изоляция.


    1. past
      23.08.2018 15:26

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


      1. divanikus
        23.08.2018 16:03

        Но теряем по сравнению как если бы запустили что-то в LXC — вот в чем вопрос.


        1. kvaps Автор
          23.08.2018 16:49

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


      1. kvaps Автор
        23.08.2018 16:43

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


        Таких, как 110 подов на ноду, например

        для решиния этой проблемы уже достаточно давно предусмотрен флаг --max-pods для kubelet


        1. past
          23.08.2018 18:23

          Конечно, Вы можете выставить там 65535, но это не даст Вам возможности запустить там 64к подов.