Привет, Хабр! 🚀
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.