Лабораторная 8.4: Финальный проект
Связанный урок: Урок 8.4: Практические паттерны и лучшие практики
Навигация: ← Предыдущая лабораторная: Stateful-приложения | Обзор модуля | Обзор курса
Цели
Создать полноценный, готовый к продакшену оператор для stateful-приложения, демонстрирующий все концепции, изученные на протяжении курса. Этот финальный проект объединяет всё, что вы изучили из Модулей 1–8, в единый исчерпывающий оператор.
Предварительные требования
- Завершение всех предыдущих модулей (Модули 1–7)
- Завершение Лабораторной 8.1, Лабораторной 8.2 и Лабораторной 8.3
- Понимание всех концепций операторов:
- Рабочая среда разработки с kubebuilder, Go, Docker/Podman и kind
Требования к проекту
Ваш финальный оператор должен включать:
- Полные CRUD-операции
- Create, Read, Update, Delete
- Корректная обработка ошибок
- Идемпотентные операции
- Отчётность о статусе
- Подресурс status
- Условия (conditions)
- Отслеживание прогресса
- Наблюдаемое поколение (observed generation)
- Вебхуки
- Валидирующие вебхуки
- Мутирующие вебхуки
- Значения по умолчанию
- Правила валидации
- Тестирование
- Модульные тесты
- Интеграционные тесты
- Покрытие тестами > 80%
- Продакшен-возможности
- Конфигурация RBAC
- Усиление безопасности
- Высокая доступность
- Оптимизация производительности
- Продвинутые возможности
- Поддержка мультиарендности
- Резервное копирование/восстановление
- Скользящие обновления
- Документация
Структура проекта
final-operator/
├── api/
│ └── v1/
│ ├── groupversion_info.go
│ └── <resource>_types.go
├── internal/controller/
│ └── <resource>_controller.go
├── config/
│ ├── crd/
│ ├── rbac/
│ ├── manager/
│ └── webhook/
├── internal/
│ ├── backup/
│ └── restore/
├── Dockerfile
├── Makefile
├── go.mod
├── go.sum
└── README.md
Упражнение 1: выберите ваше приложение
Варианты
- Оператор базы данных (PostgreSQL, MySQL, MongoDB)
- Оператор очереди сообщений (RabbitMQ, Kafka)
- Оператор кеша (Redis, Memcached)
- Оператор поисковой системы (Elasticsearch)
- Ваш выбор (любое stateful-приложение)
Задача 1.1: сгенерируйте каркас проекта оператора
Начните с создания нового проекта оператора с помощью kubebuilder:
# Create a new directory for your final project
mkdir -p ~/final-operator
cd ~/final-operator
# Initialize kubebuilder project
kubebuilder init --domain example.com --project-name final-operator
# Create your API (replace <resource> with your choice, e.g., Database, Cache, Queue)
kubebuilder create api \
--group apps \
--version v1 \
--kind <Resource> \
--resource --controller
# When prompted:
# Create Resource [y/n]: y
# Create Controller [y/n]: y
Задача 1.2: определите исчерпывающие типы API
Отредактируйте api/v1/<resource>_types.go, чтобы создать готовый к продакшену API. Вот полный пример для оператора базы данных:
package v1
import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// DatabaseSpec defines the desired state of Database
type DatabaseSpec struct {
// Image is the database image to use
// +kubebuilder:validation:Required
// +kubebuilder:default="postgres:14"
Image string `json:"image"`
// Replicas is the number of database replicas
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=10
// +kubebuilder:default=1
Replicas *int32 `json:"replicas,omitempty"`
// Storage is the storage configuration
Storage StorageSpec `json:"storage"`
// Resources are the resource requirements
Resources corev1.ResourceRequirements `json:"resources,omitempty"`
// DatabaseName is the name of the database to create
// +kubebuilder:validation:Required
DatabaseName string `json:"databaseName"`
// Username is the database user
// +kubebuilder:validation:Required
Username string `json:"username"`
// PasswordSecretRef references a Secret containing the password
// +optional
PasswordSecretRef *corev1.SecretKeySelector `json:"passwordSecretRef,omitempty"`
// Backup configuration
// +optional
Backup *BackupConfig `json:"backup,omitempty"`
// Monitoring configuration
// +optional
Monitoring *MonitoringConfig `json:"monitoring,omitempty"`
}
// StorageSpec defines storage configuration
type StorageSpec struct {
// Size is the storage size
// +kubebuilder:validation:Required
Size string `json:"size"`
// StorageClassName is the storage class to use
// +optional
StorageClassName *string `json:"storageClassName,omitempty"`
}
// BackupConfig defines backup configuration
type BackupConfig struct {
// Enabled enables automatic backups
Enabled bool `json:"enabled"`
// Schedule is the cron schedule for backups
// +optional
Schedule string `json:"schedule,omitempty"`
// Retention is the number of backups to retain
// +kubebuilder:validation:Minimum=1
// +kubebuilder:default=7
Retention int `json:"retention,omitempty"`
}
// MonitoringConfig defines monitoring configuration
type MonitoringConfig struct {
// Enabled enables monitoring
Enabled bool `json:"enabled"`
// ServiceMonitor creates a ServiceMonitor for Prometheus
// +optional
ServiceMonitor bool `json:"serviceMonitor,omitempty"`
}
// DatabaseStatus defines the observed state of Database
type DatabaseStatus struct {
// Conditions represent the latest observations
Conditions []metav1.Condition `json:"conditions,omitempty"`
// Phase is the current phase
// +kubebuilder:validation:Enum=Pending;Creating;Ready;Failed;Updating
Phase string `json:"phase,omitempty"`
// Ready indicates if the database is ready
Ready bool `json:"ready,omitempty"`
// ReadyReplicas is the number of ready replicas
ReadyReplicas int32 `json:"readyReplicas,omitempty"`
// Endpoint is the database endpoint
Endpoint string `json:"endpoint,omitempty"`
// ObservedGeneration is the generation observed by the controller
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
// LastBackupTime is when the last backup was completed
// +optional
LastBackupTime *metav1.Time `json:"lastBackupTime,omitempty"`
}
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Phase",type="string",JSONPath=".status.phase"
// +kubebuilder:printcolumn:name="Ready",type="boolean",JSONPath=".status.ready"
// +kubebuilder:printcolumn:name="Replicas",type="integer",JSONPath=".status.readyReplicas"
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
// Database is the Schema for the databases API
type Database struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec DatabaseSpec `json:"spec,omitempty"`
Status DatabaseStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
// DatabaseList contains a list of Database
type DatabaseList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Database `json:"items"`
}
func init() {
SchemeBuilder.Register(&Database{}, &DatabaseList{})
}
Задача 1.3: сгенерируйте CRD и проверьте
# Generate code and CRD manifests
make generate
make manifests
# Review the generated CRD
cat config/crd/bases/apps.example.com_databases.yaml
# Install CRDs
make install
# Verify CRD is installed
kubectl get crd databases.apps.example.com
Упражнение 2: реализация основной функциональности
Задача 2.1: реализуйте полную логику согласования
Отредактируйте internal/controller/<resource>_controller.go, чтобы реализовать полное согласование. Для полных примеров используйте эталонные реализации из решений Модуля 3 и решений Модуля 4.
Ключевые компоненты для реализации:
Reconcile()— основной цикл согласования с обработкой фазhandlePending()— обработка начального состоянияhandleCreating()— логика создания ресурсовhandleReady()— мониторинг состояния ReadyhandleUpdating()— обработка обновленийhandleDeletion()— очистка с финализаторамиreconcileSecret()— управление SecretreconcileStatefulSet()— создание/обновление StatefulSetreconcileService()— управление ServiceupdateStatus()— обновления статуса и условий
Задача 2.2: реализуйте вспомогательные функции управления статусом
Добавьте исчерпывающие функции управления статусом. Для полного управления условиями используйте эталонные реализации из решений Модуля 4.
Упражнение 3: добавление вебхуков
Задача 3.1: сгенерируйте каркас вебхуков
# Create validating and mutating webhooks
kubebuilder create webhook \
--group apps \
--version v1 \
--kind Database \
--programmatic-validation \
--defaulting
Задача 3.2: реализуйте валидирующий вебхук
Отредактируйте internal/webhook/v1/database_webhook.go, чтобы добавить исчерпывающую валидацию. Подробные примеры см. в Лабораторной 2 Модуля 5.
Ключевые валидации для реализации:
- Валидация формата имени базы данных
- Валидация формата имени пользователя
- Валидация формата размера хранилища
- Валидация диапазона реплик
- Предотвращение изменения неизменяемых полей при обновлении
Задача 3.3: реализуйте мутирующий вебхук
Добавьте логику установки значений по умолчанию для:
- Образа по умолчанию, если не указан
- Реплик по умолчанию, если не указаны
- Периода хранения резервных копий по умолчанию
- Лимитов ресурсов по умолчанию
Задача 3.4: сгенерируйте манифесты вебхуков
# Generate webhook manifests
make manifests
# Review webhook configuration
cat config/webhook/manifests.yaml
# For local development, use cert-manager or manual certificates
# See Module 5 Lab 4 for webhook deployment details
Упражнение 4: добавление тестирования
Задача 4.1: напишите исчерпывающие модульные тесты
Отредактируйте internal/controller/<resource>_controller_test.go, чтобы добавить исчерпывающие тесты. Полные примеры см. в решениях Модуля 6.
Сценарии тестирования для покрытия:
- Создание ресурса
- Обновления ресурса
- Удаление ресурса
- Обновления статуса
- Обработка ошибок
- Обработка финализаторов
Задача 4.2: напишите интеграционные тесты
Создайте internal/controller/integration_test.go для сквозных тестов. См. Лабораторную 3 Модуля 6.
Задача 4.3: запустите тесты и проверьте покрытие
# Setup envtest binaries
make setup-envtest
# Run all tests
make test
# Run with coverage
go test -coverprofile=coverage.out ./internal/controller/...
go tool cover -html=coverage.out
# Verify coverage is > 80%
go test -cover ./internal/controller/...
Задача 4.4: добавьте примеры тестов для продвинутых возможностей
Добавьте тесты для:
- Функциональности резервного копирования/восстановления
- Сценариев мультиарендности
- Обработки ошибок и повторов
- Валидации вебхуками
- Обновлений условий статуса
Полные примеры тестов см. в решениях Модуля 6.
Упражнение 5: продакшен-возможности
Задача 5.1: настройте RBAC
# Generate RBAC manifests
make manifests
# Review RBAC configuration
cat config/rbac/role.yaml
# Optimize RBAC - remove unnecessary permissions
# Only grant permissions your operator actually needs
Проверьте и оптимизируйте сгенерированный RBAC. Лучшие практики см. в Лабораторной 2 Модуля 7.
Задача 5.2: усиление безопасности
Обновите Dockerfile для безопасности
Убедитесь, что ваш Dockerfile использует distroless-образы и запускается не от root. Полный пример см. в решениях Модуля 7.
Добавьте контексты безопасности
Обновите config/manager/manager.yaml, включив контексты безопасности. Полную конфигурацию безопасности см. в решениях Модуля 7.
Задача 5.3: включите высокую доступность
Включите выбор лидера
Обновите cmd/main.go, чтобы включить выбор лидера. Полную настройку HA см. в Лабораторной 3 Модуля 7.
Добавьте бюджет прерывания подов
Создайте config/manager/pdb.yaml для конфигурации бюджета прерывания подов.
Задача 5.4: оптимизация производительности
Добавьте ограничение частоты
Обновите настройку контроллера, чтобы использовать ограничение частоты. Продвинутое ограничение частоты см. в решениях Модуля 7.
Задача 5.5: добавьте наблюдаемость
Добавьте метрики и логирование. Полную настройку наблюдаемости см. в Лабораторной 4 Модуля 6.
Упражнение 6: документация
Задача 6.1: создайте исчерпывающий README
Создайте README.md в корне проекта с:
- Руководством по быстрому старту
- Обзором архитектуры
- Документацией API
- Примерами
- Руководством по устранению неполадок
Задача 6.2: создайте примеры ресурсов
Создайте config/samples/apps_v1_database.yaml и дополнительные примеры в каталоге examples/:
- Пример базового использования
- Продвинутые сценарии
- Настройка мультиарендности
- Примеры резервного копирования/восстановления
Задача 6.3: добавьте документацию API
Задокументируйте все поля API с понятными описаниями и примерами. Используйте маркеры kubebuilder для автоматической генерации документации.
Упражнение 7: сборка и развёртывание
Задача 7.1: соберите образ контейнера
# Build the image
make docker-build IMG=final-operator:v1.0.0
# For kind, load image
kind load docker-image final-operator:v1.0.0 --name k8s-operators-course
# Or push to registry
docker push final-operator:v1.0.0
Задача 7.2: разверните оператор
# Update image in config/manager/manager.yaml
# Then deploy
make deploy IMG=final-operator:v1.0.0
# Verify deployment
kubectl get pods -n final-operator-system
# Check logs
kubectl logs -n final-operator-system -l control-plane=controller-manager
Задача 7.3: протестируйте ваш оператор
# Create a test resource
kubectl apply -f config/samples/apps_v1_database.yaml
# Watch the resource
kubectl get database database-sample -w
# Verify resources were created
kubectl get statefulset,service,secret -l app=database-sample
# Test updates
kubectl patch database database-sample --type=merge -p '{"spec":{"replicas":3}}'
# Test deletion
kubectl delete database database-sample
Чек-лист для сдачи
Используйте этот чек-лист, чтобы убедиться в полноте вашего оператора:
Основная функциональность
- Реализованы полные CRUD-операции (Create, Read, Update, Delete)
- Корректная обработка ошибок повсюду
- Идемпотентная логика согласования
- Реализованы финализаторы для очистки
Управление статусом
- Настроен подресурс status
- Условия реализованы и корректно обновляются
- Отслеживание фаз (Pending, Creating, Ready, Failed и т. д.)
- Отслеживание наблюдаемого поколения
- Отслеживание прогресса для длительных операций
Вебхуки
- Реализован валидирующий вебхук
- Реализован мутирующий вебхук
- Значения по умолчанию установлены корректно
- Правила валидации исчерпывающие
- Настроены сертификаты вебхука
Тестирование
- Написаны модульные тесты (покрытие >80%)
- Реализованы интеграционные тесты
- Набор тестов успешно выполняется (
make test) - Покрыты граничные случаи
- Протестированы сценарии ошибок
Продакшен-возможности
- RBAC настроен и оптимизирован
- Безопасность усилена (distroless, не от root, контексты безопасности)
- Включена высокая доступность (выбор лидера)
- Производительность оптимизирована (ограничение частоты, конкурентность)
- Добавлена наблюдаемость (метрики, логирование)
Продвинутые возможности
- Поддержка мультиарендности (если применимо)
- Функциональность резервного копирования/восстановления (если применимо)
- Скользящие обновления обрабатываются корректно
- Соблюдаются квоты ресурсов
Документация
- README.md полон и включает:
- Руководство по быстрому старту
- Обзор архитектуры
- Документацию API
- Примеры
- Руководство по устранению неполадок
- Предоставлены примеры ресурсов
- Комментарии в коде исчерпывающие
- Поля API задокументированы
Упаковка
- Образ контейнера успешно собирается
- Образ опубликован в реестр (или загружен в kind)
- Оператор успешно развёртывается
- Все ресурсы создаются корректно
- Оператор работает от начала до конца
Очистка
После завершения проекта:
# Delete test resources
kubectl delete database --all --all-namespaces
# Undeploy operator
make undeploy
# Uninstall CRDs
make uninstall
# Clean up kind cluster (if using)
kind delete cluster --name k8s-operators-course
Чек-лист для самооценки
Используйте этот чек-лист, чтобы убедиться, что ваш оператор соответствует готовым к продакшену стандартам:
Функциональность
- Основные операции: все CRUD-операции работают корректно
- Граничные случаи: аккуратно обрабатывает граничные случаи (удаление, обновления, сбои)
- Обработка ошибок: корректная обработка ошибок и логика повторов
- Управление статусом: статус точно отражает состояние ресурса
- Вебхуки: валидация и мутация работают корректно
Качество кода
- Структура: хорошо организован, следует лучшим практикам Go
- Читаемость: понятные имена переменных, комментарии где нужно
- Идемпотентность: согласование идемпотентно
- Управление ресурсами: правильное использование финализаторов, ссылок-владельцев
- Сообщения об ошибках: понятные, применимые сообщения об ошибках
Стандарты тестирования
- Покрытие: покрытие тестами > 80%
- Модульные тесты: исчерпывающие модульные тесты для логики контроллера
- Интеграционные тесты: сквозные интеграционные тесты
- Граничные случаи: тесты покрывают сценарии ошибок и граничные случаи
- Качество тестов: тесты сопровождаемы и хорошо структурированы
Готовность к продакшену
- Безопасность: использует distroless-образы, не от root, контексты безопасности
- RBAC: минимальная конфигурация RBAC по принципу наименьших привилегий
- Высокая доступность: включён выбор лидера
- Производительность: настроены ограничение частоты, лимиты конкурентности
- Наблюдаемость: реализованы метрики и логирование
Стандарты документации
- README: исчерпывающий README с быстрым стартом
- Документация API: все поля API задокументированы
- Примеры: предоставлено несколько примеров ресурсов
- Устранение неполадок: задокументированы распространённые проблемы и решения
- Комментарии в коде: важная логика объяснена
Интеграция с предыдущими модулями
Этот финальный проект объединяет концепции из всех предыдущих модулей:
- Модуль 1: понимание архитектуры Kubernetes и механизмов API
- Модуль 2: использование Kubebuilder для генерации каркаса операторов
- Модуль 3: controller runtime и паттерны согласования
- Модуль 4: продвинутые паттерны (условия, финализаторы, отслеживание)
- Модуль 5: вебхуки и контроль допуска
- Модуль 6: тестирование и наблюдаемость
- Модуль 7: подготовка к продакшену (упаковка, безопасность, HA)
- Модуль 8: продвинутые темы (мультиарендность, композиция, stateful-приложения)
Эталонные решения из предыдущих модулей:
- Решения Модуля 3 — реализация контроллера
- Решения Модуля 4 — продвинутые паттерны
- Решения Модуля 5 — вебхуки
- Решения Модуля 6 — тестирование
- Решения Модуля 7 — продакшен-возможности
- Решения Модуля 8 — продвинутые возможности
Решения
Полные примеры решений и эталонные реализации доступны:
- Решения предыдущих модулей: используйте эталонные решения из Модулей 3–7 для паттернов реализации
- Решения Модуля 8: см. каталог решений для:
- Паттернов мультиарендного оператора
- Примеров композиции операторов
- Реализаций резервного копирования/восстановления
- Паттернов скользящих обновлений
Итоги лабораторной
В этой лабораторной с финальным проектом вы:
- Спроектировали полноценный API — создали исчерпывающий CRD со spec и status
- Реализовали полное согласование — построили полноценный контроллер со всеми CRUD-операциями
- Добавили вебхуки — реализовали валидирующие и мутирующие вебхуки
- Написали исчерпывающие тесты — создали модульные и интеграционные тесты с покрытием >80%
- Настроили продакшен-возможности — настроили RBAC, безопасность, HA и оптимизации производительности
- Создали документацию — написали README, примеры и документацию API
- Собрали и развернули — упаковали оператор как образ контейнера и развернули в кластер
Ключевые уроки
Благодаря этому финальному проекту вы продемонстрировали владение:
- Жизненным циклом разработки операторов — от генерации каркаса до продакшен-развёртывания
- Паттернами API Kubernetes — CRD, подресурсы status, условия, финализаторы
- Паттернами контроллеров — согласование, идемпотентность, обработка ошибок
- Контролем допуска — валидирующие и мутирующие вебхуки
- Стратегиями тестирования — модульные тесты с envtest, интеграционные тесты
- Готовностью к продакшену — безопасность, HA, производительность, наблюдаемость
- Лучшими практиками — организация кода, документация, примеры
Дальнейшие шаги
После завершения этого курса вы можете:
- Создавать реальные операторы — применять эти паттерны для создания операторов для ваших приложений
- Вносить вклад в open source — участвовать в существующих операторах или создавать новые
- Продвинутые темы — изучить:
- Operator SDK (альтернатива Kubebuilder)
- Operator Lifecycle Manager (OLM)
- Operator Framework
- Мультикластерные операторы
- Метрики и дашборды операторов
Поделитесь своим проектом
Мы будем рады увидеть, что вы создали! Если вы завершили финальный проект и хотите поделиться им:
- Опубликуйте в LinkedIn — поделитесь своим проектом оператора, тем, что вы изучили, и тем, что создали
- Отметьте автора курса — отметьте Piyush Jajoo в своём посте
- Укажите детали — поделитесь:
- Какой оператор вы создали
- Ключевые реализованные возможности
- Что вы изучили из курса
- Ссылку на ваш репозиторий GitHub (если публичный)
Я постараюсь в свободное время просмотреть ваш код и дать обратную связь!
Дополнительные ресурсы
- Kubebuilder Book — исчерпывающая документация Kubebuilder
- Соглашения об API Kubernetes — рекомендации по проектированию API
- Лучшие практики операторов — лучшие практики Operator SDK
- Примеры операторов — список примеров операторов
Поздравляем! 🎉
Вы завершили весь курс «Разработка операторов Kubernetes»!
Теперь у вас есть:
- ✅ Глубокое понимание архитектуры Kubernetes и операторов
- ✅ Практический опыт создания готовых к продакшену операторов
- ✅ Знание лучших практик и паттернов
- ✅ Навыки создания операторов для любого приложения
Теперь вы готовы создавать готовые к продакшену операторы Kubernetes!