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) 를 참조하십시오.

프로젝트를 마이그레이션하는 데 권장되는 방법은 다음과 같습니다.

  1. 새 v0.1.0 프로젝트를 초기화합니다.
  2. 코드를 새 프로젝트에 복사합니다.
  3. v0.1.0에 대해 설명된 대로 새 프로젝트를 수정합니다.

이 가이드에서는 Operator SDK 의 예제 프로젝트인 memcached-operator 를 사용하여 마이그레이션 단계를 설명합니다. 사전 마이그레이션 예제는 각각 v0.0.7 memcached-operatorv0.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 프로젝트

프로세스

  1. SDK 버전이 v0.1.0인지 확인합니다.

    $ operator-sdk --version
    operator-sdk version 0.1.0
  2. 새 프로젝트를 생성합니다.

    $ 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
  3. 이전 프로젝트에서 .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을 사용하여 생성된 새 프로젝트

프로세스

  1. 사용자 지정 유형에 대한 스캐폴드 API를 생성합니다.

    1. 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
    2. 이전 프로젝트에서 정의한 만큼 사용자 지정 유형에 대해 이전 명령을 반복합니다. 각 유형은 파일 pkg/apis/ /<version>/<kind>_types.go 파일에 정의됩니다.
  2. 유형의 내용을 복사합니다.

    1. 이전 프로젝트에서 새 프로젝트의 pkg/apis//<version>/types.go 파일의 SpecStatus 콘텐츠를 새 프로젝트의 pkg/apis / /<version>/<kind>_types.go 파일로 복사합니다.
    2. 각 & 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/에서 마이그레이션된 사용자 정의 유형

프로세스

  1. 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 프로젝트의 경우 리소스를 조사할 컨트롤러 를 정의해야 합니다.

    1. 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
    2. 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{})
  2. 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 에 따라 컨트롤러는 요청을 다시 시도하거나, 즉시 재시도하거나, 지정된 기간 후에 재시도하지 않습니다.

    1. 이전 프로젝트의 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.
          ...
      }
    2. 조정 코드에서 반환 값을 변경합니다.

      1. 반환 에라타반환 reconcile.Result{}, err 로 바꿉니다.
      2. 반환 nil반환 reconcile.Result{}, nil 로 바꿉니다.
    3. 컨트롤러에서 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
    4. 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)
    5. 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
      }
  3. 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 프로젝트의 고급 주제 를 참조하십시오.

  4. 사용자 정의 파일을 복사합니다.

    이전 프로젝트에 사용자 정의 pkgs, 스크립트 또는 문서가 있는 경우 해당 파일을 새 프로젝트에 복사합니다.

  5. 배포 매니페스트에 변경 사항을 복사합니다.

    이전 프로젝트에서 다음 매니페스트에 대한 업데이트의 경우 변경 사항을 새 프로젝트의 해당 파일에 복사합니다. 파일을 직접 덮어쓰지 않도록 주의해야 하지만 필요한 사항을 검사하고 변경합니다.

    • tmp/build/Dockerfile to build/Dockerfile

      • 새 프로젝트 레이아웃에는 tmp 디렉터리가 없습니다.
    • deploy/rbac.yaml 에서 deploy/role.yamldeploy/role_binding.yaml로 RBAC 규칙 업데이트
    • deploy/cr.yamldeploy/crds/_<version>_<kind>_cr.yaml
    • deploy/crd.yaml 을 배포하여 /crds/_<version>_<kind>_crd.yaml
  6. 사용자 정의 종속 항목을 복사합니다.

    이전 프로젝트의 Gopkg.toml 에 추가된 사용자 정의 종속 항목의 경우 새 프로젝트의 Gopkg.toml 에 복사하여 추가합니다. dep 를 실행하여 새 프로젝트의 공급 업체를 업데이트합니다.

  7. 변경 사항을 확인합니다.

    Operator를 빌드하고 실행하여 작동하는지 확인합니다.

Red Hat logoGithubRedditYoutubeTwitter

자세한 정보

평가판, 구매 및 판매

커뮤니티

Red Hat 문서 정보

Red Hat을 사용하는 고객은 신뢰할 수 있는 콘텐츠가 포함된 제품과 서비스를 통해 혁신하고 목표를 달성할 수 있습니다.

보다 포괄적 수용을 위한 오픈 소스 용어 교체

Red Hat은 코드, 문서, 웹 속성에서 문제가 있는 언어를 교체하기 위해 최선을 다하고 있습니다. 자세한 내용은 다음을 참조하세요.Red Hat 블로그.

Red Hat 소개

Red Hat은 기업이 핵심 데이터 센터에서 네트워크 에지에 이르기까지 플랫폼과 환경 전반에서 더 쉽게 작업할 수 있도록 강화된 솔루션을 제공합니다.

© 2024 Red Hat, Inc.