Прим. перев.: недавно в блоге Kubernetes был представлен проект «иерархических пространств имён». Формально он существует с конца прошлого года, но именно теперь авторы сочли уместным анонсировать свой Hierarchical Namespace Controller (HNC) для массовой аудитории. О предназначении и деталях реализации — читайте в этом материале, который мы также дополнили переводом дорожной карты HNC.



Безопасно разместить большое число пользователей в одном кластере Kubernetes всегда было непросто. Главная причина в том, что все организации используют Kubernetes по-разному, поэтому единая мультипользовательская модель вряд ли всем подойдет. Вместо этого Kubernetes предлагает компоненты для создания собственного решения, такие как управление доступом на основе ролей (RBAC) и NetworkPolicies; чем лучше эти компоненты, тем легче построить безопасный многопользовательский кластер.

Namespace'ы спешат на помощь


Безусловно, наиболее важными из этих компонентов являются пространства имен. Они выступают основой практически всех политик безопасности и совместного использования control plane в Kubernetes. Например, RBAC, NetworkPolicies и ResourceQuotas по умолчанию поддерживают пространства имен, а объекты вроде Secret, ServiceAccount и Ingress свободно доступны в рамках одного пространства, но полностью изолированы от других.

У namespace'ов есть пара ключевых особенностей, благодаря которым они идеально подходят для применения политик. Во-первых, их можно использовать для представления собственности. Большинство объектов Kubernetes должны входить в какое-либо пространство имен. Используя namespace'ы для представления собственности, вы всегда можете рассчитывать на то, что у этих объектов имеется владелец.

Во-вторых, создавать и использовать пространства имен могут только пользователи с соответствующим правами. Для создания namespace'ов нужны расширенные привилегии, а остальным пользователям требуется явное разрешение на работу с ними — то есть на создание, просмотр или изменение объектов в этих пространствах имен. Таким образом, сначала создается namespace с тщательно продуманным набором политик, и только после этого непривилегированные пользователи имеют возможность создавать «обычные» объекты вроде pod'ов и сервисов.

Ограничения namespace'ов


Увы, на практике пространства имен недостаточно гибки и плохо вписываются в некоторые распространенные сценарии использования. Например, некая команда владеет несколькими микросервисами с разными секретами и квотами. В идеале им следовало бы разнести эти сервисы по отдельным пространствам имен, чтобы изолировать их друг от друга, но тут возникают две проблемы.

Во-первых, у этих namespace'ов отсутствует единая концепция владения, хотя ими обоими владеет одна команда. Это означает, что не только Kubernetes ничего не знает о том, что у этих namespace'ов один владелец, но и отсутствует возможность применять глобальные политики сразу ко всем подконтрольным namespace'ам.

Во-вторых, как известно, автономность — залог эффективной работы команд. Поскольку создание namespace'ов требует расширенных привилегий, маловероятно, что эти привилегии окажутся у кого-либо из команды разработчиков. Другими словами, всякий раз, когда команда решает создать новое пространство имен, ей приходится обращаться к администратору кластера. Это может быть вполне приемлемо для небольшой компании, однако по мере роста все сильнее проявляется негативный эффект от подобной организации.

Представляем иерархические пространства имен


Иерархические namespace'ы — новая концепция, разработанная рабочей группой Kubernetes по multi-tenancy (wg-multitenancy), чтобы решить эти проблемы. В упрощенном виде иерархический namespace представляет собой обычное пространство имен Kubernetes со включением небольшого custom-ресурса, который указывает на одно (необязательное) родительское пространство имен. Тем самым концепция владения расширяется на сами пространства имен, а не только на объекты внутри их.

Концепция владения также реализует два дополнительных типа отношений:

  • Наследование политик: если один namespace является потомком другого, объекты, имеющие отношение к политике, такие как RoleBindings в RBAC, копируются из родительского пространства в дочернее.

  • Делегированное создание: обычно для создания namespace'а требуются привилегии на уровне кластера. Иерархические пространства имен предлагают альтернативу: subnamespaces, для работы с которыми достаточно ограниченных прав из родительского пространства.

Тем самым решаются обе проблемы типичной dev-команды. Администратор кластера может создать для нее одно «корневое» пространство вместе с необходимыми политиками и делегировать полномочия на создание подпространств участникам команды. Таким образом, разработчики смогут создавать подпространства имен для собственного использования, не нарушая политик, установленных администраторами кластера.

Немного практики


Иерархические namespace'ы реализованы с помощью расширения Kubernetes под названием Hierarchical Namespace Controller или HNC. HNC состоит из двух компонентов:

  • Manager работает в кластере, управляет подпространствами имен, распространяет policy-объекты, гарантирует допустимость выстроенных иерархий и управляет точками расширения.

  • Плагин kubectl под названием kubectl-hns позволяет пользователям взаимодействовать с manager'ом.

Руководство по установке компонентов можно найти на странице releases в репозитории проекта.

Давайте посмотрим на работу HNC. Предположим, у меня нет привилегий на создание namespace'ов, но я могут просматривать пространство имен team-a и создавать subnamespace'ы в нем*. Плагин позволяет мне ввести следующую команду:

$ kubectl hns create svc1-team-a -n team-a

* Технически говоря, вы создаете небольшой объект под названием «subnamespace anchor» («подпространственный якорь») в родительском пространстве и затем HNC создает subnamespace.

В результате будет создано пространство имен svc1-team-a. Обратите внимание, что subnamespace'ы ничем не отличаются от обычных пространств имен Kubernetes, поэтому их названия должны быть уникальными.

Просмотреть получившуюся структуру можно с помощью команды tree:

$ kubectl hns tree team-a
# Output:
team-a
└── svc1-team-a

Если в родительском пространстве имеются какие-либо политики, они будут скопированы и в дочернее*. Предположим, например, что в team-a есть RBAC RoleBinding под названием sres. Этот RoleBinding также появится и в соответствующем подпространстве имен:

$ kubectl describe rolebinding sres -n svc1-team-a
# Output:
Name:         sres
Labels:       hnc.x-k8s.io/inheritedFrom=team-a  # inserted by HNC
Annotations:  <none>
Role:
  Kind:  ClusterRole
  Name:  admin
Subjects: …

* По умолчанию распространяются только Roles и RoleBindings в RBAC, но можно настроить HNC на распространение любого объекта Kubernetes.

Наконец, HNC добавляет к этим пространствам имен метки с полезной информацией об иерархии. Их можно использовать для применения других политик. Например, можно создать следующую NetworkPolicy:

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: allow-team-a
  namespace: team-a
spec:
  ingress:
  - from:
    - namespaceSelector:
        matchExpressions:
          - key: 'team-a.tree.hnc.x-k8s.io/depth' # Label created by HNC
            operator: Exists

Эта политика будет распространена на потомков team-a, а также разрешит ingress-трафик между всеми этими пространствами имен. Только HNC может присваивать метку «tree». Она гарантированно отражает текущую иерархию.

Подробности о функционале HNC можно получить в руководстве пользователя.

Дальнейшие шаги и участие в процессе


Если вы считаете, что иерархические namespace'ы пригодятся в вашей организации, версия HNC v0.5.1 доступна на GitHub (с 28 августа доступен релиз v0.5.2 — прим. перев.). Мы бы хотели узнать, что вы думаете о ней, какие проблемы решаете с ее помощью и какие функции хотели бы в нее добавить. Как и в случае с любым ПО на начальных этапах разработки, необходимо соблюдать осторожность при использовании HNC в production. При этом чем больше обратной связи мы получим, тем быстрее сможем прийти к HNC 1.0.

Мы также приветствуем вклад сторонних contributor'ов, будь то исправление ошибок/информация о них или помощь в создании прототипов новых функций, таких как исключения, улучшенный мониторинг, иерархическое квотирование ресурсов или оптимизация конфигурации.

Связаться с нами можно в репозитории, рассылке или в Slack. С нетерпением ждем ваших комментариев!

Автор оригинального анонса — Adrian Ludwin, инженер-программист и технический руководитель Hierarchical Namespace Controller.

Бонус! Дорожная карта и issues


Пожалуйста, создавайте issues — чем больше, тем веселее! Баги будут анализироваться в первую очередь, а для feature request'ов будет определяться приоритет, после чего их включат в план работ или в бэклог.

HNC пока еще не получил статус GA, поэтому будьте осторожны при его использовании в кластерах с конфигурационными объектами, которые не можете позволить себе потерять (например, с теми, которые не хранятся в репозитории Git).

Все issues HNC включаются в соответствующий план работ. На данный момент реализованы или намечены следующие основные этапы этого плана:

  • v1.0: конец I — начало II квартала 2021-го; HNC рекомендован для production.
  • v0.8: начало 2021-го; могут появиться новые критически важные функции.
  • v0.7: конец 2020-го; скорее всего, появится v1beta1 API.
  • v0.6: запланирована на октябрь 2020-го; реализация v1alpha2 API и полностью автоматизированное сквозное тестирование.
  • v0.5: вышла в июле 2020-го; упрощение функционала, улучшение тестирования и повышение стабильности.
  • v0.4: вышла в июне 2020-го; стабилизация API и добавление production-функционала.
  • v0.3: вышла в апреле 2020-го; конфигурирование типов и улучшение UX в области работы с subnamespace'ами.
  • v0.2: вышла в декабре 2019-го; содержит достаточный функционал для применения в средах категории non-production.
  • v0.1: вышла в ноябре 2019-го; первый релиз со всем необходимым функционалом. Его можно попробовать, но он не походит для каких-либо реальных рабочих нагрузок.
  • Бэклог: все внеплановые работы.

P.S. от переводчика


Читайте также в нашем блоге:

Комментарии (0)