1-Quick Start

2-Memcached-Operator
kubebuilder init --domain my.domain --repo my.domain/memcached-operatorCreate a api
kubebuilder create api --group cache --version v1alpha1 --kind Memcached --image=memcached:1.4.36-alpine --image-container-command="memcached,-m=64,-o,modern,-v" --image-container-port="11211" --run-as-user="1001" --plugins="deploy-image/v1-alpha" --make=false
ๅฝไปคๆ็น้ฟ:
--group cache --version v1alpha1 --kind Memcached:- ่ฟไธช
API็ๅฎๅ จ้ๅฎๅ็งฐๆฏ:cache.my.domain/v1alpha1?
- ่ฟไธช
--image=memcached:1.4.36-alpine: ๆๅฎ่ฆ้ๅฎ็ๅฎนๅจ--image-container-command="memcached,-m=64,-o,modern,-v": ๅฎนๅจ็ๅฏๅจๅฝไปค.--image-container-port="11211": ็ซฏๅฃ--run-as-user="1001"--make=false: ็ฆๆญขไฝฟ็จmakeๅฝไปค๏ผ่ฟๆ ทๅฏไปฅๅจ็ๆไปฃ็ ไนๅๆๅจๆฃๆฅๅไฟฎๆน
่ฟ้็จไบ ๆไปถ --plugins="deploy-image/v1-alpha", ไผๅธฎๆไปฌๆ นๆฎไธ้ข็้
็ฝฎ่ชๅจ็ๆ:
controllerไปฃ็ manage.yamlไธญ่ฟไผๅ ๅซๅฏนๅบ็Deployment
2-1 API Scehma
ไธ้ขๅฐฑๆฏ็่งฃ่ฟไบไปฃ็ .
FROM: api/v1alpha1/memcached_types.go
// MemcachedSpec defines the desired state of Memcached
type MemcachedSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file
// Size defines the number of Memcached instances
// The following markers will use OpenAPI v3 schema to validate the value
// More info: https://book.kubebuilder.io/reference/markers/crd-validation.html
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=3
// +kubebuilder:validation:ExclusiveMaximum=false
Size int32 `json:"size,omitempty"`
// Port defines the port that will be used to init the container with the image
ContainerPort int32 `json:"containerPort,omitempty"`
}
// MemcachedStatus defines the observed state of Memcached
type MemcachedStatus struct {
// Represents the observations of a Memcached's current state.
// Memcached.status.conditions.type are: "Available", "Progressing", and "Degraded"
// Memcached.status.conditions.status are one of True, False, Unknown.
// Memcached.status.conditions.reason the value should be a CamelCase string and producers of specific
// condition types may define expected values and meanings for this field, and whether the values
// are considered a guaranteed API.
// Memcached.status.conditions.Message is a human readable message indicating details about the transition.
// For further information see: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`
}
-
MemacchedSpec: ๆไปฌ้่ฆ็ฎก็้จๅ, ๅ่ฏ k8sๆไปฌๆๅพ ็็ถๆ- ่ชๅฎไน่ตๆบ็
CR้จๅ, Custom Resource - ๅฎไนไบ็จๆทๆๆๅฏไปฅ่ฎพ็ฝฎ็้้กน
- ็ฎๅๆฅ่ฏด๏ผ ่ฟ้ๆฏๆไปฌๅ่ฏ
k8s, ๆไปฌ็memcached้่ฆ้ฟๆไปไนๆ ทๅญ
- ่ชๅฎไน่ตๆบ็
-
Status Condition:- ๆ ๅๅ็
API, ่กจ่พพๅฝๅ้็พคไธญ็ ็ถๆ - ๆฏๅฝ่ตๆบ็ ็ถๆๅ็ๅๅ็ๆถๅ, (ๅๅปบ๏ผๆดๆฐ๏ผๆ่
ๅบ้),
Controllerๅฐฑไผๆดๆฐ่ฟไบๆกไปถ
- ๆ ๅๅ็
-
่
Memcachedๅๆถๅ ๅซ่ฟ2ไธช ็ปๆไฝ๏ผๅฐฑๆฏ่ฎก็ฎๅบ ๅฝๅ็็ถๆๅ ๆๆ็ถๆ็Delta
ๆไธไบๆฏ่พ trick ็ไธ่ฅฟ, markers, ไธ้ข็ๆณจ้: +kubebuilder:validation:Minimum=1
- ไธ็ง ๅฃฐๆๅผ็็บฆๆๆๆฎต, ่ฟไธชๆถๅไผๅจ
applyไนๅๆ ก้ช่ฟไธชๅผๅฟ ้กป>=1 - ็ๆ็ไฟฎๆนไผๅจไธญ
config/crd/basesไธญ
ๆฏๆฌกไฟฎๆน Api-Spec ๅ๏ผ้่ฆ make generate: ๆฅๅๆญฅๆดๆฐ CRD ไธญ็ๅ
ๅฎน.
ไธ่ฌๅนณๆถ็demoไผๆพๅจ `config/samples ไธ้ข, ไพๅฆ
apiVersion: cache.example.com/v1alpha1
kind: Memcached
metadata:
name: memcached-sample
spec:
# TODO(user): edit the following value to ensure the number
# of Pods/Instances your Operand must have on cluster
size: 1
# TODO(user): edit the following value to ensure the container has the right port to be initialized
containerPort: 112112-2 Controller
Reconciliation : ๆฏ k8s controller-loop ๆจกๅผไธญ็ๆ ธๅฟๆฆๅฟต.
็ฎ็:
- ็กฎไฟ่ตๆบ็ๅฎ้ ็ถๆไธๆๆ็ถๆ็ๅๆญฅ
- ๅบไบๅตๅ ฅ็ไธๅก้ป่พๅค็่ตๆบ็ถๆ
ๅพช็ฏ็นๆง:
Reconciliationๅฝๆฐไผไธๆญๆง่ก๏ผ็ดๅฐๆๆ็ๆกไปถ้ฝ็ฌฆๅ้ขๆ
ไธ้ข็ไผชไปฃ็ :
reconcile App {
// Check if a Deployment for the app exists, if not, create one
// If there's an error, then restart from the beginning of the reconcile
if err != nil {
return reconcile.Result{}, err
}
// Check if a Service for the app exists, if not, create one
// If there's an error, then restart from the beginning of the reconcile
if err != nil {
return reconcile.Result{}, err
}
// Look for Database CR/CRD
// Check the Database Deployment's replicas size
// If deployment.replicas size doesn't match cr.size, then update it
// Then, restart from the beginning of the reconcile. For example, by returning `reconcile.Result{Requeue: true}, nil`.
if err != nil {
return reconcile.Result{Requeue: true}, nil
}
...
// If at the end of the loop:
// Everything was executed successfully, and the reconcile can stop
return reconcile.Result{}, nil
}
ไธไธชๆ ๅ็ๆต็จ:
- ๆฃๆฅ
Developmentๆฏๅฆๅญๅจ ; - ๆฃๆฅ
Serviceๆฏๅฆๅญๅจ ; ...็ดๅฐๆๆ็ไบๆ ้ฝๆฃๆฅๅฎๆฏ ;
2-3 Return Options
return ctrl.Result{}, err- ็จ้: ๅฝ้ๅฐ้่ฏฏ็ๆถๅ๏ผ้่ฆ็ซๅป้่ฏ๏ผ่ฟๅ่ฟไธช
- ่กไธบ: ๆงๅถๅจไผ่ฎฐๅฝๅฝๅ็้่ฏฏ, ๅจ็ญๆ็ๅปถ่ฟๅ๏ผ่ชๅจ้ๆฐ่งฆๅ
reconciliation - ๅบๆฏ: ไธดๆถๆง็้่ฏฏ, ็ฝ็ป้ฎ้ขๆ่ ่ตๆบๆๆถไธๅฏ็จ
return ctrl.Result{Requeue: true}, nil- ็จ้: ๅฝ้่ฆ็ซๅณ้ๆฐๆง่ก
reconciliation, ไฝๆฏๆฒกๆ้่ฏฏ็ซๅณๅ็ๆถๅ - ๅบๆฏ: ้ๅ่ฟ็ปญๅคๆฌก่ฐๆดๆ่ ๆฃๆฅ๏ผๆฏๅฆ่ฏดๆไปฌ่ฆ็ญๅพ ๆไธชๆกไปถๆปก่ถณ็ๆถๅไฝฟ็จ
return ctrl.Result{}, nil- ็จ้: ๅฝ
reconciliationๆๅๅฎๆ, ่ไธๆๆถไธ้่ฆfurther action็ๆถๅไฝฟ็จ - ๅบๆฏ: ่ตๆบ่พพๅฐๆๆ็ถๆ๏ผๆ ้่ฟไธๆญฅๆไฝ
return ctrl.Result{RequeueAfter: nextRun.Sub(r.Now())}, nil- ็จ้: ๅปถ่ฟ้ๆฐ
Reconcile, ๅจๆๅฎ็ๆถๅไนๅ้ๆฐๆง่กreconciliation - ๅบๆฏ: ้่ฆๅฎๆ็ๆฃๆฅๆ่ ๆง่ก, ไพๅฆ่ฝฎ่ฏขๅค้จ็่ตๆบ็ถๆ