5.17. Operator SDK v0.1.0으로 마이그레이션
이 가이드에서는 Operator SDK v0.0.x를 사용하여 빌드된 Operator 프로젝트를 Operator SDK v0.1.0 에 필요한 프로젝트 구조로 마이그레이션하는 방법을 설명합니다.
Operator 프로젝트의 관련 스캐폴딩 및 테스트 툴을 포함하여 Operator SDK CLI 툴의 Red Hat 지원 버전은 더 이상 사용되지 않으며 향후 OpenShift Dedicated 릴리스에서 제거될 예정입니다. Red Hat은 현재 릴리스 라이프사이클 동안 이 기능에 대한 버그 수정 및 지원을 제공하지만 이 기능은 더 이상 개선 사항을 받지 않으며 향후 OpenShift Dedicated 릴리스에서 제거됩니다.
새 Operator 프로젝트를 생성하는 데 Red Hat 지원 버전의 Operator SDK는 권장되지 않습니다. 기존 Operator 프로젝트가 있는 Operator 작성자는 OpenShift Dedicated 4와 함께 릴리스된 Operator SDK CLI 툴 버전을 사용하여 프로젝트를 유지 관리하고 최신 버전의 OpenShift Dedicated를 대상으로 하는 Operator 릴리스를 생성할 수 있습니다.
Operator 프로젝트의 다음과 같은 관련 기본 이미지는 더 이상 사용되지 않습니다. 이러한 기본 이미지의 런타임 기능 및 구성 API는 버그 수정 및 CVE 문제를 해결하는 데 계속 지원됩니다.
- Ansible 기반 Operator 프로젝트의 기본 이미지
- Helm 기반 Operator 프로젝트의 기본 이미지
지원되지 않는 커뮤니티 유지 관리 버전에 대한 자세한 내용은 Operator SDK(Operator Framework) 를 참조하십시오.
프로젝트를 마이그레이션하는 데 권장되는 방법은 다음과 같습니다.
- 새 v0.1.0 프로젝트를 초기화합니다.
- 코드를 새 프로젝트에 복사합니다.
- v0.1.0에 대해 설명된 대로 새 프로젝트를 수정합니다.
이 가이드에서는 Operator SDK 의 예제 프로젝트인 memcached-operator
를 사용하여 마이그레이션 단계를 설명합니다. 사전 마이그레이션 예제는 각각 v0.0.7 memcached-operator 및 v0.1.0 memcached-operator 프로젝트 구조를 참조하십시오.
5.17.1. 새 Operator SDK v0.1.0 프로젝트 생성
Operator SDK v0.0.x 프로젝트의 이름을 바꾸고 새 v0.1.0 프로젝트를 생성합니다.
사전 요구 사항
- Operator SDK v0.1.0 CLI가 개발 워크스테이션에 설치됨
-
이전 버전의 Operator SDK를 사용하여 이전에 배포한 Memcached
-operator
프로젝트
프로세스
SDK 버전이 v0.1.0인지 확인합니다.
$ operator-sdk --version operator-sdk version 0.1.0
새 프로젝트를 생성합니다.
$ mkdir -p $GOPATH/src/github.com/example-inc/ $ cd $GOPATH/src/github.com/example-inc/ $ mv memcached-operator old-memcached-operator $ operator-sdk new memcached-operator --skip-git-init $ ls memcached-operator old-memcached-operator
이전 프로젝트에서
.git
을 복사합니다.$ cp -rf old-memcached-operator/.git memcached-operator/.git
5.17.2. pkg/apis에서 사용자 정의 유형 마이그레이션
프로젝트의 사용자 정의 유형을 업데이트된 Operator SDK v0.1.0 사용량으로 마이그레이션합니다.
사전 요구 사항
- Operator SDK v0.1.0 CLI가 개발 워크스테이션에 설치됨
-
이전 버전의 Operator SDK를 사용하여 이전에 배포한 Memcached
-operator
프로젝트 - Operator SDK v0.1.0을 사용하여 생성된 새 프로젝트
프로세스
사용자 지정 유형에 대한 스캐폴드 API를 생성합니다.
operator-sdk add api --api-version=<apiversion> --kind=<kind
>를 사용하여 새 프로젝트에서 CR(사용자 정의 리소스)의 API를 생성합니다.$ cd memcached-operator $ operator-sdk add api --api-version=cache.example.com/v1alpha1 --kind=Memcached $ tree pkg/apis pkg/apis/ ├── addtoscheme_cache_v1alpha1.go ├── apis.go └── cache └── v1alpha1 ├── doc.go ├── memcached_types.go ├── register.go └── zz_generated.deepcopy.go
-
이전 프로젝트에서 정의한 만큼 사용자 지정 유형에 대해 이전 명령을 반복합니다. 각 유형은 파일
pkg/apis/ /<version>/<kind>_types.go
파일에 정의됩니다.
유형의 내용을 복사합니다.
-
이전 프로젝트에서 새 프로젝트의
pkg/apis//<version>/types.go
파일의Spec
및Status
콘텐츠를 새 프로젝트의 pkg/apis/ /<version>/<kind>_types.go
파일로 복사합니다. 각 &
lt;kind>_types.go
파일에는init()
함수가 있습니다. 이 유형이 Manager의 스키마에 등록되므로 제거하지 마십시오.func init() { SchemeBuilder.Register(&Memcached{}, &MemcachedList{})
-
이전 프로젝트에서 새 프로젝트의
5.17.3. 조정 코드 마이그레이션
프로젝트의 조정 코드를 업데이트 Operator SDK v0.1.0 사용량으로 마이그레이션합니다.
사전 요구 사항
- Operator SDK v0.1.0 CLI가 개발 워크스테이션에 설치됨
-
이전 버전의 Operator SDK를 사용하여 이전에 배포한 Memcached
-operator
프로젝트 -
pkg/apis/
에서 마이그레이션된 사용자 정의 유형
프로세스
CR을 감시할 컨트롤러를 추가합니다.
v0.0.x 프로젝트에서 감시할 리소스가 이전에
cmd/<operator-name>/main.go에 정의되었습니다.
sdk.Watch("cache.example.com/v1alpha1", "Memcached", "default", time.Duration(5)*time.Second)
v0.1.0 프로젝트의 경우 리소스를 조사할 컨트롤러 를 정의해야 합니다.
operator-sdk add controller --api-version=<apiversion> --kind=<kind
>를 사용하여 CR 유형을 확인하는 컨트롤러를 추가합니다.$ operator-sdk add controller --api-version=cache.example.com/v1alpha1 --kind=Memcached $ tree pkg/controller pkg/controller/ ├── add_memcached.go ├── controller.go └── memcached └── memcached_controller.go
pkg/controller/<kind>/<kind>_controller.go 파일에서
add()
함수를 검사합니다.import ( cachev1alpha1 "github.com/example-inc/memcached-operator/pkg/apis/cache/v1alpha1" ... ) func add(mgr manager.Manager, r reconcile.Reconciler) error { c, err := controller.New("memcached-controller", mgr, controller.Options{Reconciler: r}) // Watch for changes to the primary resource Memcached err = c.Watch(&source.Kind{Type: &cachev1alpha1.Memcached{}}, &handler.EnqueueRequestForObject{}) // Watch for changes to the secondary resource pods and enqueue reconcile requests for the owner Memcached err = c.Watch(&source.Kind{Type: &corev1.Pod{}}, &handler.EnqueueRequestForOwner{ IsController: true, OwnerType: &cachev1alpha1.Memcached{}, }) }
두 번째
Watch()
를 제거하거나 이를 수정하여 CR이 소유한 보조 리소스 유형을 확인합니다.여러 리소스를 모니터링하면 애플리케이션과 관련된 여러 리소스에 대한 조정 루프를 트리거할 수 있습니다. 자세한 내용은 모니터링 및 이벤트 처리 설명서 및 Kubernetes 컨트롤러 규칙 설명서를 참조하십시오.
Operator에서 두 개 이상의 CR 유형을 모니터링하는 경우 애플리케이션에 따라 다음 중 하나를 수행할 수 있습니다.
기본 CR이 CR을 소유하는 경우 동일한 컨트롤러에서 보조 리소스로 확인하여 기본 리소스에 대한 조정 루프를 트리거합니다.
// Watch for changes to the primary resource Memcached err = c.Watch(&source.Kind{Type: &cachev1alpha1.Memcached{}}, &handler.EnqueueRequestForObject{}) // Watch for changes to the secondary resource AppService and enqueue reconcile requests for the owner Memcached err = c.Watch(&source.Kind{Type: &appv1alpha1.AppService{}}, &handler.EnqueueRequestForOwner{ IsController: true, OwnerType: &cachev1alpha1.Memcached{}, })
다른 CR과 독립적으로 CR을 감시하고 조정하는 새 컨트롤러를 추가합니다.
$ operator-sdk add controller --api-version=app.example.com/v1alpha1 --kind=AppService
// Watch for changes to the primary resource AppService err = c.Watch(&source.Kind{Type: &appv1alpha1.AppService{}}, &handler.EnqueueRequestForObject{})
pkg/stub/handler.go
에서 조정 코드를 복사하여 수정합니다.v0.1.0 프로젝트에서 조정 코드는 컨트롤러의
Reconcile()
메서드에 정의되어 있습니다. https://godoc.org/github.com/kubernetes-sigs/controller-runtime/pkg/reconcile#Reconciler 이는 이전 프로젝트의Handle()
기능과 유사합니다. 인수 및 반환 값의 차이점을 확인합니다.조정:
func (r *ReconcileMemcached) Reconcile(request reconcile.Request) (reconcile.Result, error)
처리:
func (h *Handler) Handle(ctx context.Context, event sdk.Event) error
sdk.Event
(오브젝트 사용)를 수신하는 대신Reconcile()
함수는 오브젝트를 조회하기 위한 요청 (이름
/네임
스 키)을 수신합니다.Reconcile()
함수가 오류를 반환하는 경우 컨트롤러는 요청을 다시 큐에 추가하고 다시시도합니다
. 오류가 반환되지 않으면 Result 에 따라 컨트롤러는요청을
다시 시도하거나, 즉시 재시도하거나, 지정된 기간 후에 재시도하지 않습니다.이전 프로젝트의
Handle()
함수의 코드를 컨트롤러의Reconcile()
함수의 기존 코드로 복사합니다. 개체를 조회하는Reconcile()
코드에서요청
및 삭제 여부를 확인하는 초기 섹션을 유지해야 합니다.import ( apierrors "k8s.io/apimachinery/pkg/api/errors" cachev1alpha1 "github.com/example-inc/memcached-operator/pkg/apis/cache/v1alpha1" ... ) func (r *ReconcileMemcached) Reconcile(request reconcile.Request) (reconcile.Result, error) { // Fetch the Memcached instance instance := &cachev1alpha1.Memcached{} err := r.client.Get(context.TODO() request.NamespacedName, instance) if err != nil { if apierrors.IsNotFound(err) { // Request object not found, could have been deleted after reconcile request. // Owned objects are automatically garbage collected. // Return and don't requeue return reconcile.Result{}, nil } // Error reading the object - requeue the request. return reconcile.Result{}, err } // Rest of your reconcile code goes here. ... }
조정 코드에서 반환 값을 변경합니다.
-
반환 에라타
를반환 reconcile.Result{}, err
로 바꿉니다. -
반환 nil
을반환 reconcile.Result{}, nil
로 바꿉니다.
-
컨트롤러에서 CR을 주기적으로 조정하려면
reconcile.Result
에 대해 RequeueAfter 필드를 설정할 수 있습니다. 이로 인해 컨트롤러에서 요청을 다시 큐에추가하고
원하는 기간 후에 조정을 트리거합니다. 기본값인0
은 다시 큐에 추가하지 않음을 의미합니다.reconcilePeriod := 30 * time.Second reconcileResult := reconcile.Result{RequeueAfter: reconcilePeriod} ... // Update the status err := r.client.Update(context.TODO(), memcached) if err != nil { log.Printf("failed to update memcached status: %v", err) return reconcileResult, err } return reconcileResult, nil
SDK 클라이언트(Create, Update, Delete, Get, List)에 대한 호출을 조정기의 클라이언트로 교체합니다.
자세한 내용은
operator-sdk
프로젝트의 아래 예제 및controller-runtime
클라이언트 API 설명서 를 참조하십시오.// Create dep := &appsv1.Deployment{...} err := sdk.Create(dep) // v0.0.1 err := r.client.Create(context.TODO(), dep) // Update err := sdk.Update(dep) // v0.0.1 err := r.client.Update(context.TODO(), dep) // Delete err := sdk.Delete(dep) // v0.0.1 err := r.client.Delete(context.TODO(), dep) // List podList := &corev1.PodList{} labelSelector := labels.SelectorFromSet(labelsForMemcached(memcached.Name)) listOps := &metav1.ListOptions{LabelSelector: labelSelector} err := sdk.List(memcached.Namespace, podList, sdk.WithListOptions(listOps)) // v0.1.0 listOps := &client.ListOptions{Namespace: memcached.Namespace, LabelSelector: labelSelector} err := r.client.List(context.TODO(), listOps, podList) // Get dep := &appsv1.Deployment{APIVersion: "apps/v1", Kind: "Deployment", Name: name, Namespace: namespace} err := sdk.Get(dep) // v0.1.0 dep := &appsv1.Deployment{} err = r.client.Get(context.TODO(), types.NamespacedName{Name: name, Namespace: namespace}, dep)
Handler
구조의 다른 필드를Reconcile<Kind
> 구조에 복사하고 초기화합니다.// newReconciler returns a new reconcile.Reconciler func newReconciler(mgr manager.Manager) reconcile.Reconciler { return &ReconcileMemcached{client: mgr.GetClient(), scheme: mgr.GetScheme(), foo: "bar"} } // ReconcileMemcached reconciles a Memcached object type ReconcileMemcached struct { client client.Client scheme *runtime.Scheme // Other fields foo string }
main.go
에서 변경 사항을 복사합니다.cmd/manager/main.go
의 v0.1.0 Operator의 기본 기능은 사용자 정의 리소스를 등록하고 모든 컨트롤러를 시작하는 Manager 를 설정합니다.SDK 함수
sdk.Watch()
,sdk.Handle()
,sdk.Run()
을 이전main.go
에서 마이그레이션할 필요가 없습니다. 해당 논리가 이제 컨트롤러에 정의되어 있기 때문입니다.그러나 이전
main.go
파일에 Operator별 플래그 또는 설정이 정의되어 있는 경우 해당 플래그를 복사합니다.SDK 체계에 등록된 타사 리소스 유형이 있는 경우 새 프로젝트의 Manager 체계에 등록하는 방법은
operator-sdk
프로젝트의 고급 주제 를 참조하십시오.사용자 정의 파일을 복사합니다.
이전 프로젝트에 사용자 정의
pkgs
, 스크립트 또는 문서가 있는 경우 해당 파일을 새 프로젝트에 복사합니다.배포 매니페스트에 변경 사항을 복사합니다.
이전 프로젝트에서 다음 매니페스트에 대한 업데이트의 경우 변경 사항을 새 프로젝트의 해당 파일에 복사합니다. 파일을 직접 덮어쓰지 않도록 주의해야 하지만 필요한 사항을 검사하고 변경합니다.
tmp/build/Dockerfile
tobuild/Dockerfile
- 새 프로젝트 레이아웃에는 tmp 디렉터리가 없습니다.
-
deploy/rbac.yaml
에서deploy/role.yaml
및deploy/role_binding.yaml
로 RBAC 규칙 업데이트 -
deploy/cr.yaml
을deploy/crds/_<version>_<kind>_cr.yaml
-
deploy/crd.yaml
을 배포하여/crds/_<version>_<kind>_crd.yaml
사용자 정의 종속 항목을 복사합니다.
이전 프로젝트의
Gopkg.toml
에 추가된 사용자 정의 종속 항목의 경우 새 프로젝트의Gopkg.toml
에 복사하여 추가합니다.dep
를 실행하여 새 프로젝트의 공급 업체를 업데이트합니다.변경 사항을 확인합니다.
Operator를 빌드하고 실행하여 작동하는지 확인합니다.