Lasso는 컨트롤러 프레임워크입니다.
Lasso는 컨트롤러 런타임 프로젝트와 일부 기능적 패리티를 가지며 컨트롤러 런타임 대신 사용할 수 있습니다.
올가미는 레벨이 낮습니다. 자신의 컨트롤러를 관리하고 싶다면 이를 사용할 수 있습니다. 자신만의 리소스 유형을 생성하기 위한 더 많은 편의성과 기능을 찾고 있다면 Wrangler를 확인해 보시기 바랍니다.
Wrangler와 Norman이 사용하는 핵심 컨트롤러 프레임워크.
이 문서는 Kubernetes 컨트롤러를 처음 사용하는 사람과 Kubernetes 컨트롤러를 처음 사용하지 않지만 Lasso를 처음 사용하는 사람이라는 두 가지 독자를 염두에 두고 작성되었습니다.
"Kubernetes 컨트롤러를 처음 사용하는 사람" 범주에 속한다면 Lasso의 가치 제안으로 건너뛸 수 있습니다.
Kubernetes 컨트롤러를 처음 사용하는 경우 섹션을 건너뛰지 않는 것이 좋습니다.
기본적인 Kubernetes 지식이 부족한 경우 먼저 Kubernetes 개요와 같은 기본 사항에 대한 다른 문서를 참조하는 것이 좋습니다.
참고: 이 과정은 매우 간단한 단기 집중 과정입니다. 주제와 관련된 다른 리소스를 찾아보는 것이 좋습니다. 리소스가 많이 있습니다! 권장되는 두 가지 리소스는 샘플 컨트롤러 프로젝트와 Kubernetes 컨트롤러 프레임워크 소개입니다.
Kubernetes 문서에서
Kubernetes에서 컨트롤러는 apiserver를 통해 클러스터의 공유 상태를 감시하고 현재 상태를 원하는 상태로 이동하려고 시도하는 제어 루프입니다.
"컨트롤러"라는 단어는 위의 정의에서 생각하는 것보다 더 느슨하게 사용됩니다. 우리말로 말하자면, 컨트롤러는 Kubernetes 리소스 이벤트에 응답하여 작동하는 루프 핸들러입니다. Lasso에서는 "컨트롤러"라는 단어를 사용하여 이 루프 핸들러를 등록하고 필요한 리소스를 제공하는 전체 구조를 나타냅니다. 간단히 말해서 컨트롤러는 Kubernetes 유형과 상호 작용하고 작동하는 데 필요한 모든 것을 번들로 묶는 구조입니다.
위의 목표를 달성하려면 몇 가지 하위 목표를 달성해야 합니다.
위의 목표를 달성하는 데 도움이 되는 많은 프레임워크가 있습니다. 올가미도 그 중 하나입니다. Lasso를 포함한 대부분의 프레임워크의 공통점은 이러한 목표를 달성하기 위해 client-go의 기능을 사용한다는 것입니다. client-go만 사용하여 이러한 목표를 달성할 수 있습니다. 이 섹션의 나머지 부분에서는 클라이언트 이동 개념을 사용하여 컨트롤러를 구성하는 방법을 살펴보겠습니다.
Informer는 Kubernetes 컨트롤러에 필요한 위의 목표를 달성하는 데 사용됩니다. 제보자는 이벤트 핸들러와 인덱서를 보유합니다. 인덱서는 인덱서라고 하는 저장소 내의 객체를 인덱싱하기 위한 저장소 및 맵 기능을 보유합니다. 기본 구조체는 다르지만 이를 설명하기 위해 의사 구조체가 아래에 표시됩니다.
Informer
EventHandler
Indexer
Store
Indexers
EventHandler는 이벤트 생성, 업데이트 및 삭제에 대해 서로 다른 논리를 가질 수 있습니다. 이벤트 핸들러는 컨트롤러가 들어오는 곳입니다. 이를 사용하여 이벤트 핸들러 생성, 업데이트 및 삭제를 구성합니다.
인덱서는 캐시로 사용됩니다.
저장소는 인덱서가 개체를 유지하는 곳입니다.
인덱서는 지속형 개체를 인덱싱하는 데 사용할 수 있는 함수입니다. 인덱서로 인덱싱되면 인덱서가 관심을 갖는 특성을 설명하는 문자열을 사용하여 개체를 검색할 수 있습니다.
인덱서는 네임스페이스 및 이름과 같은 간단한 메타데이터로 개체를 검색하는 데 자주 사용됩니다.
정보 제공자는 먼저 클라이언트에서 반환된 모든 리소스를 나열하여 인덱서를 채웁니다. 그런 다음 정보 제공자는 할당된 Kubernetes 리소스를 감시합니다. 이벤트가 발생하면 해당 이벤트를 사용하여 인덱서를 업데이트하고 이벤트 핸들러를 실행합니다.
일반적으로 애플리케이션에는 여러 컨트롤러가 필요합니다. 그러나 모든 컨트롤러가 자체 정보 제공자와 자체 인덱서를 갖는 것은 효율적이지 않을 수 있습니다. client-go의 SharedIndexerInformer를 사용하면 모두 동일한 인덱서를 사용하는 여러 컨트롤러를 추가할 수 있습니다.
kubernetes/sample-controller 저장소에는 Kubernetes 컨트롤러가 어떻게 작동하는지에 대한 훌륭한 시각적 자료가 있습니다.
참고: 정보 제공자는 간결성을 위해 단순화되었습니다. 정확히 어떻게 작동하는지 관심이 있다면 client-go 코드를 읽어보는 것이 좋습니다.
Lasso는 컨트롤러 패키지를 통해 컨트롤러가 무엇인지 표준화합니다. Lasso는 프로젝트 내에서 캐시, 컨트롤러 및 클라이언트를 관리하기 위한 팩토리를 도입합니다. 이는 다양한 유형의 많은 인스턴스를 관리하는 목장주에게 필수적입니다.
올가미 컨트롤러는 클라이언트 이동 작업 대기열을 사용합니다. Lasso는 작업 대기열을 처리하는 이벤트 핸들러를 등록합니다. 작업 대기열 지향 핸들러를 사용하면 각 Kubernetes 유형에 대해 하나의 이벤트 핸들러만 추가하면 됩니다. 이제 핸들러를 등록하면 해당 유형의 컨트롤러 핸들러 목록에 추가됩니다. 개체를 대기열에 넣으면 해당 개체가 작업 대기열에 추가됩니다. 작업 대기열의 각 개체는 고루틴에서 실행되는 작업자에 의해 처리됩니다. 컨트롤러의 이벤트 핸들러는 하나 이상의 컨트롤러 핸들러가 ErrIgnore
유형이 아닌 오류를 반환하도록 하는 모든 객체를 다시 대기열에 추가합니다. 이 작업 대기열에는 다른 소스에서 대기열에 추가된 개체가 있을 수도 있습니다. 이 기능은 컨트롤러의 Enqueue 기능을 통해 노출됩니다. 이는 컨트롤러가 Kubernetes 리소스 및 캐시 재동기화에만 반응하는 것에서 코드로도 호출할 수 있는 것으로 변환합니다.
sharedController 유형은 컨트롤러 기능을 노출하기 위해 컨트롤러 인터페이스를 포함합니다. sharedController는 또한 Client 함수와 함께 RegisterHandler 함수를 노출합니다. RegisterHandler는 전달된 핸들러를 컨트롤러의 핸들러 목록에 추가하고 클라이언트는 해당 리소스 유형에 해당하는 sharedController에 대한 클라이언트를 반환합니다. sharedController에는 해당 유형을 나타내는 GVK 필드(그룹 버전 종류)가 있습니다.
"공유" 측면은 보다 원시적인 Lasso 컨트롤러에서 시작됩니다. 예를 들어 작업 대기열을 사용하면 한 세트의 이벤트 핸들러를 공유할 수 있습니다. 그런 다음 Lasso 공유 컨트롤러는 GVK용 재사용 가능한 클라이언트를 보유하고 RegisterHandler를 사용하여 아래 컨트롤러에 핸들러를 쉽게 등록하는 방법을 추가하여 이에 추가합니다.
sharedController는 기본 컨트롤러를 생성할 수 있습니다. 핸들러가 sharedController에 등록된 후에만 그렇게 됩니다.
Kubernetes 클라이언트를 래핑합니다. sharedClientFactory와 같은 상위 구조체에서 클라이언트를 관리하기 위한 GVK 필드를 포함합니다. 기본 REST 클라이언트에 대한 User-Agent 헤더 구성과 같은 몇 가지 추가 기능을 노출합니다.
올가미 캐시는 client-go의 SharedIndexInformer를 둘러싼 가벼운 래퍼입니다.
올가미 캐시의 주요 이점은 재사용이 가능하도록 GVK가 메모리에서 SharedIndexInformer를 관리하는 캐시 팩토리를 할당할 수 있다는 것입니다. Lasso Cache 기능을 사용할 때 이를 생성하기 위해 전달된 CacheFactory 내에서 자체적으로 관리됩니다.
공유 캐시 팩토리는 캐시를 저장하고 GVK 구조체를 통해 관리할 수 있도록 합니다. 캐시가 생성되면 다시 사용할 수 있습니다.
공유 클라이언트 팩토리는 GVK용 클라이언트가 생성된 후 재사용될 수 있도록 존재합니다.
SharedControllerFactory는 위의 모든 것을 하나로 묶습니다. 단일 진입점을 통해 클라이언트, 캐시 및 핸들러에 액세스할 수 있으며 모두 관리됩니다. 주로 공유 컨트롤러 팩토리와 상호작용이 가능합니다. 필요한 모든 기본 컨트롤러, 클라이언트 및 캐시가 생성됩니다. 그러면 이러한 개체가 중복되지 않는지 확인됩니다. 경쟁 조건을 방지합니다.
ForObject, ForKind, ForResource 또는 ForResourceKind를 사용하면 SharedControllerFactory가 다음을 수행합니다.
deferredController는 일단 실행되면 컨트롤러를 생성하고 반환하는 함수입니다. SharedCacheFactory의 캐시를 사용하여 컨트롤러를 생성합니다. deferredController 함수의 목적은 꼭 필요할 때까지 캐시 채우기를 보류하는 것입니다. 이렇게 하면 핸들러를 등록했거나 대기열에 추가했거나 컨트롤러의 캐시를 요청한 Kubernetes 리소스만 메모리에 저장됩니다.
SharedControllerFactory에서 sharedController를 가져오면 아직 기본 컨트롤러가 인스턴스화되지 않습니다. 대신 언급된 작업 중 하나가 수행되면 deferredController 메서드를 호출하여 메서드를 생성합니다.
다음은 핸들러를 등록하고 올가미에서 실행하는 간단한 방법에 대한 단계입니다.
package main
import (
"context"
"github.com/rancher/lasso/pkg/controller"
appsv1 "k8s.io/api/apps/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/rest"
)
func main () {
config , err := clientcmd . BuildConfigFromFlags ( "" , os . Getenv ( "KUBECONFIG" ))
if err != nil {
panic ( err )
}
// Setup types you want to work with
scheme := runtime . NewScheme ()
appsv1 . AddToScheme ( scheme )
controllerFactory , err := controller . NewSharedControllerFactoryFromConfig ( config , scheme )
if err != nil {
panic ( err )
}
// ForObject, ForKind, ForResource, and ForResourceKind can all be used to retrieve the controller.
// They all accept different parameters but the first three all eventually call ForResourceKind.
// Refer to [How to use Lasso](#how-to-use-lasso) for more information on how ForResourceKind works.
sharedController , err := controllerFactory . ForObject ( & appsv1. Deployment {})
if err != nil {
panic ( err )
}
// Register a handler on a shared controller. If you need a dedicated queue then use controller.New()
sharedController . RegisterHandler ( context . TODO (), "my-handler" , controller . SharedControllerHandlerFunc ( func ( key string , obj runtime. Object ) (runtime. Object , error ) {
// obj is the latest version of this obj in the cache and MAY BE NIL when an object is finally deleted
dep , ok := obj .( * appsv1. Deployment )
if ! ok {
return obj , nil
}
// Do some stuff ...
// Get stuff from the cache
sharedController . Informer (). GetStore (). Get ( key )
result := & appsv1. Deployment {}
err := sharedController . Client (). Update ( ctx , dep . Namespace , dep , result , metav1. UpdateOptions {})
// return the latest version of the object
return result , err
}))
// the second, int parameter is the number of workers to be used for EACH controller.
err = controllerFactory . Start ( context . TODO (), 5 )
if err != nil {
panic ( err )
}
}
Lasso의 일부 테스트는 envtest를 사용하여 실행됩니다. Envtest를 사용하면 오버헤드가 거의 또는 전혀 없이 "가짜" Kubernetes 서버에 대해 테스트를 실행할 수 있습니다.
필수 setup-envtest
바이너리를 설치하려면 다음 명령을 사용하십시오.
go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
테스트를 실행하기 전에 다음 명령을 실행하여 가짜 서버를 설정해야 합니다.
# note that this will use a new/latest version of k8s. Our CI will run against the version of k8s that corresponds to lasso's
# current client-go version, as seen in scripts/test.sh
export KUBEBUILDER_ASSETS= $( setup-envtest use -p path )
다음 리소스는 이 문서를 작성하는 데 도움이 되었습니다. 여기에 제시된 것보다 더 많은 것을 배우려면 적극 권장됩니다.