controller-runtime construye el entorno de desarrollo del operador

Tabla de contenido

estructura basica

Inyectar CRD


estructura basica

Primero descargue el go pkg correspondiente

go get -u sigs.k8s.io/controller-runtime

A continuación, debe crear el controlador y el administrador.

La esencia de Operator es un modo de programación de cola reentrante, mientras que Manager se puede usar para administrar Controller y Admission Webhook, incluido el cliente, la memoria caché y el esquema para acceder a objetos de recursos, lo que proporciona un mecanismo simple de inyección de dependencia y un mecanismo de procesamiento de señales para una espera de apagado ordenada.

 Ver código de muestra en documentos oficiales

opsController.go

package kube

import (
	"context"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/controller-runtime/pkg/reconcile"
)

type OpsController struct {
	client.Client
}

func NewOpsController() *OpsController {
	return &OpsController{}
}

func (a *OpsController) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {
	return reconcile.Result{}, nil
}

func (a *OpsController) InjectClient(c client.Client) error {
	a.Client = c
	return nil
}

Primero escuche los recursos oficiales, como Ingress (que debe especificarse en el Administrador más adelante), así que complete la función de sintonización como

func (a *OpsController) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {
	resource := &v1.Ingress{}
	a.Client.Get(ctx, req.NamespacedName, resource)
	fmt.Println(resource)
	return reconcile.Result{}, nil
}

Cuando se envía un nuevo objeto Ingress a Apiserver, la estructura completa se imprimirá en la consola.

package kube

import (
	v1 "k8s.io/api/networking/v1"
	"os"

	"sigs.k8s.io/controller-runtime/pkg/builder"
	"sigs.k8s.io/controller-runtime/pkg/client/config"

	logf "sigs.k8s.io/controller-runtime/pkg/log"
	"sigs.k8s.io/controller-runtime/pkg/log/zap"
	"sigs.k8s.io/controller-runtime/pkg/manager"
	"sigs.k8s.io/controller-runtime/pkg/manager/signals"
)

func InitManager() {
	logf.SetLogger(zap.New())

	var log = logf.Log.WithName("builder-examples")

	mgr, err := manager.New(config.GetConfigOrDie(), manager.Options{})
	if err != nil {
		log.Error(err, "could not create manager")
		os.Exit(1)
	}

	err = builder.
		ControllerManagedBy(mgr).  // Create the ControllerManagedBy
		For(&v1.Ingress{}). // ReplicaSet is the Application API
		Complete(NewOpsController())
	if err != nil {
		log.Error(err, "could not create controller")
		os.Exit(1)
	}

	if err := mgr.Start(signals.SetupSignalHandler()); err != nil {
		log.Error(err, "could not start manager")
		os.Exit(1)
	}
}

En este código, el derecho de comando del Ingreso se asigna al Controlador recién creado (que puede ser administrado por varios Controladores al mismo tiempo) y se inicia el Administrador, que en realidad es la función de entrada del operador.

Simplemente envíe un objeto Ingress, la salida de la consola se imprime y el final ha terminado.

Hasta ahora, hemos completado el proceso de llamada más básico de un Operador.

Inyectar CRD

Operador=CRD+Controlador+Webhook

En un entorno real, a menudo se requieren recursos altamente personalizados para completar el control de procesos complejos y la orientación de expectativas.

Por tanto, este apartado es para generar CRD y completar el seguimiento y control de CR.

También en el código fuente, puede encontrar un fragmento de código de muestra , que es una demostración de la implementación anterior.

Entre ellas, se completan las funciones de declaración CRD, copia profunda y registro expuesto externamente.

También hay un código de implementación para esto en el generador de código publicado oficialmente por Kubernetes .

De acuerdo con esta demostración, se deben completar algunos campos preestablecidos del CRD para crear el objeto de escucha del administrador y la operación de deserialización cuando el controlador llama a client-go.

Antes de iniciar Manager, debe registrar el CRD en Scheme y agregar el controlador de control y asignación al CRD.

	err = v1.AddToScheme(mgr.GetScheme())
	if err != nil {
		log.Error(err, "could not register scheme")
	}

	err = builder.
		ControllerManagedBy(mgr). // Create the ControllerManagedBy
		For(&v1.Operation{}).     // ReplicaSet is the Application API
		Complete(NewOpsController())
	if err != nil {
		log.Error(err, "could not create controller")
		os.Exit(1)
	}

Modifique la función de ajuste para imprimir el objeto activado en la consola.

func (a *OpsController) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {
	resource := &v1.Operation{}
	err := a.Client.Get(ctx, req.NamespacedName, resource)
	if err != nil {
		return reconcile.Result{}, err
	}
	fmt.Println(resource)
	return reconcile.Result{}, nil
}

Refiriéndose al documento oficial  , debe editar un yaml y aplicarlo. Aquí también está la declaración del campo, principalmente para enviar el objeto al Apiserver.

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  # 名字必需与下面的 spec 字段匹配,并且格式为 '<名称的复数形式>.<组名>'
  name: operations.extensions.octoboy.com
spec:
  # 组名称,用于 REST API: /apis/<组>/<版本>
  group: extensions.octoboy.com
  # 列举此 CustomResourceDefinition 所支持的版本
  versions:
    - name: v1
      # 每个版本都可以通过 served 标志来独立启用或禁止
      served: true
      # 其中一个且只有一个版本必需被标记为存储版本
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                action:
                  type: string
  # 可以是 Namespaced 或 Cluster
  scope: Namespaced
  names:
    # 名称的复数形式,用于 URL:/apis/<组>/<版本>/<名称的复数形式>
    plural: operations
    # 名称的单数形式,作为命令行使用时和显示时的别名
    singular: operation
    # kind 通常是单数形式的驼峰命名(CamelCased)形式。你的资源清单会使用这一形式。
    kind: Operation
    # shortNames 允许你在命令行使用较短的字符串来匹配资源
    shortNames:
      - ops

 Luego inicie nuestro Operador y simplemente escriba un objeto yaml.

apiVersion: extensions.octoboy.com/v1
kind: Operation
metadata:
  name: myops
  namespace: default
spec:
  action: "restart"

 Mientras aplica, observe la salida de la consola

&{ {Operation extensions.octoboy.com/v1} {myops default 1344e481-4db4-461d-8d8d-b07713a76236 3927679 1 2023-03-07 14:21:09 +0800 CST <nil> <nil> map[] map[ kubectl.kubernetes.io/last-applied-configuration:{"apiVersion":"extensions.octoboy.com/v1","kind":"Operation","metadata":{"anotaciones":{},"name" :"myops","namespace":"default"},"spec":{"action":"restart"}} ] [] [] [{kubectl
-client-side-apply Update extensions.octoboy.com/v1 2023-03-07 14:21:09 +0800 CST FieldsV1 {"f:metadatos":{"f:anotaciones":{".":{},"f:kubectl.kubernetes.io/last-applied-configuration ":{}}},"f:spec":{".":{},"f:acción":{}}} }]} {} {0001-01-01 00:00:00 +0000 UTC}}

Hasta ahora, se ha creado un controlador de operador simple a través del tiempo de ejecución del controlador.

Supongo que te gusta

Origin blog.csdn.net/kingu_crimson/article/details/129366950
Recomendado
Clasificación