Rootless kubernetes

Материал из ALT Linux Wiki

Rootless Kubernetes

Описание

Запуск Kubernetes в режиме rootless обеспечивает запуск Podов без системных root-привелегий в рамках user namespace системного пользователя u7s-admin. Работа в этом режиме практически не требует никаких модификаций, но обеспечивает повышенные уровень защищенности kubernetes, так как клиентские приложения даже при использовании уязвимостей не могут получить права пользователя root и нарушить работу узла.

Запуск kubernetes версии 1.26.3 и старше в режиме rootless обеспечивает пакет podsec-k8s версии 1.0.5 или выше.

Выбор регистратора образов

Пакет обеспечивает загрузку kubernet-образов с регистраторов различного уровня. Уровень регистратора определяется переменной среды U7S_REGISTRY. Переменная может принимать следующие основные значения:

  • Локальный регистратор: C локального регистраторе, как правило, устанавливается подписанные образы с ограничением политики доступа для различных категория пользователей, устанавливаемые скриптами пакета podsec. Это образы загружаются с регистратора registry.local пользователем группы podsec_dev, подписываются и загружаются в локальный регистратор registry.local. Подробности по установке rootless kubernetes в этом режиме описаны в документе Установка и настройка U7S (rootless kuber).
    • registry.local/k8s-c10f1 - образы для сертфицированного дистрибутива c10;
    • registry.local/k8s-p10 - образы для несертфицированного дистрибутива p10.
  • Регистратор altlinux: С регистратора altlinux устанавливаются образы для которых не требуются ограничения политики доступа для различных категория пользователей:
    • registry.altlinux.org/k8s-c10f1 - образы для сертфицированного дистрибутива c10;
    • registry.altlinux.org/k8s-p10 - образы для несертфицированного дистрибутива p10.
  • Native kubernetes регистратор: Если переменная U7S_REGISTRY установлена в пустое значение (U7S_REGISTRY=) образы загружаются со стандартного регистратора образов kubernetes.

Если переменная 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.

Запуск kubernetes в режиме rootless

Для запуска 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:...

Проверка работы узла

Для перевода узла в состояние Ready, запуска coredns Pod’ов запустите flannel.

Запуск сетевого маршрутизатора для контейенеров kube-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-узле выполните команду:

# 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.

  1. Зайдите на master-узел и проверьте подключение worker-узла:
# kubectl get nodes -o wide
NAME       STATUS   ROLES           AGE     VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                 KERNEL-VERSION         CONTAINER-RUNTIME
host-212   Ready    control-plane   7h54m   v1.26.3   10.96.0.1     <none>        ALT SP Server 11100-01   5.15.105-un-def-alt1   cri-o://1.26.2
host-226   Ready    <none>          8m30s   v1.26.3   10.96.0.1     <none>        ALT SP Server 11100-01   5.15.105-un-def-alt1   cri-o://1.26.2