본문 바로가기
WIKI 기술 지식 베이스

안전 시작(safe-start) 구현하기

원문 보기 위키 갱신

안전 시작(safe-start) 구현하기 (Implementing Safe-start)

이 가이드는 프로바이더 개발자가 크로스플레인 프로바이더에 안전 시작(safe-start) 기능을 구현하는 방법을 보여 줍니다. safe-start는 ManagedResourceDefinitions를 통해 사용하지 않는 관리 리소스(my resource)를 비활성화하여 성능을 개선하고 리소스 오버헤드를 줄입니다.

출처: 문서

본문

이 기능은 v2에서 도입되었습니다. 자세한 내용은 크로스플레인의 기능 수명주기(Crossplane feature lifecycle) 문서를 참고하세요.

중요 safe-start는 Crossplane v2.0+와 crossplane-runtime v2.0+가 필요합니다. safe-start 구현에는 프로바이더 시작 동작에 영향을 주는 코드 변경이 포함됩니다.

safe-start가 제공하는 것 (What safe-start provides)

safe-start는 프로바이더가 CRD 설치를 처리하는 방식을 변경합니다.

safe-start 없이:

  • 프로바이더는 설치 시 모든 관리 리소스 CRD를 생성합니다.
  • 사용자는 하나 또는 두 개만 필요하더라도 모든 리소스를 받습니다.
  • 더 높은 메모리 사용량과 API 서버 부하.

safe-start 포함:

  • 프로바이더는 ManagedResourceDefinitions를 생성하지만 CRD는 활성화될 때만 생성합니다.
  • 사용자는 ManagedResourceActivationPolicies를 통해 필요한 리소스만 활성화합니다.
  • 클러스터 리소스 오버헤드의 상당한 감소.

사전 요구 사항 (Prerequisites)

safe-start를 구현하기 전에:

  • crossplane-runtime v2.0+로 빌드된 프로바이더
  • ManagedResourceDefinitions에 대한 이해
  • Crossplane v2.0+가 있는 테스트 환경

구현 단계 (Implementation steps)

1단계: safe-start 기능 선언 (Declare safe-start capability)

프로바이더 패키지 메타데이터에 safe-start를 추가합니다.

# package/crossplane.yaml
apiVersion: meta.pkg.crossplane.io/v1
kind: Provider
metadata:
  name: provider-example
spec:
  capabilities:
  - safe-start

2단계: 필요한 imports 추가 (Add required imports)

main.go imports를 업데이트합니다 (전체 API 참조는 crossplane-runtime godoc 참고).

import (
    // existing imports...
    
    "k8s.io/apimachinery/pkg/runtime/schema"
    apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
    
    "github.com/crossplane/crossplane-runtime/v2/pkg/controller"
    "github.com/crossplane/crossplane-runtime/v2/pkg/gate"
    "github.com/crossplane/crossplane-runtime/v2/pkg/reconciler/customresourcesgate"
)

3단계: 게이트 초기화 (Initialize the gate)

main 함수에 게이트 초기화를 추가합니다.

func main() {
    // existing setup code...
    
    o := controller.Options{
        // existing options...
        Gate: new(gate.Gate[schema.GroupVersionKind]),
    }
    
    // Add CustomResourceDefinition to scheme for gate controller
    if err := apiextensionsv1.AddToScheme(mgr.GetScheme()); err != nil {
        panic(err)
    }
    
    // Setup controllers
    if err := yourprovider.Setup(mgr, o); err != nil {
        panic(err)
    }
        
    // Setup the CRD gate controller  
    if err := customresourcesgate.Setup(mgr, o); err != nil {
        panic(err)
    }
        
    // start manager...
}

4단계: 게이트된 컨트롤러 설정 사용 (Use gated controller setup)

각 관리 리소스 컨트롤러에 대한 게이트된(gated) 설정 함수를 만듭니다.

// SetupGated registers controller setup with the gate, waiting for the
// required CRD
func SetupGated(mgr ctrl.Manager, o controller.Options) error {
    o.Gate.Register(func() {
        if err := Setup(mgr, o); err != nil {
            panic(err)
        }
    }, v1alpha1.MyResourceGroupVersionKind)
    return nil
}

// Setup is your existing controller setup function (unchanged)
func Setup(mgr ctrl.Manager, o controller.Options) error {
    // existing controller setup code...
}

5단계: 컨트롤러 등록 업데이트 (Update controller registration)

컨트롤러 설정이 게이트된 버전을 사용하도록 변경합니다.

// internal/controller/controller.go
func Setup(mgr ctrl.Manager, o controller.Options) error {
    for _, setup := range []func(ctrl.Manager, controller.Options) error{
        myresource.SetupGated,  // Changed from myresource.Setup
        // other gated setups...
    } {
        if err := setup(mgr, o); err != nil {
            return err
        }
    }
    return nil
}

구현 세부 사항 (Implementation details)

safe-start 구현은 "게이트(gate)" 패턴을 사용합니다.

  • 게이트 초기화: CRD 준비 상태를 추적하는 게이트를 만듭니다.
  • 컨트롤러 등록: 컨트롤러가 게이트에 등록하며, 필요한 CRD를 지정합니다.
  • CRD 모니터링: customresourcesgate 컨트롤러가 CRD 생성/삭제를 감시합니다.
  • 지연된 시작: 컨트롤러는 필요한 CRD가 활성화될 때만 시작합니다.

구현 테스트 (Testing your implementation)

기본 워크플로우로 safe-start 동작을 테스트합니다.

# Install Crossplane v2.0+
helm install crossplane crossplane-stable/crossplane \
  --namespace crossplane-system \
  --set provider.defaultActivations={}

# Install your provider  
kubectl apply -f provider.yaml

# Check that MRDs are created but inactive
kubectl get mrds
# All should show STATE: Inactive

# No CRDs should exist yet
kubectl get crds | grep yourprovider.m.crossplane.io
# Should return no results

# Create activation policy
kubectl apply -f - 

문제 해결 (Troubleshooting)

컨트롤러가 시작되지 않음

원인: 게이트가 활성화되지 않는 CRD를 기다립니다.

해결책: 크로스플레인이 MRD를 활성화하고 CRD를 생성했는지 확인하세요.

kubectl get mrds -o wide
kubectl describe mrap 

CRD가 나타나지 않음

원인: MRD가 활성화되지 않거나 활성화 정책이 일치하지 않습니다.

해결책: 활성화 정책 패턴이 MRD 이름과 일치하는지 확인하세요.

kubectl get mrds
kubectl get mrap -o yaml

마이그레이션 고려 사항 (Migration considerations)

기존 프로바이더에 safe-start를 추가할 때:

  • 기존 설치: 예상대로 계속 동작합니다 (CRD 변경 없음).
  • 새 설치: 비활성 MRD로 시작하며, 활성화 정책이 필요합니다.

다음 단계 (Next steps)

  • 다양한 활성화 패턴으로 safe-start 구현을 테스트합니다.
  • 활성화 요구 사항을 설명하도록 프로바이더 문서를 업데이트합니다.
  • 이제 활성화 정책이 필요한 프로바이더에 대한 사용자 경험을 고려합니다.

사용자 경험에 대해 더 알아보려면 사용하지 않는 관리 리소스 비활성화 문서를 참고하세요.

더 알아보기 (Learn more)