ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • go-client Informer 사용시 Indexer는 선택적으로 사용되는건가?
    Kubernetes 2025. 3. 2. 11:34
    728x90

    Informer를 사용할 때 Indexer는 필수 요소가 아니며, 필요할 경우 선택적으로 추가할 수 있습니다.

     

    1️⃣ Indexer 없이 Informer만 사용할 경우

    기본적으로 SharedInformer는 내부적으로 Reflector를 사용하여 데이터를 가져오고, 단순한 캐시(Store) 에 저장합니다.
    이 경우, 데이터를 가져올 때는 전체 목록을 순회하면서 원하는 데이터를 찾아야 하기 때문에 검색 성능이 낮을 수 있습니다.

    📌 Indexer 없이 Informer만 사용하는 예제

    package main
    
    import (
    	"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()
    }

    📌 이 코드에서는 Indexer를 사용하지 않으며, Informer가 데이터를 단순 캐시에 저장하고 가져오는 방식으로 동작합니다.

     

    2️⃣ Indexer를 사용하는 경우

    Indexer를 사용하면 특정 키(예: Node 이름, 네임스페이스, 라벨 등)로 데이터를 인덱싱하여 빠르게 조회할 수 있습니다.
    즉, 대량의 데이터를 처리할 때 성능 최적화에 도움이 됩니다.

    📌 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 조회
    	pods, err := indexer.ByIndex("nodeName", "worker-node-1")
    	if err == nil {
    		fmt.Println("worker-node-1에서 실행 중인 Pod 목록:", pods)
    	} else {
    		fmt.Println("Index 조회 실패:", err)
    	}
    }

    📌 Indexer를 추가하면

    • 특정 조건(예: nodeName)을 기준으로 데이터를 빠르게 검색 가능.
    • indexer.ByIndex("nodeName", "worker-node-1") 처럼 특정 키를 기준으로 데이터를 조회할 수 있음.
    • 전체 데이터에서 검색하는 것보다 성능이 훨씬 향상됨.

    3️⃣ Indexer를 언제 사용할까?

    Indexer가 필요한 경우

    • 특정 키를 기준으로 자주 데이터를 조회해야 할 때 (예: 특정 Node에 배포된 Pod 찾기).
    • 대규모 Kubernetes 클러스터에서 검색 속도를 높여야 할 때.
    • 특정 필드(예: 라벨, 네임스페이스, 노드 이름)로 데이터를 필터링할 때.

    Indexer 없이도 충분한 경우

    • 단순히 이벤트(추가, 수정, 삭제) 핸들러만 필요할 때.
    • 데이터가 많지 않아서 kubectl get pods 같은 전체 조회로도 충분할 때.

     

    💡 즉, Indexer는 선택적으로 사용할 수 있으며, 검색 성능 최적화가 필요할 때만 추가하는 것이 좋다! 🚀

     
     

     

    728x90
Designed by Tistory.