[k8s] operator-sdk(Go)로 memcahce 오퍼레이터 구축하기 - 1
[k8s] operator-sdk(Go)로 memcahce 오퍼레이터 구축하기 - 1
Quickstart for Go-based Operators | Operator SDK Quickstart for Go-based OperatorsA simple set of instructions to set up and run a Go-based operator.sdk.operatorframework.io 필수 체크 요소 - cluster-admin 권한이 있어야함 - example.com 이
sua-tech.tistory.com
Operator 배포와 CRD등록까진 했다
api/v1alpha1/memcached_types.go 수정하기
spec에 size 부분을 추가하고 status에 nodes를 추가한다
// 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
Foo string `json:"foo,omitempty"`
Size int32 `json:"size"` // sua added
}
// 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"`
}
- api 수정을 했다면 make install 작업이 필요하다
make 수행 : CRD와 관련된 코드 다시 생성
[root@tech7 memcached-operator]# make
/root/k8s/Operator/memcached-operator/bin/controller-gen-v0.14.0 rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
/root/k8s/Operator/memcached-operator/bin/controller-gen-v0.14.0 object:headerFile="hack/boilerplate.go.txt" paths="./..."
go fmt ./...
api/v1alpha1/memcached_types.go
go vet ./...
go: downloading github.com/onsi/gomega v1.30.0
go build -o bin/manager cmd/main.go
Controller 수정하기
경로: memcached-operator/internal/controller
파일: memcached_controller.go
memcached_controller.go
- import
- struct MemcachedReconciler
- client / runtime.schema
- func : Reconcile
- k8s 에서 CR (Memcached) 리소스를 생성, 수정, 삭제 할때마다 호출이 된다
- size 필드를 읽고 인스턴스 수를 맞추는 로직을 추가할 예정
- func : SetupWithManager
[root@tech7 controller]# cat memcached_controller.go
package controller
import (
"context"
"fmt" // fmt 패키지를 추가
"github.com/go-logr/logr" // logr 패키지 import
"k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log" // log 패키지 import
cachev1alpha1 "github.com/example/memcached-operator/api/v1alpha1"
)
// MemcachedReconciler reconciles a Memcached object
type MemcachedReconciler struct {
client.Client
Scheme *runtime.Scheme
Log logr.Logger // logr.Logger 타입으로 정의
}
//+kubebuilder:rbac:groups=cache.example.com,resources=memcacheds,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=cache.example.com,resources=memcacheds/status,verbs=get;update;patch
//+kubebuilder:rbac:groups=cache.example.com,resources=memcacheds/finalizers,verbs=update
// Reconcile is part of the main kubernetes reconciliation loop which aims to
// move the current state of the cluster closer to the desired state.
// TODO(user): Modify the Reconcile function to compare the state specified by
// the Memcached object against the actual cluster state, and then
// perform operations to make the cluster state reflect the state specified by
// the user.
//
// For more details, check Reconcile and its Result here:
// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.17.3/pkg/reconcile
func (r *MemcachedReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
log := log.FromContext(ctx) // 컨텍스트에서 로그 가져오기
// 1. Memcached 인스턴스 가져오기
var memcached cachev1alpha1.Memcached
if err := r.Get(ctx, req.NamespacedName, &memcached); err != nil {
log.Error(err, "unable to fetch Memcached")
return ctrl.Result{}, client.IgnoreNotFound(err)
}
// 2. 현재 Memcached 인스턴스 수와 Size 비교하여 조정
desiredSize := memcached.Spec.Size
currentSize := memcached.Status.AvailableReplicas
// 상태 비교 후 생성 및 삭제 처리
if desiredSize > currentSize {
// 인스턴스 생성 로직
log.Info("Desired size is greater than current size, creating new instances")
if err := r.createMemcachedInstances(ctx, &memcached, desiredSize-currentSize); err != nil {
log.Error(err, "unable to create new Memcached instances")
return ctrl.Result{}, err
}
} else if desiredSize < currentSize {
// 인스턴스 삭제 로직
log.Info("Desired size is less than current size, deleting extra instances")
if err := r.deleteMemcachedInstances(ctx, &memcached, currentSize-desiredSize); err != nil {
log.Error(err, "unable to delete extra Memcached instances")
return ctrl.Result{}, err
}
} else {
log.Info("Desired size matches current size, no changes needed")
}
return ctrl.Result{}, nil
}
// SetupWithManager sets up the controller with the Manager.
func (r *MemcachedReconciler) SetupWithManager(mgr ctrl.Manager) error {
r.Log = ctrl.Log.WithName("controllers").WithName("Memcached") // 로깅 설정
return ctrl.NewControllerManagedBy(mgr).
For(&cachev1alpha1.Memcached{}).
Complete(r)
}
// Memcached 인스턴스 생성
func (r *MemcachedReconciler) createMemcachedInstances(ctx context.Context, memcached *cachev1alpha1.Memcached, numInstances int32) error {
log := log.FromContext(ctx)
// StatefulSet 생성 로직
// 실제 Memcached StatefulSet 생성하는 코드가 들어갑니다.
for i := int32(0); i < numInstances; i++ {
// StatefulSet을 생성하는 로직 작성
log.Info(fmt.Sprintf("Creating Memcached instance %d", i+1))
// 예시: StatefulSet을 생성하는 코드
// 실제로는 여기서 clientset을 사용해 StatefulSet을 생성합니다.
}
return nil
}
// Memcached 인스턴스 삭제
func (r *MemcachedReconciler) deleteMemcachedInstances(ctx context.Context, memcached *cachev1alpha1.Memcached, numInstances int32) error {
log := log.FromContext(ctx)
// StatefulSet 삭제 로직
for i := int32(0); i < numInstances; i++ {
// StatefulSet 삭제하는 로직 작성
log.Info(fmt.Sprintf("Deleting Memcached instance %d", i+1))
// 예시: StatefulSet 삭제 코드
// 실제로는 여기서 clientset을 사용해 StatefulSet을 삭제합니다.
}
return nil
}
make run 으로 Operator를 실행한다
[root@tech7 memcached-operator]# make run
/root/k8s/Operator/memcached-operator/bin/controller-gen-v0.14.0 rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
/root/k8s/Operator/memcached-operator/bin/controller-gen-v0.14.0 object:headerFile="hack/boilerplate.go.txt" paths="./..."
go fmt ./...
internal/controller/memcached_controller.go
go vet ./...
go run ./cmd/main.go
2024-11-14T19:08:30+09:00 INFO setup starting manager
2024-11-14T19:08:30+09:00 INFO controller-runtime.metrics Starting metrics server
2024-11-14T19:08:30+09:00 INFO starting server {"kind": "health probe", "addr": "[::]:8081"}
2024-11-14T19:08:30+09:00 INFO controller-runtime.metrics Serving metrics server {"bindAddress": ":8080", "secure": false}
2024-11-14T19:08:30+09:00 INFO Starting EventSource {"controller": "memcached", "controllerGroup": "cache.example.com", "controllerKind": "Memcached", "source": "kind source: *v1alpha1.Memcached"}
2024-11-14T19:08:30+09:00 INFO Starting Controller {"controller": "memcached", "controllerGroup": "cache.example.com", "controllerKind": "Memcached"}
2024-11-14T19:08:30+09:00 INFO Starting workers {"controller": "memcached", "controllerGroup": "cache.example.com", "controllerKind": "Memcached", "worker count": 1}
Memcached 리소스를 정의하는 파일 등록
경로 : memcached-operator/config/samples
파일 : cache_v1alpha1_memcached.yaml
[root@tech7 samples]# cat cache_v1alpha1_memcached.yaml
apiVersion: cache.example.com/v1alpha1
kind: Memcached
metadata:
labels:
app.kubernetes.io/name: memcached-operator
app.kubernetes.io/managed-by: kustomize
name: memcached-sample
spec:
size : 2
# TODO(user): Add fields here
k apply -f cache_v1alpha1_memcached.yaml
하면 reconcile 함수가 구동되어 아래와 같은 로그를 operator 에 남긴다
2024-11-14T19:14:01+09:00 INFO Desired size is greater than current size, creating new instances {"controller": "memcached", "controllerGroup": "cache.example.com", "controllerKind": "Memcached", "Memcached": {"name":"memcached-sample","namespace":"default"}, "namespace": "default", "name": "memcached-sample", "reconcileID": "efa97613-c682-4967-a8e0-2a6c37d54d3d"}
2024-11-14T19:14:01+09:00 INFO Creating Memcached instance 1 {"controller": "memcached", "controllerGroup": "cache.example.com", "controllerKind": "Memcached", "Memcached": {"name":"memcached-sample","namespace":"default"}, "namespace": "default", "name": "memcached-sample", "reconcileID": "efa97613-c682-4967-a8e0-2a6c37d54d3d"}
2024-11-14T19:14:01+09:00 INFO Creating Memcached instance 2 {"controller": "memcached", "controllerGroup": "cache.example.com", "controllerKind": "Memcached", "Memcached": {"name":"memcached-sample","namespace":"default"}, "namespace": "default", "name": "memcached-sample", "reconcileID": "efa97613-c682-4967-a8e0-2a6c37d54d3d"}
'k8s' 카테고리의 다른 글
[k8s] operator-sdk(Go)로 memcahce 오퍼레이터 구축하기 - 3 (요약) (1) | 2024.11.18 |
---|---|
[k8s] operator-sdk(Go)로 memcahce 오퍼레이터 구축하기 - 1 (0) | 2024.11.14 |
[k8s] CRD->CR->Operator(kopf python) 만들기 (0) | 2024.08.27 |
[K8s] ClusterIP vs Headless vs Nodeport vs LoadBalancer ( ft. Ingress) (0) | 2024.08.22 |
centos 9 - k8s 구성하기 (master, worker01,worker02) (3) | 2024.08.02 |