Tabla de contenido
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.