k8s operator 만들기
Require
- k8s 버전의 이해
- golang
Link
Resource
Custom Resource만드는 방식으로는 2가지 방식이 있습니다만, 최근에는 CRD 방식으로 대부분 구현합니다.
- 애그리게이트 API
- CRD

동작방식
기본적으로 k8s resource를 만들면 etcd에 저장 한 후 controller가 관리합니다. 따라서 사용자가 새로운 리소스를 생성한다고 하면, 새로운 리소스를 처리하는 contorller가 필요합니다.
먼저 우리는 k8s에 새로운 리소스를 등록해주어야 합니다.
k8s에 버전 형상을 기억하고 버전을 지정하여 생성하여줍니다.
사용자 리소스 정의
CustomResource
apiVersion: flights.com/v1
kind: FlightTicket
metadata:
name: my-flight-ticket
spec:
from: Mumbai
to: London
number: 2
CustomResourceDefinition
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: flighttickets.flights.com
spec:
scope: Namespced
group: flights.com # 사용자 지정 리소스에 apiVersion
names:
kind: FlightTicket
singular: flightticket
plural: flighttickets
shortnames:
- ft
versions:
- name: v1
served: true
storage: true
schema: #사양 섹션에서 지정할 수 있는 모든 매개 변수를 정의
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
from:
type: string
to:
type: string
number:
type: integer
minimum: 1
maximum: 10
컨트롤러 구조

Infomer는 클러스터와 Controller사이의 중개자 역할로 지정한 리소스를 큐에 넣어주는 역할을 합니다. 컨트롤러는 그 큐에서 이벤트들을 받아 처리하면 됩니다.
컨트롤러를 만들기 위해서는 제공되는 샘플컨트롤러를 복사하여 참조 및 수정하여 빌드 후 올리는 방법이 있습니다. 이 컨트롤러에 좀 더 복잡한 로직을 넣을 수 있는것이 operator입니다.

Operator-SDK
Require
- git
- go 1.18
Install
Install guide를 보면서 인스톨을 진행합니다.
Window는 설치가 안됩니다.

Make Project Directory
mkdir $HOME/projects/monitor-operator
Init Project
operator-sdk init \
--domain=kyh0703.github.io \
--repo=github.com/kyh0703/memcached-operator
/usr/local/go/src/net/cgo_linux.go:13:8: no such package located Error: not all generators ran successfully run `controller-gen object:headerFile=hack/boilerplate.go.txt paths=./... -w` to see all available markers, or `controller-gen object:headerFile=hack/boilerplate.go.txt paths=./... -h` for usage make: *** [Makefile:95: generate] Error 1 Error: failed to create API: unable to run post-scaffold tasks of "base.go.kubebuilder.io/v3": 위와 같은 에러가 뜨면.. 당황하지말고 gcc가 설치되어있는지 확인!
vertify Project File
domain: kyh0703.github.io
layout:
- go.kubebuilder.io/v3
plugins:
manifests.sdk.operatorframework.io/v2: {}
scorecard.sdk.operatorframework.io/v2: {}
projectName: monitor-operator
repo: github.com/kyh0703/k8s-custom-controller
version: "3"
CRDS
operator-sdk create api --group=cache --version=v1alpha1 --kind=Memcached
api, controller폴더가 생깁니다.
modify api types file
/api/v1alpha1/*_types.go
사용할 필드를 정의하여 줍니다. make generate 명령어로 변경사항을 반영합니다.
// 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
// Foo is an example field of Memcached. Edit memcached_types.go to remove/update
Size string `json:"size,omitempty"`
}
// MemcachedStatus defines the observed state of Memcached
type MemcachedStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
Nodes []string `json:"nodes"`
}
Generating CRD manifests
$ make generate
$ make manifests
컨트롤러 정의
import (
...
appsv1 "k8s.io/api/apps/v1"
...
)
func (r *MemcachedReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&cachev1alpha1.Memcached{}).
Owns(&appsv1.Deployment{}).
WithOptions(controller.Options{
MaxConcurrentReconciles: 2,
}).Complete(r)
}
- NewControllerManagedBy: Controller Builder 생성
- For: 컨트롤러가 관찰하기 위한 우선적인 리소스를 특정한 후 이벤트에 대해
Reconcil을 요청함 - Owns: 컨트롤러가 관찰하기 위한 추가 리소스를 지정
- WithOption: 동시 사용 개수 등 다양한 옵션을 지정할 수 있음
구현
func (r *MemcachedReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
_ = log.FromContext(ctx)
// TODO(user): your logic here
return ctrl.Result{}, nil
}
Reconcile에서 이벤트 발생 시에 대한 코드를 구현합니다.
return
- With the error:
return ctrl.Result{}, err
- Without an error:
return ctrl.Result{Requeue: true}, nil
- Therefore, to stop the Reconcile, use:
return ctrl.Result{}, nil
- Reconcile again after X time:
return ctrl.Result{RequeueAfter: nextRun.Sub(r.Now())}, nil
Build
make install # crd install
make deploy # create deployment
make run # 실행
make run ENABLE_WEBHOOKS=false
make undeploy
make uninstall
댓글남기기