Как стать автором
Обновить
703.58
OTUS
Цифровые навыки от ведущих экспертов

Собственные CRD в Kubernetes

Время на прочтение4 мин
Количество просмотров4K

Привет, Хабр! 🚀

Custom Resource Definition в Kubernetes - это хороший инструмент, который позволяет расширять API Kubernetes, добавляя собственные, пользовательские ресурсы. Эти определения не просто новые названия для существующих концепций; они создают новые типы ресурсов, которые Kubernetes будет распознавать и обрабатывать так же, как и встроенные ресурсы, такие как Pods, Deployments и Services.

CRD функционируют путем определения новых типов ресурсов. Сначала создается описание ресурса, которое говорит Kubernetes, какие поля будут доступны и как они должны быть обработаны. Как только CRD определен и добавлен в кластер Kubernetes, он становится доступен через API Kubernetes, позволяя создавать, обновлять и удалять объекты с использованием этого нового определения.

CRD позволяют индивидуально адаптировать Kubernetes под конкретные нужды вашего приложения или организации, добавляя новые типы ресурсов. А так же можно определить собственные контроллеры, которые реагируют на изменения в этих пользовательских ресурсах, позволяя автоматизировать и настраивать поведение кластера.

Cоздание CRD

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

apiVersion: определяет версию API Kubernetes, которая используется для CRD. Обычно это apiextensions.k8s.io/v1.

kind: для CRD это всегда CustomResourceDefinition.

metadata: содержит метаданные о CRD, включая уникальное имя.

spec: основная часть определения CRD, где указывается конфигурация, включая группу, версию и область (Namespaced или Cluster).

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: myresources.example.com
spec:
  group: example.com
  versions:
    - name: v1
      served: true
      storage: true
  scope: Namespaced
  names:
    plural: myresources
    singular: myresource
    kind: MyResource

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

Схема:

spec:
  versions:
    - name: v1
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                configField:
                  type: string
                numberField:
                  type: integer
                  minimum: 1
                enumField:
                  type: string
                  enum: ["Option1", "Option2", "Option3"]

После создания файла CRD его необходимо зарегистрировать в кластере Kubernetes. Это делается с помощью команды kubectl apply.

kubectl apply -f my-crd.yaml

После регистрации CRD, можно создать экземпляры пользовательского ресурса, используя определение CRD:

apiVersion: example.com/v1
kind: MyResource
metadata:
  name: example-myresource
spec:
  configField: значение
kubectl apply -f my-resource.yaml

Управление и валидация

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

spec:
  versions:
    - name: v1
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                configField:
                  type: string
                  pattern: '^[a-zA-Z0-9]+$'

Задаем поле configField как строку, которая должна соответствовать определенному шаблону (в данном случае - только буквы и цифры).

Правила доступа к CRD и связанным с ним ресурсам управляются с помощью Role-Based Access Control:

# role для доступа к CRD
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: crd-manager
rules:
- apiGroups: ["example.com"]
  resources: ["myresources"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

# RoleBinding для связывания role с пользователем
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: crd-manager-binding
  namespace: default
subjects:
- kind: User
  name: "user@example.com"
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: crd-manager
  apiGroup: rbac.authorization.k8s.io

default в openAPIV3Schema позволяет задать значения по умолчанию для полей CRD:

spec:
  versions:
    - name: v1
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                configField:
                  type: string
                  default: 'default-value'

Если при создании экземпляра ресурса поле configField не указано, оно автоматически получит значение default-value.

CRD могут быть обновлены для изменения их структуры или валидационных правил. Это делается путем изменения манифеста CRD и применения его с помощью kubectl apply.

Допустим, мы хотим добавить новое поле additionalConfig в наш CRD:

spec:
  versions:
    - name: v1
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                configField:
                  type: string
                additionalConfig:
                  type: integer

После добавления нового поля в манифест, применяем изменения:

kubectl apply -f my-updated-crd.yaml

Отслеживание состояния CRD помогает понять текущее состояние ресурсов в вашем кластере. Это можно сделать с помощью команды kubectl get:

kubectl get crd myresources.example.com -o yaml

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

Удаление CRD из кластера удаляет определение и все связанные с ним экземпляры:

kubectl delete crd myresources.example.com

Контроллеры позволяют динамически реагировать на изменения в CRD и управлять связанными ресурсами. Они могут быть написаны на любом языке, поддерживающем взаимодействие с API Kubernetes:

// простой примерчик на golang

func watchMyResources() {
    // конфигурация для подключения к API серверу Kubernetes
    config, err := rest.InClusterConfig()
    if err != nil {
        log.Fatalf("Ошибка получения конфигурации: %s", err.Error())
    }

    clientset, err := dynamic.NewForConfig(config)
    if err != nil {
        log.Fatalf("Ошибка создания клиента: %s", err.Error())
    }

    // ресурс для отслеживания
    resource := schema.GroupVersionResource{Group: "example.com", Version: "v1", Resource: "myresources"}

    // отслеживание изменений
    watcher, err := clientset.Resource(resource).Namespace("").Watch(context.Background(), metav1.ListOptions{})
    if err != nil {
        log.Fatalf("Ошибка создания наблюдателя: %s", err.Error())
    }

    // обраотка событий
    for event := range watcher.ResultChan() {
        fmt.Printf("Обнаружено событие: %s\n", event.Type)
    }
}

func main() {
    watchMyResources()
}

Собственные CRD позволяют нам создавать собственные абстракции и управлять ими с помощью стандартных инструментов Kubernetes.

Напоследок хочу порекомендовать бесплатный урок от экспертов OTUS, которые расскажут про архитектуру решений на основе Kubernetes.

Теги:
Хабы:
Всего голосов 8: ↑6 и ↓2+6
Комментарии0

Публикации

Информация

Сайт
otus.ru
Дата регистрации
Дата основания
Численность
101–200 человек
Местоположение
Россия
Представитель
OTUS