Шаблоны для проектов доступные по умолчанию

В Deckhouse Kubernetes Platform есть набор шаблонов для создания проектов:

  • 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

Создание проекта

  1. Для создания проекта создайте ресурс Project с указанием имени шаблона проекта в поле .spec.projectTemplateName.
  2. В параметре .spec.parameters ресурса Project укажите значения параметров для секции .spec.parametersSchema.openAPIV3Schema ресурса ProjectTemplate.

    Пример создания проекта с помощью ресурса Project из default ProjectTemplate представлен ниже:

    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
    
  3. Для проверки статуса проекта выполните команду:

    d8 k get projects my-project
    

    Успешно созданный проект должен отображаться в статусе Deployed (синхронизирован). Если отображается статус Error (ошибка), добавьте аргумент -o yaml к команде (например, d8 k get projects my-project -o yaml) для получения более подробной информации о причине ошибки.

Автоматическое создание проекта для пространства имён

Для пространства имён возможно создать новый проект. Для этого пометьте пространство имён аннотацией projects.deckhouse.io/adopt. Например:

  1. Создайте новое пространство имён:

    d8 k create ns test
    
  2. Пометьте его аннотацией:

    d8 k annotate ns test projects.deckhouse.io/adopt=""
    
  3. Убедитесь, что проект создался:

    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
    

Шаблон созданного проекта можно изменить на существующий.

Обратите внимание, что при смене шаблона может возникнуть конфликт ресурсов: если в чарте шаблона прописаны ресурсы, которые уже присутствуют в пространстве имён, то применить шаблон не получится.

Создание собственного шаблона для проекта

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

Для создания своего шаблона:

  1. Возьмите за основу один из шаблонов по умолчанию, например, default.
  2. Скопируйте его в отдельный файл, например, my-project-template.yaml при помощи команды:

    d8 k get projecttemplates default -o yaml > my-project-template.yaml
    
  3. Отредактируйте файл my-project-template.yaml, внесите в него необходимые изменения.

    Необходимо изменить не только шаблон, но и схему входных параметров под него.

    Шаблоны для проектов поддерживают все функции шаблонизации Helm.

  4. Измените имя шаблона в поле .metadata.name.
  5. Примените полученный шаблон командой:

    d8 k apply -f my-project-template.yaml
    
  6. Проверьте доступность нового шаблона с помощью команды:

    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

Происходит валидация объектов с лейблом heritage: multitenancy-manager.
Для этого используются следующие ресурсы:

  1. ValidatingAdmissionPolicy — определяет правила валидации:
    • Операции: UPDATE и DELETE;
    • Проверка: разрешены только операции от имени service account контроллера;
    • Применяется ко всем ресурсам и API группам.
  2. ValidatingAdmissionPolicyBinding — определяет на какие объекты распространяется валидация:
    • Использует namespaceSelector и objectSelector для выбора ресурсов по лейблу heritage: multitenancy-manager.

Создание собственной валидации

Для реализации валидации для ресурсов с другим лейблом (например, heritage: my-custom-label):

  1. Создайте файл с манифестами ресурсов 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"' # Замените на ваш 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
    
  2. Настройте параметры валидации:

    • policyName — уникальное имя политики (должно совпадать с Policy и Binding);
    • request.userInfo.username — имя service account, которому разрешено изменять ресурсы (замените на ваш service account);
    • heritage: my-custom-label — значение лейбла heritage для ваших ресурсов (замените на ваше значение). Запрещено использование значение multitenancy-manager, deckhouse;
    • failurePolicy: Fail — политика при ошибке валидации:
      • Fail — отклонять запрос при ошибке проверки,
      • Ignore — игнорировать ошибки валидации.
    • validationActions — действия валидации:
      • Deny — отклонять неразрешенные операции,
      • Audit — записывать операции в аудит лог.
  3. Примените политику:

    d8 k apply -f my-validation-policy.yaml
    
  4. Убедитесь, что ваши ресурсы имеют соответствующий лейбл heritage:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: my-resource
      labels:
        heritage: my-custom-label