Быстро начните работу с оператором K8S
Быстро начните работу с оператором K8S

Предисловие

Если вы хотите выполнить вторичную разработку для K8S или инкапсулировать некоторые функции на исходной основе, чтобы разработчикам было проще их использовать, вам необходимо освоить использование оператора.

Что такое оператор

Я думаю Operator Действительно K8S Дизайн расширения очень продуманный. Оно похоже на подключаемую систему. Как только оно у вас появится, вы почувствуете, что оно у вас есть. k8s Расширенное право на эксплуатацию может расширить различные виды использования. Это Что такое оператор Шерстяная ткань? Это требует CRD Кстати.

CRD

Прежде всего нам нужно знать, что первая концепция CRD(Custom Resource Define),Пользовательское определение ресурса,Судя по названию, этоиспользоватьможет пройти CRD для создания пользовательских ресурсов. мы знаем в K8S Существуют различные ресурсы в PodDeploymentStatefulSet… Письмо yaml Соответствующий тип ресурса будет указан при вводе файла.

Официальная документация:Create a CustomResourceDefinition Существует фактическое CustomResourceDefinition Случай

Язык кода:javascript
копировать
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  # name must match the spec fields below, and be in the form: <plural>.<group>
  name: crontabs.stable.example.com
spec:
  # group name to use for REST API: /apis/<group>/<version>
  group: stable.example.com
  # list of versions supported by this CustomResourceDefinition
  versions:
    - name: v1
      # Each version can be enabled/disabled by Served flag.
      served: true
      # One and only one version must be marked as the storage version.
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                cronSpec:
                  type: string
                image:
                  type: string
                replicas:
                  type: integer
  # either Namespaced or Cluster
  scope: Namespaced
  names:
    # plural name to be used in the URL: /apis/<group>/<version>/<plural>
    plural: crontabs
    # singular name to be used as an alias on the CLI and for display
    singular: crontab
    # kind is normally the CamelCased singular type. Your resource manifests use this.
    kind: CronTab
    # shortNames allow shorter string to match your resource on the CLI
    shortNames:
    - ct

---- Ниже приводится конкретная информация object ----

apiVersion: "stable.example.com/v1"
kind: CronTab
metadata:
  name: my-new-cron-object
spec:
  cronSpec: "* * * * */5"
  image: my-awesome-cron-image

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

Controller

Определенно невозможно иметь ресурсы без того, чтобы кто-то ими управлял, поэтому нам нужен контроллер, чтобы контролировать его поведение и действия. Фактически, контроллер — это, по сути, контур управления. Мы знаем, что режим управления k8s на самом деле основан на модели состояния. Он будет отслеживать состояние всех ресурсов. Когда текущий статус ресурса не соответствует состоянию ресурса, определенному пользователем, он будет вносить коррективы и находить способы корректировки. состояние ресурсов до ожидаемого значения.

Язык кода:javascript
копировать
for {
    действительныйсостояние := получатькластерсерединаобъект X издействительныйсостояние(Actual State) 
    ожидатьсостояние := получатькластерсерединаобъект X изожидатьсостояние(Expectation State) 
    if действительныйсостояние == ожидатьсостояние{        ничего не делать
    } else {
        Выполнять хореографические действия, которые приводят фактическое состояние в желаемое состояние.
    }
}

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

Operator

Поэтому мы можем просто понимать это как Operator = CRD + Controller Другими словами, пользовательские ресурсы плюс пользовательские контроллеры Оператор, с помощью которого мы можем не только настраивать нужные нам ресурсы, но и управлять ими с помощью желаемой логики и метода.

Тогда вы можете себе представить, насколько он универсален. Например: с помощью пользовательских ресурсов вы можете определить различные атрибуты, которые вам нужны. В исходном развертывании были только эти атрибуты. Теперь вы можете расширить различные атрибуты, которые хотите, и объединить некоторые существующие ресурсы. В то же время с помощью специального контроллера вы можете выполнять любую операцию. Самое главное, что вы можете сразу знать, когда необходимо запланировать различные ситуации (перезапуск, аварийный выход и т. д.), и вы можете контролировать, как идти. к планированию, какие свойства следует настроить после планирования и т. д.

Тогда эта статья поможет вам быстро создать демо-версию, чтобы познакомиться с Оператором. Конечно, предполагается, что вам нужна работоспособная среда k8s.

Создать оператора с помощью kubebuilder

развивать Operator Нет необходимости использовать kubebuilder Также доступен https://github.com/operator-framework/operator-sdk Я больше привык использовать kubebuilder Вот и все

Установить

Установить См. документацию:installation

Язык кода:javascript
копировать
$ curl -L -o kubebuilder "https://go.kubebuilder.io/dl/latest/$(go env GOOS)/$(go env GOARCH)"  
$ chmod +x kubebuilder && mv kubebuilder /usr/local/bin/  

Создать проект

Язык кода:javascript
копировать
$ mkdir opex
$ cd opex
$ kubebuilder init --domain linkinstars.com --repo linkinstars.com/op-ex

Создать API

Язык кода:javascript
копировать
$ kubebuilder create api --group example --version v1 --kind ExampleA
# Затем введите дважды y
Create Resource [y/n]
y
Create Controller [y/n]
y
Writing kustomize manifests for you to edit...
Writing scaffold for you to edit...
api/v1/examplea_types.go
api/v1/groupversion_info.go
internal/controller/suite_test.go
internal/controller/examplea_controller.go
...
...

Шаблон CRD-контроллера. Вы можете начать с беглого просмотра структуры проекта. Далее мы начнем работать над кодированием.

кодирование

Во-первых, давайте проясним нашу цель. Наша цель — создать CRD и Контроллер для взаимодействия с Оператором. Созданный нами на этот раз CRD играет роль монитора. Когда объект с меткой (Label) с указанным именем появится во всем кластере, монитор изменит свой статус и станет контролируемым.

Изменить определение CRD

Исправлять api/v1/examplea_types.go документ

Язык кода:javascript
копировать
package v1

import (
  metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// ExampleASpec defines the desired state of ExampleA
type ExampleASpec struct {
  GroupName string `json:"groupName,omitempty"`
}

// ExampleAStatus defines the observed state of ExampleA
type ExampleAStatus struct {
  UnderControl bool `json:"underControl,omitempty"`
}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status

// ExampleA is the Schema for the examplea API
type ExampleA struct {
  metav1.TypeMeta   `json:",inline"`
  metav1.ObjectMeta `json:"metadata,omitempty"`

  Spec   ExampleASpec   `json:"spec,omitempty"`
  Status ExampleAStatus `json:"status,omitempty"`
}

//+kubebuilder:object:root=true

// ExampleAList contains a list of ExampleA
type ExampleAList struct {
  metav1.TypeMeta `json:",inline"`
  metav1.ListMeta `json:"metadata,omitempty"`
  Items           []ExampleA `json:"items"`
}

func init() {
  SchemeBuilder.Register(&ExampleA{}, &ExampleAList{})
}

Вы можете видеть, что здесь мы в основном определяем ExampleA из Spec,То есть мы часто yaml документсередина Писатьиз spec свойства, куда мы добавили GroupName То есть имя группы.

Изменить определение контроллера

Исправлять internal/controller/examplea_controller.go

Язык кода:javascript
копировать
package controller

import (
  "context"
  corev1 "k8s.io/api/core/v1"
  "k8s.io/apimachinery/pkg/runtime"
  "k8s.io/apimachinery/pkg/types"
  examplev1 "linkinstars.com/op-ex/api/v1"
  ctrl "sigs.k8s.io/controller-runtime"
  "sigs.k8s.io/controller-runtime/pkg/client"
  "sigs.k8s.io/controller-runtime/pkg/handler"
  "sigs.k8s.io/controller-runtime/pkg/log"
  "sigs.k8s.io/controller-runtime/pkg/reconcile"
)

// ExampleAReconciler reconciles a ExampleA object
type ExampleAReconciler struct {
  client.Client
  Scheme *runtime.Scheme
}

//+kubebuilder:rbac:groups=example.linkinstars.com,resources=examplea,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=example.linkinstars.com,resources=examplea/status,verbs=get;update;patch
//+kubebuilder:rbac:groups=example.linkinstars.com,resources=examplea/finalizers,verbs=update

// Reconcile 
func (r *ExampleAReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
  logger := log.FromContext(ctx)
  logger.Info("Начать вызов метода Reconcile")

  var exp examplev1.ExampleA
  if err := r.Get(ctx, req.NamespacedName, &exp); err != nil {
    logger.Error(err, "Соответствующий ресурс изCRD не найден")
    return ctrl.Result{}, client.IgnoreNotFound(err)
  }

  exp.Status.UnderControl = false

  var podList corev1.PodList
  if err := r.List(ctx, &podList); err != nil {
    logger.Error(err, «Невозможно получить список модулей»).
  } else {
    for _, item := range podList.Items {
      if item.GetLabels()["group"] == exp.Spec.GroupName {
        logger.Info("Найти соответствующий ресурс изпода", "name", item.GetName())
        exp.Status.UnderControl = true
      }
    }
  }

  if err := r.Status().Update(ctx, &exp); err != nil {
    logger.Error(err, «Невозможно обновить состояние ресурса CRD»)
    return ctrl.Result{}, err
  }
  logger.Info("Состояние ресурса CRD обновлено", "status", exp.Status.UnderControl)
  return ctrl.Result{}, nil
}

// SetupWithManager sets up the controller with the Manager.
func (r *ExampleAReconciler) SetupWithManager(mgr ctrl.Manager) error {
  return ctrl.NewControllerManagedBy(mgr).
    For(&examplev1.ExampleA{}).
    Watches(
      &corev1.Pod{},
      handler.EnqueueRequestsFromMapFunc(r.podChangeHandler),
    ).
    Complete(r)
}

func (r *ExampleAReconciler) podChangeHandler(ctx context.Context, obj client.Object) []reconcile.Request {
  logger := log.FromContext(ctx)

  var req []reconcile.Request
  var list examplev1.ExampleAList
  if err := r.Client.List(ctx, &list); err != nil {
    logger.Error(err, «Невозможно получить ресурс»)
  } else {
    for _, item := range list.Items {
      if item.Spec.GroupName == obj.GetLabels()["group"] {
        req = append(req, reconcile.Request{
          NamespacedName: types.NamespacedName{Name: item.Name, Namespace: item.Namespace},
        })
      }
    }
  }
  return req
}

Основная логика очень проста,Просто пройди все из капсула, если найдется label с соответствующими groupName из pod Сразу Исправлятькогдавперед crd из UnderControl Статус true

Язык кода:javascript
копировать
if item.GetLabels()["group"] == exp.Spec.GroupName {
    logger.Info("Найти соответствующий ресурс изпода", "name", item.GetName())
    exp.Status.UnderControl = true
}

Есть несколько ключевых моментов

  • Согласование: Внимание📢,Этот метод является нашим главным приоритетом. Когда наш ресурс изменится, будет вызван этот метод. Включает объектсоздавать,spec изменения, изменения статуса и т. д.
  • SetupWithManager: добавлен монитор Watches Первый параметр метода — тип мониторизобъекта, второй параметр — handler。
  • podChangeHandler:Сразудамониторвсеиз капсула, когда pod Когда ресурсы изменяются (например, pod раз создано) добавит reconcile.Request запросить событие

отлаживать

Установить

использовать kubebuilder Из удобства означает, что развертываниеотлаживать очень удобно. Есть шаблоны. Выполните следующую команду, чтобы сгенерировать и. CRD Установитьприезжать k8s в кластере.

Язык кода:javascript
копировать
$ make manifests
$ make install

После успешного завершения установки проверьте это.

Язык кода:javascript
копировать
$ kubectl get crds |grep linkin
exampleas.example.linkinstars.com                   2023-08-03T23:02:39Z

неожиданная ошибка

Язык кода:javascript
копировать
error: accumulating resources: accumulation err='accumulating resources from 'bases/example.linkinstars.com_examplea.yaml'

Если возникает ошибка, подобная этой,Обычно возникает из-за проблем с генерацией названий документов из,Исправлять config/crd/kustomization.yaml документсерединаиз resources: для - bases/example.linkinstars.com_exampleas.yaml Соответствует правильному имени

запускать

Для запуска рекомендуется открыть новое окно терминала.,Он запустится в терминале и введет соответствующее избревно.,Удобен для последующего просмотра

Язык кода:javascript
копировать
$ make run
Язык кода:javascript
копировать
2023-08-03T23:07:21+08:00  INFO  controller-runtime.metrics  Metrics server is starting to listen  {"addr": ":8080"}
2023-08-03T23:07:21+08:00  INFO  setup  starting manager
2023-08-03T23:07:21+08:00  INFO  starting server  {"path": "/metrics", "kind": "metrics", "addr": "[::]:8080"}
2023-08-03T23:07:21+08:00  INFO  Starting server  {"kind": "health probe", "addr": "[::]:8081"}
2023-08-03T23:07:21+08:00  INFO  Starting EventSource  {"controller": "examplea", "controllerGroup": "example.linkinstars.com", "controllerKind": "ExampleA", "source": "kind source: *v1.ExampleA"}
2023-08-03T23:07:21+08:00  INFO  Starting EventSource  {"controller": "examplea", "controllerGroup": "example.linkinstars.com", "controllerKind": "ExampleA", "source": "kind source: *v1.Pod"}
2023-08-03T23:07:21+08:00  INFO  Starting Controller  {"controller": "examplea", "controllerGroup": "example.linkinstars.com", "controllerKind": "ExampleA"}
2023-08-03T23:07:21+08:00  INFO  Starting workers  {"controller": "examplea", "controllerGroup": "example.linkinstars.com", "controllerKind": "ExampleA", "worker count": 1}
2023-08-03T23:08:46+08:00  INFO  Начните вызывать метод Reconcile  {"controller": "examplea", "controllerGroup": "example.linkinstars.com", "controllerKind": "ExampleA", "ExampleA": {"name":"my-opex","namespace":"default"}, "namespace": "default", "name": "my-opex", "reconcileID": "9a03fe8e-8461-4500-b32f-140161095f8b"}
2023-08-03T23:08:46+08:00  INFO  Обновлено состояние ресурса CRD.  {"controller": "examplea", "controllerGroup": "example.linkinstars.com", "controllerKind": "ExampleA", "ExampleA": {"name":"my-opex","namespace":"default"}, "namespace": "default", "name": "my-opex", "reconcileID": "9a03fe8e-8461-4500-b32f-140161095f8b", "status": false}

Создать CRD

Создайте CRD config/samples/example_v1_examplea.yaml Содержание следующее, уточняйте groupName для business То есть, когда появится business из pod этот crd Мы начали внимательно следить.

Язык кода:javascript
копировать
apiVersion: example.linkinstars.com/v1  
kind: ExampleA  
metadata:  
  labels:  
    app.kubernetes.io/name: examplea  
    app.kubernetes.io/instance: examplea-sample  
    app.kubernetes.io/part-of: opex  
    app.kubernetes.io/managed-by: kustomize  
    app.kubernetes.io/created-by: opex  
  name: my-opex  
spec:  
  groupName: business
Язык кода:javascript
копировать
kubectl apply -f config/samples/example_v1_examplea.yaml

Затем,Давайте проверим состояние бывшего CRD.,Вы можете видеть, что теперь состояние должно быть пустым.

Язык кода:javascript
копировать
$ kubectl describe ExampleA my-opex

Затем Создать новыйдокумент example_v1_examplea 1.yaml

Язык кода:javascript
копировать
apiVersion: v1
kind: Pod
metadata:
  name: busybox
  labels:
    group: "business"
spec:
  containers:
    - name: busybox
      image: busybox:latest
      command:
        - sleep
        - "3600"

Затем еще раз проверьте статус CRD.

Язык кода:javascript
копировать
$ kubectl describe ExampleA my-opex
...
Spec:
  Group Name:  business
Status:
  Under Control:  true
Events:           <none>
...

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

Язык кода:javascript
копировать
2023-08-03T23:28:21+08:00  INFO  Начните вызывать метод Reconcile  {"controller": "examplea", "controllerGroup": "example.linkinstars.com", "controllerKind": "ExampleA", "ExampleA": {"name":"my-opex","namespace":"default"}, "namespace": "default", "name": "my-opex", "reconcileID": "7578ca2f-2bfe-4e4b-ba1c-3d43ff366ddf"}
2023-08-03T23:28:21+08:00  INFO  Обновлено состояние ресурса CRD.  {"controller": "examplea", "controllerGroup": "example.linkinstars.com", "controllerKind": "ExampleA", "ExampleA": {"name":"my-opex","namespace":"default"}, "namespace": "default", "name": "my-opex", "reconcileID": "7578ca2f-2bfe-4e4b-ba1c-3d43ff366ddf", "status": false}
2023-08-03T23:28:21+08:00  INFO  Начните вызывать метод Reconcile  {"controller": "examplea", "controllerGroup": "example.linkinstars.com", "controllerKind": "ExampleA", "ExampleA": {"name":"my-opex","namespace":"default"}, "namespace": "default", "name": "my-opex", "reconcileID": "e37ac2a6-a769-491c-9d73-e89ea8e43f23"}
2023-08-03T23:28:21+08:00  INFO  Обновлено состояние ресурса CRD.  {"controller": "examplea", "controllerGroup": "example.linkinstars.com", "controllerKind": "ExampleA", "ExampleA": {"name":"my-opex","namespace":"default"}, "namespace": "default", "name": "my-opex", "reconcileID": "e37ac2a6-a769-491c-9d73-e89ea8e43f23", "status": false}

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

Если вам нужно сначала переработать и удалить соответствующие ресурсы, сначала kubectl delete -f Удалите все созданные тесты. Затем выполните его напрямую make uninstall Вот и все.

для руля

В Интернете много для руля и Operator изаналогия, на самом деле Я Думаю, эти два направления разные. шлем Это значит собрать все необходимые ресурсы для развертывания вместе, чтобы облегчить упаковку. когдаран CRD Подобные функции также могут быть реализованы и являются более мощными. но helm Ресурс уже есть в коллекции, в большинстве случаев развертывается. k8s Предоставить из deploy/service/… Ожидания достаточно. Самое главное, руль Не могу контролировать цикл, контроллер. Вот и все Operator из души.

Подвести итог

Я думаю, многие люди узнают Operator Сложный или трудный в использовании, большинство людей этого не понимают. k8s Внутренние принципы приводят к из. Если ты его очень хорошо знаешь Controller Manager из принципа и для, до контура управления, по сути Operator Он был очень хорошо упакован. Дизайн такой Думаю, причина в том, что очень удобно расширяться.

kubebuilder Есть еще один официальный CronJob из учебника, позволит вам быстро использовать Operator реализовать CronJob из Функция。Я Новичкам все еще может быть немного сложно думать для, но после того, как вы прочтете эту статью и попрактикуетесь в ней, я предлагаю вам поиграть, и понять будет легче.

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose