Описание
Проекты (ресурс Project) в Deckhouse Virtualization Platform (DVP) обеспечивают изолированные окружения для создания ресурсов пользователя.
Настройки проекта позволяют задать квоты для ресурсов, ограничить сетевое взаимодействие, как внутри платформы, так и вне её.
Для создания проектов используются шаблоны (ресурс ProjectTemplate).
При изменении шаблона проекта, все созданные проекты будут обновлены в соответствии с новым шаблоном.
Шаблоны для проектов доступные по умолчанию
В DVP есть набор шаблонов для создания проектов:
default— шаблон для базовых сценариев использования проектов:- ограничение ресурсов;
- сетевая изоляция;
- автоматические алерты и сбор логов;
- выбор профиля безопасности;
-
настройка администраторов проекта.
Описание шаблона в GitHub.
secure— включает все возможности шаблонаdefault, а также дополнительные функции:- настройка допустимых для проекта UID/GID;
- правила аудита обращения Linux-пользователей проекта к ядру;
- сканирование запускаемых образов контейнеров на наличие известных уязвимостей (CVE).
Описание шаблона в GitHub.
secure-with-dedicated-nodes— включает все возможности шаблонаsecure, а также дополнительные функции:- определение селектора узла для всех ВМ в проекте: если ВМ создана, селектор узла ВМ будет автоматически заменён на селектор узла проекта;
- определение стандартных tolerations для всех ВМ в проекте: если ВМ создана, стандартные значения tolerations добавляются к нему автоматически.
Описание шаблона в GitHub.
Чтобы перечислить все доступные параметры для шаблона проекта, выполните команду:
d8 k get projecttemplates <ИМЯ_ШАБЛОНА_ПРОЕКТА> -o jsonpath='{.spec.parametersSchema.openAPIV3Schema}' | jq
Создание проекта
- Для создания проекта создайте ресурс Project с указанием имени шаблона проекта в поле .spec.projectTemplateName.
-
В параметре .spec.parameters ресурса
Projectукажите значения параметров для секции .spec.parametersSchema.openAPIV3Schema ресурсаProjectTemplate.Пример создания проекта с помощью ресурса Project из
defaultProjectTemplate представлен ниже:apiVersion: deckhouse.io/v1alpha2 kind: Project metadata: name: my-project spec: description: This is an example from the Deckhouse documentation. projectTemplateName: default parameters: resourceQuota: requests: cpu: 5 memory: 5Gi storage: 1Gi limits: cpu: 5 memory: 5Gi networkPolicy: Isolated podSecurityProfile: Restricted extendedMonitoringEnabled: true administrators: - subject: Group name: k8s-admins -
Для проверки статуса проекта выполните команду:
d8 k get projects my-projectУспешно созданный проект должен отображаться в статусе
Deployed(синхронизирован). Если отображается статусError(ошибка), добавьте аргумент-o yamlк команде (например,d8 k get projects my-project -o yaml) для получения более подробной информации о причине ошибки.
Автоматическое создание проекта для пространства имён
Для пространства имён возможно создать новый проект. Для этого пометьте пространство имён аннотацией projects.deckhouse.io/adopt. Например:
-
Создайте новое пространство имён:
d8 k create ns test -
Пометьте его аннотацией:
d8 k annotate ns test projects.deckhouse.io/adopt="" -
Убедитесь, что проект создался:
d8 k get projectsВ списке проектов появится новый проект, соответствующий пространству имён:
NAME STATE PROJECT TEMPLATE DESCRIPTION AGE deckhouse Deployed virtual This is a virtual project 181d default Deployed virtual This is a virtual project 181d test Deployed empty 1m
Шаблон созданного проекта можно изменить на существующий.
Обратите внимание, что при смене шаблона может возникнуть конфликт ресурсов: если в чарте шаблона прописаны ресурсы, которые уже присутствуют в пространстве имён, то применить шаблон не получится.
Создание собственного шаблона для проекта
Шаблоны проектов по умолчанию включают базовые сценарии использования и служат примером возможностей шаблонов.
Для создания своего шаблона:
- Возьмите за основу один из шаблонов по умолчанию, например,
default. -
Скопируйте его в отдельный файл, например,
my-project-template.yamlпри помощи команды:d8 k get projecttemplates default -o yaml > my-project-template.yaml -
Отредактируйте файл
my-project-template.yaml, внесите в него необходимые изменения.Необходимо изменить не только шаблон, но и схему входных параметров под него.
Шаблоны для проектов поддерживают все функции шаблонизации Helm.
- Измените имя шаблона в поле
.metadata.name. -
Примените полученный шаблон командой:
d8 k apply -f my-project-template.yaml -
Проверьте доступность нового шаблона с помощью команды:
d8 k get projecttemplates <ИМЯ_НОВОГО_ШАБЛОНА>
Использование лейблов для управления ресурсами
При создании ресурсов в ProjectTemplate можно использовать специальные лейблы для управления поведением multitenancy-manager при обработке этих ресурсов:
Пропуск создания лейбла heritage: multitenancy-manager
По умолчанию все ресурсы, созданные из ProjectTemplate, получают лейбл heritage: multitenancy-manager.
Он запрещают изменение ресурсов пользователями или любым контроллером, кроме multitenancy-manager.
Если необходимо разрешить изменение ресурса (например, для совместимости с другими системами, или в случае реализации собственного контроля изменения создаваемых объектов), добавьте к ресурсу лейбл projects.deckhouse.io/skip-heritage-label.
Пример:
apiVersion: v1
kind: ConfigMap
metadata:
name: my-config
namespace: {{ .projectName }}
labels:
projects.deckhouse.io/skip-heritage-label: "true"
app: my-app
data:
key: value
В этом случае ресурс получит лейблы projects.deckhouse.io/project и projects.deckhouse.io/project-template, но не получит лейбл heritage: multitenancy-manager.
Исключение ресурсов из управления multitenancy-manager
Если необходимо исключить ресурс из управления multitenancy-manager (например, если он должен управляться вручную или другим контроллером), добавьте к ресурсу лейбл projects.deckhouse.io/unmanaged.
Пример:
apiVersion: v1
kind: Secret
metadata:
name: external-secret
namespace: {{ .projectName }}
labels:
projects.deckhouse.io/unmanaged: "true"
type: Opaque
data:
token: <base64-encoded-value>
Ресурсы с лейблом projects.deckhouse.io/unmanaged:
- Будут созданы только один раз при создании проекта.
- Не будут обновляться при последующих изменениях шаблона или обновлениях.
- Не будут отслеживаться в статусе проекта.
- Получат лейблы
projects.deckhouse.io/projectиprojects.deckhouse.io/project-template, но не получат лейблheritage: multitenancy-manager.
После того как ресурс помечен как unmanaged, он будет создан при первой установке, но не будет обновляться при изменении ProjectTemplate. После создания ресурс становится полностью независимым и должен управляться вручную.
Реализация валидации изменений объектов с помощью пользовательского лейбла
Модуль multitenancy-manager использует ValidatingAdmissionPolicy для защиты ресурсов с лейблом heritage: multitenancy-manager от ручных изменений.
Вы можете реализовать аналогичную валидацию для ресурсов с любым лейблом.
Принцип работы валидации в multitenancy-manager
multitenancy-manager валидирует объекты с лейблом heritage: multitenancy-manager.
Для этого используются следующие ресурсы:
- ValidatingAdmissionPolicy — определяет правила валидации:
- Операции:
UPDATEиDELETE; - Проверка: разрешены только операции от имени service account контроллера;
- Применяется ко всем ресурсам и API группам.
- Операции:
- ValidatingAdmissionPolicyBinding — определяет на какие объекты распространяется валидация:
- Использует
namespaceSelectorиobjectSelectorдля выбора ресурсов по лейблуheritage: multitenancy-manager.
- Использует
Создание собственной валидации
Для реализации валидации для ресурсов с другим лейблом (например, heritage: my-custom-label):
-
Создайте файл с манифестами ресурсов ValidatingAdmissionPolicy и ValidatingAdmissionPolicyBinding:
apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingAdmissionPolicy metadata: name: my-custom-label-validation spec: failurePolicy: Fail matchConstraints: resourceRules: - apiGroups: ["*"] apiVersions: ["*"] operations: ["UPDATE", "DELETE"] resources: ["*"] scope: "*" validations: - expression: 'request.userInfo.username == "system:serviceaccount:my-namespace:my-service-account"' # Замените на ваш сервисный аккаунт. reason: Forbidden messageExpression: 'object.kind == ''Namespace'' ? ''This resource is managed by '' + object.metadata.name + '' system. Manual modification is forbidden.'' : ''This resource is managed by '' + object.metadata.namespace + '' system. Manual modification is forbidden.''' --- apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingAdmissionPolicyBinding metadata: name: my-custom-label-validation spec: policyName: my-custom-label-validation validationActions: [Deny, Audit] matchResources: namespaceSelector: matchLabels: heritage: my-custom-label objectSelector: matchLabels: heritage: my-custom-label -
Настройте параметры валидации:
policyName— уникальное имя политики (должно совпадать сPolicyиBinding);request.userInfo.username— имя сервисного аккаунта, которому разрешено изменять ресурсы (замените на ваш сервисный аккаунт);heritage: my-custom-label— значение лейблаheritageдля ваших ресурсов (замените на ваше значение). Запрещено использование значениеmultitenancy-manager,deckhouse;failurePolicy: Fail— политика при ошибке валидации:Fail— отклонять запрос при ошибке проверки,Ignore— игнорировать ошибки валидации.
validationActions— действия валидации:Deny— отклонять неразрешенные операции,Audit— записывать операции в аудит лог.
-
Примените политику:
d8 k apply -f my-validation-policy.yaml -
Убедитесь, что ваши ресурсы имеют соответствующий лейбл
heritage:apiVersion: v1 kind: ConfigMap metadata: name: my-resource labels: heritage: my-custom-label
Выдача кластерных ресурсов проектам
multitenancy-manager позволяет администраторам кластера управлять тем, какие кластерные ресурсы (например, StorageClass) можно использовать из неймспейсов проектов.
Для этого используются кастомные ресурсы:
- GrantableClusterResourceDefinition (cluster-scoped) — регистрирует кластерный ресурс, который
можно выдавать проектам. Определяет тип ресурса (
grantedResource), где проверяются ссылки на него (usageReferences), базовую доступность (defaultAvailability) и способ определения значения по умолчанию для проекта (defaultFrom). Каждая ссылка отдельно включает подстановку значения по умолчанию черезdefault: true. Указывайте этот параметр только для полей, значение которых всегда должно быть задано (например,storageClassNameуPersistentVolumeClaim). Если отсутствие ссылки имеет смысл (например, для аннотации-переключателя), не указывайтеdefault: true. В этом случае такая ссылка по-прежнему будет проверяться и учитываться в квоте, но её значение не будет подставляться автоматически. - ClusterResourceGrantPolicy (cluster-scoped) — выбирает проекты (по меткам неймспейса через
projectSelector) и для каждого ресурса (resourceName) задаёт разрешённые имена (allowed,allowedSelector) и значение по умолчанию (default). Если задан allow-лист, использовать можно только ресурсы из этого списка. - AvailableClusterResource (namespaced, read-only, короткое имя
available) — формируемый контроллером каталог доступных для проекта кластерных ресурсов. Пользователи проекта могут использовать его, чтобы узнать, какие ресурсы им доступны - ClusterResourceGrant (namespaced) — определяет квоты проекта на кластерные ресурсы (лимиты на количество объектов и на измеряемые величины, например запрошенный объём хранилища). В статусе объекта отображается текущее потребление.
apiVersion: multitenancy.deckhouse.io/v1alpha1
kind: GrantableClusterResourceDefinition
metadata:
name: storageclasses
spec:
grantedResource:
apiVersion: storage.k8s.io/v1
kind: StorageClass
enforcement: Managed
defaultAvailability: All
defaultFrom:
annotationKey: storageclass.kubernetes.io/is-default-class
usageReferences:
- rule:
apiGroups:
- ""
apiVersions:
- v1
resources:
- persistentvolumeclaims
fieldPath: $.spec.storageClassName
default: true
---
apiVersion: multitenancy.deckhouse.io/v1alpha1
kind: ClusterResourceGrantPolicy
metadata:
name: production-storage
spec:
projectSelector:
matchLabels:
environment: production
resources:
- resourceName: storageclasses
default: fast-ssd # Перекрывает дефолт по аннотации.
allowed:
- fast-ssd
- standard
allowedSelector: # Дополнительно разрешает любой StorageClass с меткой shared=true.
matchLabels:
shared: "true"
Особенности применения:
- Проверяющий (validating) вебхук запрещает создание/обновление объектов в подходящих проектах, если используемое значение не разрешено. Уже присутствующие в объекте значения при обновлении не блокируются — существующие объекты продолжают работать.
- Мутирующий (mutating) вебхук подставляет значение по умолчанию только при создании и только в
ссылки, помеченные
default: true. Ссылки без неё (например, аннотации-переключатели) никогда не заполняются. - Grant без совпавших проектов (или проект без совпавших grant’ов) ничего не ограничивает.