Задача
Для экспериментов мне требуется периодически поднимать кластер 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
К стандартным настройкам добавляем:
lxc.apparmor.profile: unconfined lxc.cap.drop: lxc.cgroup.devices.allow: a lxc.mount.auto: proc:rw sys:rw
Параметры контейнера в Proxmox 6
К стандартным настройкам контейнера добавляем:
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
Параметры контейнера в Proxmox 7
После апгрейда до Proxmox 7 в системе cgroups обновился до версии cgroups2. В итоге kubelet нормально стартовал с такими параметрами контейнера:
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
Также в версии 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:
kubectl edit cm -n kube-system kube-proxy
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
Установка Kubernetes Dashboard Web UI:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/master/aio/deploy/recommended/kubernetes-dashboard.yaml
Если мы админим кластер с машины, где есть kubectl и браузер, то для того, чтобы локально пользоваться Kubernetes Dashboard Web UI достаточно запустить:
kubectl proxy &
и консоль будет доступна по адресу: http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/.
Если необходимо иметь доступ консоли не только с локального хоста, на котором исполняется kubectl proxy, то запускаем его так:
kubectl proxy --address='0.0.0.0' --accept-hosts='^*$'
В результате, консоль будет доступна и с других хостов.
Кроме того, для доступа к консоли 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).
Discussion
Thank you! This one REALY HELP ME!