# Hierarchical namespaces

<https://habr.com/ru/companies/vk/articles/717938/>

<https://github.com/kubernetes-sigs/hierarchical-namespaces>

![](/files/9p67DHsDOgDNkdEhyRU5)

Пространства имен — критически важный ресурс для поддержки мультитенантной архитектуры кластера Kubernetes. Но ими трудно управлять при работе с крупномасштабными мультитенантными кластерами. К счастью, процесс можно упростить, добавив в Kubernetes функцию иерархических пространств имен. [Команда VK Cloud](https://mcs.mail.ru/?utm_source=habr\&utm_medium=media\&utm_campaign=hierarchical-namespaces) перевела статью о том, как это сделать.

Это статья для тех, у кого есть общее представление о Kubernetes, кластерах, контейнерах и подах. Также потребуются базовые знания о пространствах имен в Kubernetes.

## Пространства имен Kubernetes 101

Пространства имен — это ресурс Kubernetes, позволяющий изолировать друг от друга ресурсы других типов. Как и в случае с большинством ресурсов Kubernetes, можно создать пространство двумя способами: определить в файле манифеста с помощью декларативного подхода или императивно, в командной строке. Ниже для примера приведен код файла манифеста для создания пространства coolapp. Это декларативный подход:

```
apiVersion: v1
kind: Namespace
metadata:
  name: coolapp

```

Следующий набор команд императивно создает пространство имен с помощью инструмента kubectl CLI:

```
kubectl create namespace coolapp

```

После создания пространства имен инженеры назначают ему другие ресурсы Kubernetes. Пример ниже показывает, как императивно запустить под Kubernetes с контейнером nginx и назначить ему пространство coolapp, отображающееся в результате выполнения команды.

```
# kubectl run ngnix --image nginx -n coolapp pod/ngnix created

```

Чтобы перечислить ресурсы в этом пространстве имен, его нужно декларировать. Вот код получения подов в пространство имен coolapps и результаты его выполнения:

```
# kubectl get pods -n coolapp
NAME    READY   STATUS    RESTARTS   AGE
ngnix   1/1     Running   0          3m5s

```

Если ресурс назначен какому-то пространству имен, то доступ к нему можно получить только через это пространство. Этот код показывает результат получения подов в пространстве имен по умолчанию, у которого в данном случае нет подов:

```
# kubectl get pods
No resources found in default namespace.

```

Почему не удалось найти поды? Потому что созданный ранее под nginx назначен пространству coolapp, а не пространству имен по умолчанию. Под nginx виден только в пространстве coolapp.

## Безопасность как преимущество пространства имен

Если ресурс доступен только в определенном пространстве имен, это повышает его уровень безопасности. В пространствах имен Kubernetes с помощью [контроля доступа на основе ролей](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) (RBAC) можно назначать права доступа пользователям, группам и другим ресурсам. Например, инженер может создать группу coolapp-admins и предоставить ей полный доступ к любым ресурсам в пространстве имен coolapp. Полный доступ означает, что пользователи из группы coolapp-admins могут создавать, перечислять, обновлять, исправлять и удалять ресурсы.

С другой стороны, инженер может создать группу coolapp-devs, у которой есть разрешения только на создание, обновление и удаление подов в пространстве имен coolapp. Права этой группы касаются только подов и определенных действий, которые можно совершать с ними.

При назначении разрешений ресурсам и ролям в пространствах имен поддерживается очень высокая детализация. Такой уровень безопасности оказывается очень кстати при поддержке мультитенантной архитектуры.

## Основы мультитенантной архитектуры Kubernetes

Мультитенантный кластер Kubernetes — это кластер, в котором сосуществуют несколько организаций (см. рис. 1 ниже).

![](/files/CcFqhJ0CX5nl8KeFs1g3)

Kubernetes может работать с несколькими арендаторами в одном кластере

Мультитенантная архитектура экономичнее и проще в управлении по сравнению с выделением отдельных кластеров каждому отделу или организации.

В выделенной архитектуре у каждой организации есть собственный Control Plane и виртуальные машины с рабочими нодами. Это довольно дорогое решение. Кроме того, для каждого кластера понадобится выделенный технический персонал. Все это может привести к высоким избыточным расходам. А если ресурсы не используются в полном объеме, это просто трата денег впустую.

С другой стороны, поскольку в мультитенантной архитектуре все операции сконцентрированы в одном кластере, повышается эффективность использования физических ресурсов и трудозатрат ИТ-специалистов.

## Упрощаем управление мультитенантным пространством имен

В мультитенантном кластере Kubernetes изоляция организаций реализуется именно с помощью пространств имен. Как мы уже писали выше, в отдельно взятом кластере Kubernetes с помощью пространства можно разделить права доступа пользователей, групп и ресурсов. Таким образом, если инженерам нужно выделить ресурсы на тенант в кластере Kubernetes, они назначают тенант одному или нескольким пространствам имен в этом кластере. Разрешения для ресурсов предоставляются в конкретном пространстве (см. рис. 2 ниже).

![](/files/eEWVfsoKZBr72USBACsV)

В мультитенантном кластере тенанты отделяются друг от друга с помощью пространств имен Kubernetes

Для примера представьте мультитенантный кластер с тремя тенантами: компаниями A, B и C. В каждой из этих компаний есть тенанты, которым разрешено использовать условное общее корпоративное приложение Acme-App, которое размещается на одном кластере.

Теперь давайте представим, что в каждой компании есть несколько подразделений, имеющих право использовать разные функции приложения. В нашем примере это будут HR, финансовый отдел и отдел планирования.

Итак, если в кластере Kubernetes нужно завести и изолировать друг от друга три компании, инженеры создают набор пространств имен:

```
acme-app-company-a-hr
acme-app-company-a-finance
acme-app-company-a-scheduling
acme-app-company-b-hr
acme-app-company-b-finance
acme-app-company-b-scheduling
acme-app-company-c-hr
acme-app-company-c-finance
acme-app-company-c-scheduling

```

Для реализации разрешений понадобилось создать девять пространств имен для тенантов. Это вполне подходящая структура, которая, однако, может превратиться в головную боль для техподдержки. Например, если инженерам понадобится изменить разрешение, действующее для всех подразделений одной компании, то им придется вносить изменения как минимум в три пространства имен. А если нужно изменить разрешение для всех компаний, использующих Acme-App, то придется назначать разрешения для всех девяти пространств. Подробности можно узнать [из видео, посвященного этой теме](https://youtu.be/fO3vUMc_WbI).

Очевидно, нужен более рациональный подход. И это как раз иерархические пространства имен. Если они реализованы в кластере Kubernetes, можно создать такую структуру:

```
acme-app
├── company-a
│   ├── company-a-hr
│   ├── company-a-finance
│   └── company-a-scheduling
├── company-b
│   ├── company-b-hr
│   ├── company-b-finance
│   └── company-b-scheduling
├── company-c
│   ├── company-c-hr
│   ├── company-c-finance
│   └── company-c-scheduling

```

Как видите, в иерархических пространствах имен реализуется упрощенная организационная структура. В дополнение к организационной простоте такие пространства позволяют распределять разрешения на подчиненные пространства имен.

Вернемся к дереву acme-app с иллюстрации выше. Если в корневом пространстве имен acme-app изменяется разрешение, такое изменение будет распространяться на все подчиненные пространства в структуре дерева. А если инженерам нужно внести изменение во все подчиненные пространства компании A, им нужно всего лишь изменить разрешения в пространстве имен компании A. Подчиненные пространства имен — company-a-hr, company-a-finance и company-a-scheduling — откорректируются автоматически.

Иерархические пространства не только упрощают работу с тенантами в мультитенантном кластере Kubernetes, они еще и повышают операционную эффективность в плане общей эксплуатации и безопасности. К сожалению, на момент написания этой статьи иерархические пространства имен не поставляются с Kubernetes «из коробки», их нужно установить.

## Добавляем иерархические пространства имен в кластер Kubernetes

Установка иерархических пространств имен в кластер Kubernetes — дело нехитрое. Ниже приведен пример кода, который делает это под Linux. Кроме того, скрипт устанавливает плагин hns для инструмента командной строки kubectl. Плагин и kubectl предназначены для создания и поддержки иерархических пространств имен. Пример взят из [официальной инструкции](https://github.com/kubernetes-sigs/hierarchical-namespaces/releases/), VK Cloud тоже будет работать.

```
kubectl label ns kube-system hnc.x-k8s.io/excluded-namespace=true --overwrite
kubectl label ns kube-public hnc.x-k8s.io/excluded-namespace=true --overwrite
kubectl label ns kube-node-lease hnc.x-k8s.io/excluded-namespace=true --overwrite

```

Это нужно для того, чтобы исключить проблемы с сервисными пространствами.

```
HNC_VERSION=v1.0.0
kubectl apply -f https://github.com/kubernetes-sigs/hierarchical-namespaces/releases/download/${HNC_VERSION}/default.yaml
HNC_VERSION=v1.0.0
HNC_PLATFORM=linux_amd64 # также поддерживаются: darwin_amd64, darwin_arm64, windows_amd64
curl -L https://github.com/kubernetes-sigs/hierarchical-namespaces/releases/download/${HNC_VERSION}/kubectl-hns_${HNC_PLATFORM} -o ./kubectl-hns
chmod +x ./kubectl-hns
kubectl hns

```

### Bash-скрипт для установки иерархических пространств имен в кластере Kubernetes

После выполнения скрипта кластер Kubernetes начнет поддерживать иерархические пространства имен. Теперь можно выполнить еще один код, чтобы создать иерархические пространства имен для приложения acme-app, которое уже фигурировало в нашей статье.

```
#!/bin/bash
# Root namespace

kubectl create namespace acme-app
sleep 2  # Take a rest so the namespace can provision

# Company A namespaces
kubectl hns create company-a -n acme-app
sleep 2  # Take a rest so the namespace can provision
kubectl hns create company-a-hr -n company-a
kubectl hns create company-a-finance -n company-a
kubectl hns create company-a-scheduling -n company-a

# Company B namespaces
kubectl hns create company-b -n acme-app
sleep 2 # Take a rest so the namespace can provision

kubectl hns create company-b-hr -n company-b
kubectl hns create company-b-finance -n company-b
kubectl hns create company-b-scheduling -n company-b

# Company C namespaces
kubectl hns create company-c -n acme-app
sleep 2 # Take a rest so the namespace can provision

kubectl hns create company-c-hr -n company-c
kubectl hns create company-c-finance -n company-c
kubectl hns create company-c-scheduling -n company-c

# Display the hierarchical namespaces tree
kubectl hns tree acme-app

```

### Скрипт для создания набора иерархических пространств имен для мультитенантного приложения acme-app

Так выглядит дерево, созданное в результате выполнения вышеприведенного кода:

```
acme-app
├── [s] company-a
│   ├── [s] company-a-finance
│   ├── [s] company-a-hr
│   └── [s] company-a-scheduling
 ── [s] company-b
│   ├── [s] company-b-finance
│   ├── [s] company-b-hr
│   └── [s] company-b-scheduling
└── [s] company-c
    ├── [s] company-c-finance
    ├── [s] company-c-hr
    └── [s] company-c-scheduling

[s] indicates subnamespaces

```

Иерархия пространств имен, созданная скриптом, отражает иерархию, которую мы представили выше в этой статье.

## Подведем итоги

Иерархические пространства имен дают однозначные преимущества при ведении нескольких тенантов в одном кластере Kubernetes. Благодаря им можно управлять разрешениями в каскадном режиме. Любое изменение разрешений, актуальных для родительского пространства имен, будет применяться и к подчиненным пространствам. Эффективность очевидна.

Как мы уже упоминали, иерархические пространства имен нужно устанавливать для каждого кластера. Они не реализованы в стандартной версии Kubernetes. Вам придется встроить процесс их подготовки в рабочий процесс развертывания, реализуемый у вас в компании. Это потребует некоторых усилий, но оно того стоит. Если в компании поддерживаются мультитенантные кластеры Kubernetes, то имеет смысл сделать иерархические пространства стандартным компонентом архитектуры Kubernetes: в долгосрочной перспективе это сэкономит вам время и деньги.

> Попробуйте
>
> [Kubernetes as a Service на платформе VK Cloud](https://mcs.mail.ru/containers/?utm_source=habr\&utm_medium=media\&utm_campaign=hierarchical-namespaces)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://book.konstantinsecurity.com/readme/architect/kubernetes/isolation/hierarchical-namespaces.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
