Rootless kubernetes
Общее описание
Запуск Kubernetes
в режиме rootless
обеспечивает запуск Pod
ов без системных root
-привелегий в рамках user namespace
системного пользователя u7s-admin
. Работа в этом режиме практически не требует никаких модификаций, но обеспечивает повышенные уровень защищенности kubernetes
, так как клиентские приложения даже при использовании уязвимостей не могут получить права пользователя root
и нарушить работу узла.
Запуск kubernetes
версии 1.26.3
и старше в режиме rootless
обеспечивает пакет podsec-k8s
версии 1.0.5
или выше.
podsec-k8s - Быстрый старт
Установка master-узла
Инициализация master-узла
Для запуска kubernetes
в режиме rootless
установите пакет podsec-k8s
версии 1.0.5
или выше.
apt-get install podsec-k8s
Измените переменную PATH:
export PATH=/usr/libexec/podsec/u7s/bin/:$PATH
В каталоге /usr/libexec/podsec/u7s/bin/
находятся программы, обеспечивающие работы kubernetes
в rootless
-режиме.
Для разворачивания master-узла
запустите команду:
kubeadm init
По умолчанию уровень отладки устанавливается в
0
. Если необходимо увеличить уровень отладки укажите перед подкомандойinit
флаг-v n
. Гдеn
принимает значения от0
до9
-ти.
После:
- генерации сертификатов в каталоге
/etc/kuarnetes/pki
, - загрузки образов,
- генерации conf-файлов в каталоге
/etc/kubernetes/manifests/
,/etc/kubernetes/manifests/etcd/
- запуска сервиса
kubelet
иPod
’ов системныхkubernetes-образов
инициализируется kubernet-кластер
из одного узла.
По окончании скрипт выводит строки подключения master
(Control Plane
) и worker-узлов
:
You can now join any number of control-plane nodes by copying certificate authorities and service account keys on each node and then running the following as root: kubeadm join xxx.xxx.xxx.xxx:6443 --token ... --discovery-token-ca-cert-hash sha256:.. --control-plane Then you can join any number of worker nodes by running the following on each as root: kubeadm join xxx.xxx.xxx.xxx:6443 --token ... --discovery-token-ca-cert-hash sha256:...
Запуск сетевого маршрутизатора для контейенеров kube-flannel
Для перевода узла в состояние Ready
, запуска coredns
Pod
’ов запустите flannel
.
На master-узле
под пользоваталем root
выполните команду:
# kubectl apply -f /etc/kubernetes/manifests/kube-flannel.yml Connected to the local host. Press ^] three times within 1s to exit session. [INFO] Entering RootlessKit namespaces: OK namespace/kube-flannel created clusterrole.rbac.authorization.k8s.io/flannel created clusterrolebinding.rbac.authorization.k8s.io/flannel created serviceaccount/flannel created configmap/kube-flannel-cfg created daemonset.apps/kube-flannel-ds created Connection to the local host terminated.
После завершения скрипта в течении минуты настраиваются сервисы мастер-узла кластера. По ее истечении проверьте работу usernetes
(rootless kuber
)
Проверка работы master-узла
На master-узле
выполните команду:
# kubectl get daemonsets.apps -A NAMESPACE NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE kube-flannel kube-flannel-ds 1 1 1 1 1 <none> 102s kube-system kube-proxy 1 1 1 1 1 kubernetes.io/os=linux 8h
Число READY
каждого daemonset
должно быть равно числу DESIRED
и должно быть равно числу узлов кластера.
# kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME <host> Ready control-plane 16m v1.26.3 10.96.0.1 <none> ALT SP Server 11100-01 5.15.105-un-def-alt1 cri-o://1.26.2
Проверьте работу usernetes
(rootless kuber
)
# kubectl get all -A NAMESPACE NAME READY STATUS RESTARTS AGE kube-system pod/coredns-c7df5cd6c-5pkkm 1/1 Running 0 19m kube-system pod/coredns-c7df5cd6c-cm6vf 1/1 Running 0 19m kube-system pod/etcd-host-212 1/1 Running 0 19m kube-system pod/kube-apiserver-host-212 1/1 Running 0 19m kube-system pod/kube-controller-manager-host-212 1/1 Running 0 19m kube-system pod/kube-proxy-lqf9c 1/1 Running 0 19m kube-system pod/kube-scheduler-host-212 1/1 Running 0 19m NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE default service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 19m kube-system service/kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 19m NAMESPACE NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE kube-system daemonset.apps/kube-proxy 1 1 1 1 1 kubernetes.io/os=linux 19m NAMESPACE NAME READY UP-TO-DATE AVAILABLE AGE kube-system deployment.apps/coredns 2/2 2 2 19m NAMESPACE NAME DESIRED CURRENT READY AGE kube-system replicaset.apps/coredns-c7df5cd6c 2 2 2 19m
Состояние всех Pod
’ов должны быть в 1/1
.
Проверьте состояние дерева процессов:
# pstree ... ├─systemd─┬─(sd-pam) │ ├─dbus-daemon │ ├─nsenter.sh───nsenter───_kubelet.sh───kubelet───11*[{kubelet}] │ └─rootlesskit.sh───rootlesskit─┬─exe─┬─conmon───kube-controller───7*[{kube-controller}] │ │ ├─conmon───kube-apiserver───8*[{kube-apiserver}] │ │ ├─conmon───kube-scheduler───7*[{kube-scheduler}] │ │ ├─conmon───etcd───8*[{etcd}] │ │ ├─conmon───kube-proxy───4*[{kube-proxy}] │ │ ├─2*[conmon───coredns───8*[{coredns}]] │ │ ├─rootlesskit.sh───crio───10*[{crio}] │ │ └─7*[{exe}] │ ├─slirp4netns │ └─8*[{rootlesskit}] ...
Процесс kubelet
запускается как сервис в user namespace
процесса rootlesskit
.
Все остальные процессы kube-controller
, kube-apiserver
, kube-scheduler
, kube-proxy
, etcd
, coredns
запускаются как контейнеры от соответствующих образов в user namespace
процесса rootlesskit
.
Обеспечение запуска обычных POD’ов на мастер-узле
По умолчанию на master-узле пользовательские Pod
ы не запускаются. Чтобы снять это ограничение наберите команду:
# kubectl taint nodes <host> node-role.kubernetes.io/control-plane:NoSchedule- node/<host> untainted
Инициализация и подключение worker-узла
Установите пакет podsec-k8s
:
apt-get install podsec-k8s
Подключение worker-узлов
Скопируйте команду подключения worker-узла
, полученную на этапе установки начального master-узла
. Запустите ее:
kubeadm join xxx.xxx.xxx.xxx:6443 --token ... --discovery-token-ca-cert-hash sha256:...
По умолчанию уровень отладки устанавливается в
0
. Если необходимо увеличить уровень отладки укажите перед подкомандойjoin
флаг-v n
. Гдеn
принимает значения от0
до9
-ти.
По окончании скрипт выводит текст:
This node has joined the cluster: * Certificate signing request was sent to apiserver and a response was received. * The Kubelet was informed of the new secure connection details. Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
Проверка состояния процессов
Проверьте состояние дерева процессов:
# pstree ... ├─systemd─┬─(sd-pam) │ ├─dbus-daemon │ ├─nsenter.sh───nsenter───_kubelet.sh───kubelet───10*[{kubelet}] │ └─rootlesskit.sh───rootlesskit─┬─exe─┬─conmon───kube-proxy───4*[{kube-proxy}] │ │ ├─rootlesskit.sh───crio───9*[{crio}] │ │ └─6*[{exe}] │ ├─slirp4netns │ └─8*[{rootlesskit}] ...
Процесс kubelet
запускается как сервис в user namespace
процесса rootlesskit
.
Все остальные процессы kube-proxy
, kube-flannel
запускаются как контейнеры от соответствующих образов в user namespace
процесса rootlesskit
.
Проверка готовности master и worker узлов kubernets
Зайдите на master-узел
и проверьте подключение worker-узла
:
# kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME <host1> Ready control-plane 7h54m v1.26.3 10.96.0.1 <none> ALT cri-o://1.26.2 <host2> Ready <none> 8m30s v1.26.3 10.96.0.1 <none> ALT cri-o://1.26.2 ...
Инициализация и подключение дополнительных master-узлов
Установите пакет podsec-k8s
:
apt-get install podsec-k8s
Подключение master-узлов
Скопируйте команду подключения master-узла
, полученную на этапе установки начального master-узла
.
Она отличается от команды подключения worker
-узлов наличием дополнительных параметров
--control-plane
, --certificate-key
.
Запустите ее:
kubeadm join xxx.xxx.xxx.xxx:6443 --token ... --discovery-token-ca-cert-hash sha256:... --control-plane --certificate-key ...
По умолчанию уровень отладки устанавливается в
0
. Если необходимо увеличить уровень отладки укажите перед подкомандойjoin
флаг-v n
. Гдеn
принимает значения от0
до9
-ти.
По окончании скрипт выводит текст:
This node has joined the cluster and a new control plane instance was created: * Certificate signing request was sent to apiserver and approval was received. * The Kubelet was informed of the new secure connection details. * Control plane label and taint were applied to the new node. * The Kubernetes control plane instances scaled up. * A new etcd member was added to the local/stacked etcd cluster.
Проверка состояния процессов
Проверьте состояние дерева процессов:
# pstree ... ├─systemd─┬─(sd-pam) │ ├─dbus-daemon │ ├─kubelet.sh───nsenter_u7s───nsenter───_kubelet.sh───kubelet───11*[{kubelet}] │ └─rootlesskit.sh───rootlesskit─┬─exe─┬─conmon───kube-controller───4*[{kube-controller}] │ │ ├─conmon───kube-scheduler───8*[{kube-scheduler}] │ │ ├─conmon───etcd───9*[{etcd}] │ │ ├─conmon───kube-proxy───4*[{kube-proxy}] │ │ ├─conmon───kube-apiserver───8*[{kube-apiserver}] │ │ ├─rootlesskit.sh───crio───8*[{crio}] │ │ └─7*[{exe}] │ ├─slirp4netns │ └─8*[{rootlesskit}]
Дерево процессов должно совпадать с деревом процессов основного master-узла
.
Проверка готовности master и worker узлов kubernets
На одном из master-узлов наберите команду:
# kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME <host1> Ready control-plane 7h54m v1.26.3 10.96.0.1 <none> ALT cri-o://1.26.2 <host2> Ready <none> 8m30s v1.26.3 10.96.0.1 <none> ALT cri-o://1.26.2 ... <hostN> Ready control-plane 55m v1.26.3 10.96.122.<N> <none> ALT cri-o://1.26.2 ...
Использование REST-интерефейсов подключенных master-узлов
По умолчанию на подключенных master-узлах
в файле /etc/kubernetes/admin.conf
указан адрес API-интерфейса
основного master-узла
:
apiVersion: v1 clusters: - cluster: ... server: https://<master1>:6443 ...
Для балансировки нагрузки в файлах конфигурации ~user/.kube/config
есть смысл указать адреса API-интерфейсов
дополнительгных master-узла
:
apiVersion: v1 clusters: - cluster: ... server: https://<masterN>:6443 ...
Разворачивание rootless kubernetes кластера с балансировщиком REST-запросов haproxy
При подключении дополнительного control-plane
(master
)-узла необходимо
- установить и настроить на один из улов в кластере или вне его
haproxy
для балансировки запросов; - переустановить начальный
master-узел
для работы сhaproxy
- подключать дополнительные
control-plane
(master
)-узлы с указанием их в балансировщике запросовhaproxy
; - подключать дополнительные
worker
-узлы
Настройка балансировщика REST-запросов haproxy
Полная настройка отказоустойчивого кластера haproxy
из 3-х узлов описана в документе ALT Container OS подветка K8S. Создание HA кластера.
Здесь же мы рассмотрим создание и настройка с одним сервером haproxy
с балансировкой запросов на master
-узлы.
Установите пакет haproxy
:
# apt-get install haproxy
Отредактируйте конфигурационный файл /etc/haproxy/haproxy.cfg
:
- добавьте в него описание
frontend
’amain
, принимающего запросы по порту8443
:frontend main bind *:8443 mode tcp option tcplog default_backend apiserver
- добавьте описание
backend
’аapiserver
:backend apiserver option httpchk GET /healthz http-check expect status 200 mode tcp option ssl-hello-chk balance roundrobin server master01 <IP_или_DNS_начального_мастер_узла>:6443 check
- запустите
haproxy
:
# systemctl enable haproxy # systemctl start haproxy
Настройка отказоустойчивого кластера серверов haproxy, keepalived
Особенности разворачивания приложений kubernetes
При использовании сервисов типа NodePort
поднятые в рамках кластера порты в диапазоне 30000-32767
остаются в namespace
пользователя u7s-admin
. Для их проброса наружу необходимо в пользователе u7s-admin
запустить команду:
$ nsenter_u7s rootlessctl add-ports 0.0.0.0:<port>:<port>/tcp
Сервисы типа NodePort
из за их небольшого диапазона и "нестабильности" портов при переносе решения в другой кластер довольно редко используются. Рекомендуется вместо них использовать сервисы типа ClusterIP
c доступом к ним через Ingress
-контроллеры.
Установка и настройка ingress-контролера
Выбор регистратора образов
Пакет обеспечивает загрузку kubernet-образов
с регистраторов различного уровня. Уровень регистратора определяется переменной среды U7S_REGISTRY
. Переменная может принимать нижеописанные основные значения.
Native kubernetes регистратор
export U7S_REGISTRY=
Если переменная U7S_REGISTRY
установлена в пустое значение образы загружаются со стандартного регистратора образов kubernetes
.
Регистратор altlinux
С регистратора altlinux
устанавливаются образы для которых не требуются ограничения политики доступа для различных категория пользователей:
export U7S_REGISTRY=registry.altlinux.org/k8s-c10f1
- образы для сертфицированного дистрибутива c10
;
export U7S_REGISTRY=registry.altlinux.org/k8s-p10
- образы для несертфицированного дистрибутива p10
.
podsec - Локальный регистратор
C локального регистраторе, как правило, устанавливается подписанные образы с ограничением политики доступа для различных категория пользователей, устанавливаемые скриптами пакета podsec
. Это образы загружаются с регистратора registry.local
пользователем группы podsec_dev
, подписываются и загружаются в локальный регистратор registry.local
. Подробности по установке rootless kubernetes
в этом режиме описаны в документе Установка и настройка U7S (rootless kuber).
export U7S_REGISTRY=registry.local/k8s-c10f1
- образы для сертфицированного дистрибутива c10
;
export U7S_REGISTRY=registry.local/k8s-p10
- образы для несертфицированного дистрибутива p10
.
Настройка политики доступа к образам различным категориям пользователей
Поддержка электронной подписи образов
Автоматический выбор регистратора образов
Если переменная U7S_REGISTRY
не установлена, ее значения вычисляется автоматически по следующему алгоритму:
- Если файл
/etc/hosts
содержит описание хоста registry.local
префикс переменной U7S_REGISTRY
принимает значение registry.local/
, иначе registry.altlinux.org/
.
- Если переменная
CPE_NAME
файла /etc/os-release
содержит значение spserver
суффикс переменной U7S_REGISTRY
принимает значение k8s-c10f1
, иначе k8s-p10
.
podsec-k8s-rbac - Поддержка управление доступом на основе ролей (RBAC)
podsec-inotify - Мониторинг безопасности системы