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

—

от автора

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

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.


ссылка на оригинал статьи https://habr.com/ru/articles/787790/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *