Kubernetes
client-go library의 Reflector, Informer, Indexer 역할
DevOps Engineer
2025. 3. 2. 11:15
728x90
client-go 라이브러리는 Kubernetes API와 상호 작용하기 위한 Go 라이브러리이며, 클라이언트 애플리케이션이 Kubernetes 리소스를 효율적으로 관리할 수 있도록 도와줍니다.
이 중에서 Reflector, Informer, Indexer는 Kubernetes API 데이터를 효율적으로 캐싱하고 동기화하는 핵심 컴포넌트입니다.
1️⃣ Reflector
🔹 개념
- Reflector는 Kubernetes API 서버에서 특정 리소스를 감시하고, 변경 사항을 감지하여 로컬 캐시(Store)에 데이터를 동기화하는 역할을 합니다.
- API 서버의 watch 기능을 사용하여 새로운 리소스, 수정된 리소스, 삭제된 리소스를 감지합니다.
🔹 동작 방식
- API 서버에 LIST 요청을 보내 기존 리소스를 가져옵니다.
- API 서버의 WATCH 스트림을 감시하여 변경 사항을 실시간으로 감지합니다.
- 변경된 데이터를 Store에 업데이트합니다.
🔹 예제 코드 (Reflector 사용)
package main
import (
"context"
"fmt"
"time"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/cache"
)
func main() {
// Kubernetes 클라이언트 생성
config, _ := rest.InClusterConfig()
client, _ := dynamic.NewForConfig(config)
// 감시할 리소스 설정 (예: Pods)
gvr := schema.GroupVersionResource{Group: "", Version: "v1", Resource: "pods"}
// Reflector 생성 및 실행
store := cache.NewStore(cache.MetaNamespaceKeyFunc)
reflector := cache.NewReflector(
cache.NewListWatchFromClient(client.Resource(gvr), "pods", "", cache.Indexers{}),
&cache.ResourceEventHandlerFuncs{},
store,
5*time.Minute,
)
stopCh := make(chan struct{})
go reflector.Run(stopCh)
// 일정 시간 후 캐시 확인
time.Sleep(10 * time.Second)
for _, obj := range store.List() {
fmt.Println(obj)
}
}
🔹 주요 특징
- API 서버 부하 감소: 클라이언트가 계속해서 API 서버를 호출하지 않고, Reflector가 최신 상태를 유지함.
- 고속 데이터 조회: Reflector는 Store를 사용해 데이터를 캐싱하므로 빠르게 조회 가능.
- WATCH 스트림 활용: API 서버의 watch 기능을 사용하여 변경 사항을 실시간으로 반영.
2️⃣ Informer
🔹 개념
- Informer는 Reflector를 내부적으로 사용하며, Kubernetes 리소스의 변경 사항을 감지하고 이를 애플리케이션에 알리는 역할을 합니다.
- 이벤트 기반으로 작동하며, AddFunc, UpdateFunc, DeleteFunc 핸들러를 통해 변경 사항을 감지할 수 있습니다.
🔹 동작 방식
- Reflector를 사용하여 Kubernetes API 서버에서 데이터를 가져옴.
- 데이터를 로컬 캐시에 저장하고, 필요한 경우 Indexer를 사용해 검색을 최적화함.
- 리소스 변경 이벤트가 발생하면 EventHandlerFuncs를 통해 콜백 함수를 호출.
🔹 예제 코드 (Informer 사용)
package main
import (
"context"
"fmt"
"time"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
)
func main() {
// Kubernetes 클라이언트 생성
config, _ := rest.InClusterConfig()
clientset, _ := kubernetes.NewForConfig(config)
// Shared Informer Factory 생성 (Pod 리소스 감시)
factory := informers.NewSharedInformerFactory(clientset, 30*time.Second)
podInformer := factory.Core().V1().Pods().Informer()
// 이벤트 핸들러 등록
podInformer.AddEventHandler(
cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
fmt.Println("Pod 추가됨:", obj)
},
UpdateFunc: func(oldObj, newObj interface{}) {
fmt.Println("Pod 업데이트됨:", newObj)
},
DeleteFunc: func(obj interface{}) {
fmt.Println("Pod 삭제됨:", obj)
},
},
)
// Informer 실행
stopCh := make(chan struct{})
go podInformer.Run(stopCh)
// 실행 지속
wait.NeverStop()
}
🔹 주요 특징
- Reflector 포함: API 서버에서 데이터를 가져오고 Watch 스트림을 유지.
- 비동기 이벤트 처리: 리소스가 변경될 때만 핸들러가 실행됨.
- 고성능 데이터 조회: 내부적으로 캐시와 Indexer를 사용하여 API 서버 호출을 최소화.
3️⃣ Indexer
🔹 개념
- Indexer는 Informer가 관리하는 캐시 데이터를 특정 키 값으로 인덱싱하여 빠르게 검색할 수 있도록 도와줍니다.
- 기본적으로 Informer는 cache.Store를 사용하지만, Indexer를 추가하면 다양한 기준으로 데이터를 효율적으로 검색 가능합니다.
🔹 동작 방식
- Informer가 데이터를 받아 캐시에 저장할 때 Indexer도 함께 업데이트됨.
- 특정 키 또는 필터 기준을 기반으로 빠르게 데이터 조회 가능.
🔹 예제 코드 (Indexer 사용)
package main
import (
"fmt"
v1 "k8s.io/api/core/v1"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/cache"
)
func main() {
// Kubernetes 클라이언트 생성
config, _ := rest.InClusterConfig()
clientset, _ := kubernetes.NewForConfig(config)
// Shared Informer Factory 생성
factory := informers.NewSharedInformerFactory(clientset, 0)
podInformer := factory.Core().V1().Pods().Informer()
// Indexer 추가 (Pod의 Node 이름을 키로 저장)
indexer := podInformer.GetIndexer()
indexer.AddIndexers(cache.Indexers{
"nodeName": func(obj interface{}) ([]string, error) {
pod := obj.(*v1.Pod)
return []string{pod.Spec.NodeName}, nil
},
})
// Informer 실행
stopCh := make(chan struct{})
go podInformer.Run(stopCh)
// 일정 시간 대기 후 Indexer 검색
// 특정 노드에서 실행 중인 Pod 조회
nodePods, _ := indexer.ByIndex("nodeName", "worker-node-1")
fmt.Println("worker-node-1에서 실행 중인 Pod 목록:", nodePods)
}
🔹 주요 특징
- 고속 검색 가능: 특정 필드(예: nodeName)로 데이터 검색 속도를 개선.
- API 서버 부하 감소: API 서버를 직접 호출하지 않고 캐시에서 데이터 조회 가능.
- 사용자 정의 인덱스 가능: 여러 개의 키를 기반으로 데이터를 조회할 수 있음.
정리
💡 Informer는 Reflector를 포함하고, Indexer는 Informer의 캐시를 최적화하는 역할을 한다! 🚀
728x90