В предыдущей статье мы рассмотрели преимущества кастомизации и настройки облачной инфраструктуры, основанные на гибкости и масштабируемости Kubernetes. Разобрали, как этот подход способствует повышению адаптивности бизнес-задач в облачной среде. Однако мы лишь немного коснулись аспекта персонализации. В этой статье предлагаю более детально рассмотреть компоненты Kubernetes, которые позволяют создать еще более индивидуализированную инфраструктуру для развертывания приложений.

Подробнее о Custom Resource Definitions

Custom Resource Definitions (CRD) являются центром расширяемости Kubernetes. CRD позволяет разработчикам создавать и использовать их собственные специализированные ресурсы, вместо того чтобы полагаться только на стандартные, предоставляемые Kubernetes. CRD стали основой для общения разнообразных сторонних приложений и инструментов с кластерами Kubernetes.

Одно из наиболее важных преимуществ CRD — возможность полностью управлять ими с помощью существующих команд kubectl. Это делает их относительно простыми для использования и интеграции в имеющиеся рабочие процессы. Однако CRD не могут функционировать самостоятельно. Они работают вместе с Kubernetes API Aggregation Layer, который соединяет CRD с основным Kubernetes API Server. Как следствие, управление и контроль доступа к CRD можно настроить точно так же, как и для встроенных ресурсов.

Важность CRD в экосистеме Kubernetes можно увидеть во множестве Operators, которые созданы с использованием CRD и Operator SDK. Операторы представляют собой приложения, развернутые на кластере, которые извлекают всю пользу из CRD для расширения функционала Kubernetes, дающего возможность адаптировать его под свои уникальные приложения и сервисы.

Важно отметить, что несмотря на огромные возможности, которые открываются благодаря использованию CRD, они также могут представлять собой риск. Неудачное использование или ошибки в CRD могут привести к проблемам в кластере. Поэтому всегда рекомендуется тщательно тестировать CRD в безопасной среде перед их выпуском в проде.

Давайте рассмотрим CRD более подробно на примере создания ресурса «User», который будет для хранить информацию о пользователях в нашем приложении.

  1. В первую очередь нужно создать описание CRD. Создайте файл под названием user_crd.yaml со следующим содержимым:

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: users.custom.example.com
spec:
  group: custom.example.com
  versions:
  - name: v1
    served: true
    storage: true
    schema:
      openAPIV3Schema:
        type: object
        properties:
          spec:
            type: object
            properties:
              firstName:
                type: string
              lastName:
                type: string
              email:
                type: string
  scope: Namespaced
  names:
    plural: users
    singular: user
    kind: User
    shortNames:
    - usr
  1. Теперь создайте CRD в вашем кластере с помощью kubectl и проверьте его создание:

kubectl apply -f user_crd.yaml
kubectl get crd
  1. Следующим шагом будем создание объекта нового типа «User». Создайте новый файл user_object.yaml и добавьте следующий код:

apiVersion: "custom.example.com/v1"
kind: User
metadata:
  name: user-sample
spec:
  firstName: Ivan
  lastName: Petrov
  email: ivan.petrov@example.com
  1. Создайте новый объект «User» с помощью kubectl и проверьте создание объекта:

kubectl apply -f user_object.yaml
kubectl get users
  1. Вы также можете проверить полную информацию об этом пользователе:

kubectl describe user user-sample

Создание собственных CRD может быть сложным процессом. Но с правильным пониманием Kubernetes и подходящими инструментами создание качественной CRD становится достижимой задачей. Просто помните, что лучший CRD — это CRD, которую вы создали сами и полностью контролируете.

Создание собственных версий объектов API

Обычно, чтобы добавить собственные методы в API Kubernetes, разработчики используют Aggregated API Servers. Они обрабатывают дополнительные API методы и, в отличие от CRD, позволяют вручную управлять всем процессом. При использовании Aggregated API Servers вы получаете контроль над всем процессом управления и обработки дополнительных API методов. Это позволяет точно определить, каким образом будут обрабатываться запросы и какая логика будет применяться к этим методам. Aggregated API Servers предоставляют возможность создания своего собственного API пути и определения, какие версии, группы и пространства имен будут использоваться в их методах API.

Предлагаю рассмотреть несколько общих сценариев использования Aggregated API Servers:

  1. Пользовательские методы для объектов API. Агрегированные API-серверы можно использовать, чтобы добавить пользовательские методы для объектов API в Kubernetes. Например, можно создать API-сервер, который добавляет методы для работы с пользовательским типом данных.

  2. Расширения для существующих ресурсов API. Можно создавать новые функции и методы к существующим ресурсам API. Это будет полезным, если вам нужно изменить поведение существующего ресурса или добавить новую функциональность.

  3. Интеграция с внешними сервисами. Агрегированные API-серверы могут быть использованы для интеграции Kubernetes с внешними сервисами. Например, можно создать API-сервер, который взаимодействует с внешней базой данных или другим API.

  4. Создание собственных контроллеров. Контроллеры в Kubernetes следят за состоянием кластера и принимают меры для поддержания желаемого состояния. Путем создания собственных контроллеров вы можете добавлять свою логику для управления кастомными ресурсами или изменением поведения существующих ресурсов.

Давайте рассмотрим пример, где мы создадим простой контроллер на языке Go для мониторинга подов. При создании собственных контроллеров API в Kubernetes вам понадобится описать две части: контроллер и его манифест YAML.

Пример кода контроллера на Go:

package main

import (
	"fmt"
	corev1 "k8s.io/api/core/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/client-go/util/homedir"
	"path/filepath"
	"time"
)

func main() {
	// Подключение к кластеру Kubernetes
	home := homedir.HomeDir()
	kubeconfig := filepath.Join(home, ".kube", "config")
	config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
	if err != nil {
		panic(err.Error())
	}
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		panic(err.Error())
	}

	// Запуск бесконечного цикла мониторинга
	for {
		// Получение списка подов из кластера
		pods, err := clientset.CoreV1().Pods("default").List(context.TODO(), metav1.ListOptions{})
		if err != nil {
			panic(err.Error())
		}

		// Вывод информации о каждом поде
		fmt.Println("Pods in the cluster:")
		for _, pod := range pods.Items {
			fmt.Printf("- %s\n", pod.Name)
		}

		// Задержка перед следующим мониторингом
		time.Sleep(30 * time.Second)
	}
}

Данный контроллер мониторит и выводит список подов в кластере каждые 30 секунд.

Пример манифеста для развертывания контроллера my-controller:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-controller
spec:
  selector:
    matchLabels:
      app: my-controller
  template:
    metadata:
      labels:
        app: my-controller
    spec:
      containers:
      - name: my-controller
        image: my-controller:latest
        command:
        - /bin/sh
        - -c
        - /usr/local/bin/my-controller

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

Операторы Kubernetes

Операторы Kubernetes обеспечивают специфичную для домена логику управления и обновления сложных системных сценариев, как правило, выходящих за рамки примитивов, доступных в Kubernetes через стандартные API.

Вспомним, что операторы в Kubernetes используются для автоматизации управления, установки и обновления экземпляров приложений или сложных состояний в Kubernetes. Они активно используются в области управления состоянием приложения, например, в случае баз данных, серверов, очереди сообщений и других сложных системных компонентов. Все это требует специфических знаний о процессах установки, настройки, обновления и масштабирования данных систем, которые включены прямо в оператор.

Для иллюстрации давайте рассмотрим операторы Postgres и Prometheus, которые хорошо иллюстрируют используемые концепции.

Пример с оператором базы данных

  1. Установка Postgres operator
    Операторы обычно предоставляются как Helm-чарты, что позволяет просто их установить.

helm install postgres-operator zalando/postgres-operator

Теперь внутри Kubernetes у нас есть оператор PostgreSQL, который принимает контроль и автоматизирует управление базами данных PostgreSQL.

  1. Использование оператора
    Создавая заявки на базу данных через Custom Resource Definition (CRD), Kubernetes и оператор заботятся о всем остальном, например, о поднятии настроенной базы данных, бэкапах, обновлениях и масштабировании. Это делается путем создания конфигурации в формате YAML и развертывания ее в кластере:

apiVersion: acid.zalan.do/v1
kind: postgresql
metadata:
  name: mydb
  namespace: default
spec:
  teamId: "myteam"
  volume:
    size: 1Gi
  numberOfInstances: 2
  users:
    admin:
    - superuser
    - createdb
  databases:
    mydb: admin
  postgresql:
    version: "12"

После развертывания этого конфигурационного файла оператор создаст две реплики базы данных PostgreSQL. Система будет автоматически масштабироваться и обновляться по мере необходимости, а оператор будет обрабатывать всю эту сложную логику.

Оператор PostgreSQL также обрабатывает резервное копирование и восстановление, обслуживание и устранение неисправностей. Он может автоматически заменять узлы базы данных при сбоях и обеспечивать высокую доступность и надежность.

В качестве еще одного примера действий этого оператора — значение numberOfInstances. Если это значение в спецификации CRD увеличено, оператор автоматически добавит новые реплики к существующей базе данных.

Пример с оператором мониторинга

Еще одним полезным примером оператора Kubernetes является оператор мониторинга, который автоматизирует процесс настройки и управления инфраструктурой мониторинга.

Например, Prometheus Operator — это оператор для управления экземплярами Prometheus и других компонентов связанного стека мониторинга.

  1. Установка Prometheus Operator

kubectl apply -f https://raw.githubusercontent.com/coreos/prometheus-operator/release-0.48/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml
kubectl apply -f https://raw.githubusercontent.com/coreos/prometheus-operator/release-0.48/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml
kubectl apply -f https://raw.githubusercontent.com/coreos/prometheus-operator/release-0.48/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml
kubectl apply -f https://raw.githubusercontent.com/coreos/prometheus-operator/release-0.48/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml
kubectl apply -f https://raw.githubusercontent.com/coreos/prometheus-operator/release-0.48/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml
kubectl apply -f https://raw.githubusercontent.com/coreos/prometheus-operator/release-0.48/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml

kubectl apply -f https://raw.githubusercontent.com/coreos/prometheus-operator/release-0.48/example/prometheus-operator-deployment.yaml
  1. Использование оператора
    После установки оператора можно создавать экземпляры мониторинга, определяя их через Custom Resource Definitions (CRD). Например, создание экземпляра мониторинга для приложения:

apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
  name: app-prometheus
spec:
  replicas: 1
  serviceAccountName: prometheus
  securityContext:
    fsGroup: 2000
  serviceMonitorSelector:
    matchLabels:
      app: myapp
  ruleSelector:
    matchLabels:
      prometheus: myapp
  resources:
    requests:
      memory: 400Mi
  alerting:
    alertmanagers:
    - namespace: monitoring
      name: alertmanager-main
      port: web

В приведенном примере replicas: 1 указывает на существование только одной реплики Prometheus. ServiceMonitorSelector конфигурирует Prometheus, чтобы он «подключался» ко всем ServiceMonitors в неймспейсе, имеющим метку «app: myapp», что позволяет Prometheus автоматически обнаруживать и использовать цели мониторинга.

resources определяет необходимость ресурсов для подов Prometheus, в данном случае «memory: 400Mi».

В секции alerting мы указываем, куда Prometheus должен посылать сигналы тревоги. В этом случае сигналы будут направлены на экземпляр Alertmanager, находящийся в неймспейсе «monitoring».

После создания этого CRD, оператор Prometheus создаст экземпляр Prometheus с указанными конфигурациями и начнет слежение за указанными сервисами. Это обеспечит надежный и управляемый контроль вашего приложения.

Операторы Kubernetes способны управлять жизненным циклом сложных приложений и состояний, предоставляя уровень автоматизации, который ранее был доступен только в рамках управляемых сервисов облака.

Заключение

Custom Resource Definitions (CRD), собственные версии объектов API и Operators — это мощные инструменты, которые позволяют настраивать инфраструктуру под определенные потребности и достигать высокой производительности и эффективности приложений. Хотя создание персонализированной инфраструктуры может потребовать значительных усилий, которые будут вложены в настройку и управление, в итоге вы сможете в значительной степени сэкономить ресурсы и время благодаря детальной оптимизации ваших процессов.

Спасибо за внимание! Надеюсь, статья была интересна всем, кто стремится извлечь максимум пользы из облачных вычислений и создать настраиваемое окружение для своих приложений. Пишите ваши предложения и замечания в комментариях.

Автор статьи @exzvor


НЛО прилетело и оставило здесь промокод для читателей нашего блога:
— 15% на заказ любого VDS (кроме тарифа Прогрев) — HABRFIRSTVDS.

Комментарии (0)