Differences

This shows you the differences between two versions of the page.


Previous revision
proxmox:how_to_start_kubernetes_inside_proxmox_lxc_container [2021/12/18 18:40] (current) – [Proxmox br_netfilter module absent] admin
Line 1: Line 1:
 +====== Задача ======
 +Для экспериментов мне требуется периодически поднимать кластер **kubernetes** (на момент написания - версия 1.16.0). \\
 +Я не хочу использовать виртуальные машины, а хочу использовать контейнеры. В первую очередь из-за некоторых аппаратных ограничений (мой хост довольно слабый - **Pentium J5005** и 24Gb памяти DDR4). \\
 +В качестве инструмента развертывания я использую **ansible**. \\
 +
 +====== Настройки хоста Proxmox 5.x/6 ======
 +
 +Вот тут есть описание профиля контейнера, с которыми все должно работать. Но я пока это не применял.
 +[[https://discuss.linuxcontainers.org/t/not-able-to-run-kubernetes-inside-docker-inside-lxd/4643/3]]
 +
 +===== модули ядра =====
 +В **/etc/modules** добавляем:
 +  overlay
 +  aufs
 +и чтобы не переазгружаться выполняем:
 +  /sbin/lsmod | /bin/grep overlay || /sbin/modprobe overlay
 +  /sbin/lsmod | /bin/grep aufs || /sbin/modprobe aufs
 +
 +====== Параметры контейнеров ======
 +Запустить **master**-node в **unprivileged** контейнере пока не удалось, потому что нужен доступ к настройкам (в частности ядра **memory overcommit**).
 +То есть при создании контейнера мнимаем галку **unprivileged**. \\
 +Объем **swap** - 0.
 +
 +====== Параметры контейнера в Proxmox 5.x ======
 +К стандартным настройкам добавляем:
 +<code>lxc.apparmor.profile: unconfined
 +lxc.cap.drop:
 +lxc.cgroup.devices.allow: a
 +lxc.mount.auto: proc:rw sys:rw</code> 
 +
 +====== Параметры контейнера в Proxmox 6 ======
 +К стандартным настройкам контейнера добавляем:
 +<code>mp0: /boot,mp=/boot
 +mp1: /lib/modules,mp=/lib/modules
 +lxc.hook.autodev: sh -c "mknod -m 0644 ${LXC_ROOTFS_MOUNT}/dev/kmsg c 1 11"
 +lxc.apparmor.profile: unconfined
 +lxc.cap.drop:
 +lxc.cgroup.devices.allow: a
 +lxc.mount.auto: proc:rw sys:rw</code>
 +
 +====== Параметры контейнера в Proxmox 7 ======
 +После апгрейда до **Proxmox 7** в системе **cgroups** обновился до версии **cgroups2**. В итоге **kubelet** нормально стартовал с такими параметрами контейнера:
 +<code>mp0: /boot,mp=/boot
 +mp1: /lib/modules,mp=/lib/modules
 +lxc.apparmor.profile: unconfined
 +lxc.cap.drop:
 +lxc.cgroup2.devices.allow: a
 +lxc.mount.auto: proc:rw sys:rw
 +lxc.mount.entry: /dev/kmsg dev/kmsg none defaults,bind,create=file</code>
 +Также в версии Proxmox 7 используется ядро 5.11 и более новое. В нем запрещено изменения параметров **net_filter** (https://github.com/kubernetes-sigs/kind/issues/2240#issuecomment-838938881). В результате не стартует **kube-proxy**:
 +  server.go:650] Version: v1.20.1
 +  conntrack.go:100] Set sysctl 'net/netfilter/nf_conntrack_max' to 131072
 +  server.go:495] open /proc/sys/net/netfilter/nf_conntrack_max: permission denied
 +Выхода три:
 +  * либо откатиться на **pve-kernel-5.10.6-1-pve**
 +  * обновить **kube-proxy** (в мае 2021 в него смерджили патч, который позволяет не изменять значения, которые уже достаточно хороши для работы **kube-proxy** - https://github.com/kubernetes-sigs/kind/pull/2241)
 +  * в конфиге **kube-proxy** дать параметру **conntrack-max-per-core** значение **0** - тогда **kube-proxy** будет использовать то значение, которое установлено сейчас. Для этого нужно найти и отредактировать значение в **ConfigMap**: <code>kubectl edit cm -n kube-system kube-proxy</code>
 +
 +===== Proxmox br_netfilter module absent =====
 +Недавно, после апгрейда ОС в контейнере - Ubuntu 20.04 -> Ubuntu 21.04 перестали стартовать контейнеры kubelet и все выглядит так, словно отсутствует модуль **br_filter**. https://forum.proxmox.com/threads/missing-br_netfilter-module.53791/ Это прям шоустоппер!! \\
 +Оказалось, что не стоит обновлять систему раньше времени и обязательно перед такими манипуляциями делать бекапы!!! :). \\
 +В итоге - я просто создал новый контейнер, натянул на него чистый кластер k8s, а затем скопировал с ноды старого кластера директории:
 +  /etc/kubernetes
 +  /etc/var/lib/etcd
 +  /etc/var/lib/kubelet
 +В общем-то всё... Кластер реанимировался.
 + 
 +======= Kubernetes CNI =======
 +В качетсве **CNI** можно использовать либо **flannel**:
 +  kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
 +либо **kube-router**:
 +  kubectl apply -f https://raw.githubusercontent.com/cloudnativelabs/kube-router/master/daemonset/kubeadm-kuberouter.yaml
 +====== Kubernetes Dashboard Web UI ======
 +
 +[[https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/#welcome-view|https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/#welcome-view]]\\
 +Установка **Kubernetes Dashboard Web UI**:<code>
 +kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/master/aio/deploy/recommended/kubernetes-dashboard.yaml
 +</code>
 +
 +Если мы админим кластер с машины, где есть **kubectl** и браузер, то для того, чтобы **локально** пользоваться **Kubernetes Dashboard Web UI** достаточно запустить:
 +<code>
 +kubectl proxy &
 +</code>
 +
 +и консоль будет доступна по адресу: [[http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/|http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/]].\\
 +Если необходимо иметь доступ консоли не только с локального хоста, на котором исполняется **kubectl proxy**, то запускаем его так:<code>
 +kubectl proxy --address='0.0.0.0' --accept-hosts='^*$'
 +</code>
 +
 +В результате, консоль будет доступна и с других хостов.\\
 +Кроме того, для доступа к консоли **Kubernetes Dashboard Web UI** без **kubectl proxy** нужно сменить тип **service**'а который предоставляет доступ к pod'у **kubernetes-dashboard**. Вместо установленного по-умолчанию **ClusterIP** нужно сделать **NodePort**:
 +  kubectl -n kube-system patch service kubernetes-dashboard  -p '{"spec":{"type":"NodePort"}}'
 +В результате, **dashboard** будет доступен на IP-адресе master-ноды. \\
 +Это можно сделать и вручную, отредактировав **service**, который предоставляет доступ к pod'у **kubernetes-dashboard**, где в качестве **.spec.type** указать **NodePort**:
 +  kubectl -n kube-system edit service kubernetes-dashboard
 +
 +====== Ошибки ======
 +
 +===== Failed to start cAdvisor inotify_init: too many open files =====
 +Нужно увеличить **inotify/max_user_instances** \\
 +Текущее значение можно посмотреть так:
 +  cat /proc/sys/fs/inotify/max_user_instances
 +Для увеличения лимита добавляем строку
 +  fs.inotify.max_user_instances=999999
 +В файл **/etc/sysctl.conf** и применяем:
 +  sysctl --system
 +Или вот одной строкой:
 +  echo fs.inotify.max_user_instances=99999 | sudo tee -a /etc/sysctl.conf && sudo sysctl --system
 +===== Файловая система контейнера =====
 +При попытке запустить **kubelet** в контейнере, файловая система которого лежит просто в директории хоста, вываливается ошибка:
 +  Failed to start ContainerManager failed to get rootfs info: failed to get device for dir "/var/lib/kubelet": could not find device with major: 0, minor: 49 in cached partitions map
 +Так делать нельзя. Файловая система контейнера должна лежать в каком-то контейнере, который будет смонтирован как **loop**-устройство(например по-умолчанию - в **qcow2**).
 +
 +====== Ссылки ======
 +https://medium.com/@kvaps/run-kubernetes-in-lxc-container-f04aa94b6c9c ([[ https://habr.com/ru/post/420913/|вот тоже самое на русском языке ]])\\
 +https://forum.proxmox.com/threads/docker-in-lxc-container.45204/ \\
 +
 +
 +