21. Versionierte API
• Versions-Nummern und Level
• Start mit v1alpha1, v1alpha2, ...
• Bei zunehmender Stabilität und Tests mit v1beta1
• Stabile Versionen ohne Level, wie v1, v2, ...
24. De
fi
nition in YAML – Spezi
fi
kation
versions:
- name: v1alpha1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
....
status:
...
25. De
fi
nition in Go – Rahmen
package v1alpha1
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
type Mechanic struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata"`
Spec MechanicSpec `json:"spec"`
Status MechanicStatus `json:"status"`
}
26. De
fi
nition in Go – Spezi
fi
kation
package v1alpha1
import corev1 "k8s.io/api/core/v1"
type Microservice struct {
Scaling MicroserviceScaling `json:"scaling"`
Containers []Container `json:"containers"`
Volumes []corev1.Volume `json:"volumes,omitempty"`
}
...
type MechanicSpec struct {
Microservice Microservice `json:"microservice"`
Dependencies Dependencies `json:"dependencies"`
Network Network `json:"network"`
}
27. DeepCopy wird benötigt
func (in *Mechanic) DeepCopyInto(out *Mechanic) {
out.TypeMeta = in.TypeMeta
out.ObjectMeta = in.ObjectMeta
out.Spec = MechanicSpec{...}
}
func (in *Mechanic) DeepCopyObject() runtime.Object {
out := Mechanic{}
in.DeepCopyInto(&out)
return &out
}
38. Aufgaben
• Kon
fi
guration
• Informer erzeugen und Handler registrieren
• Ein bis N Informer im Hintergrund arbeiten lassen
• Auf Callbacks entsprechend reagieren
39. De
fi
nition
package mechanic
type Mechanic struct {
con
fi
g *rest.Con
fi
g
client kubernetes.Interface
namespace string
mif mechanicv1alpha1.MechanicInterface
minfo cache.SharedIndexInformer
}
40. Den Controller erzeugen
package mechanic
func New(con
fi
g *rest.Con
fi
g, namespace string) (*Mechanic, error) {
m := &Mechanic{...}
namespaceableMIF, err := mechanicv1alpha1.NewForCon
fi
g(m.con
fi
g)
...
m.mif = namespaceableMIF.Namespace(namespace)
client, err := kubernetes.NewForCon
fi
g(con
fi
g)
...
m.client = client
m.minfo = mechanicv1alpha1.NewMechanicInformerWithInterface(m.mif).Informer()
return m, nil
}
41. Auf geht es zur Arbeit
package mechanic
func (m *Mechanic) Run(ctx context.Context) {
// Add handler functions to informer.
m.minfo.AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: m.addMechanicHandler,
UpdateFunc: m.updateMechanicHandler,
DeleteFunc: m.deleteMechanicHandler,
})
// Let it work.
go m.minfo.Run(wait.NeverStop)
// Run based on context.
select {
case <-ctx.Done:
}
}
44. Externe Abhängigkeiten abstrahieren
• Struktur mit Name, Typ als String und Schlüssel-Wert-
Parametern
• Iteration über die Abhängigkeiten
• Instanzierung auf Basis des Typs
• Parameter übergeben
• Aktion ausführen
46. Hauptprogramm
package main
func main() {
// Read
fl
ags and con
fi
guration.
...
con
fi
g, err := clientcmd.BuildCon
fi
gFromFlags(masterURL, kubecon
fi
g)
...
// Run mechanic.
m, err := mechanic.New(con
fi
g, namespace)
...
mechanicv1alpha1.AddToScheme(scheme.Scheme)
m.Run(context.Background())
}
48. Kubebuilder
• Manuelle Schritte zeigen die prinzipielle Arbeitsweise
• Kubebuilder unterstützt dies als Framework
• Basierend auf API Quellen mit Kommentaren wird
Standard-Code generiert
• Anstatt Handler werden Reconcile-Funktionen mit
Requests erzeugt und später aufgerufen
• Generator-Aufrufe sind idempotent
50. Zusammenfassung
• Initial ein komplexer Weg zur Installation und dem Betrieb
von Anwendungssystemen im Netz
• Stellt komfortable Möglichkeiten aber auch gewünschte
Grenzen für die Installation von Microservices zur
Verfügung
• Keine Abweichung der Kon
fi
gurationssprache der
Anwendungen und der Anwendungsinstallation