Kubernetes 이벤트 리스너와 컨트롤러

Ryu·2022년 5월 17일
0

목적

Kubernetes evnets에 대한 이벤트 리스너를 등록하고 싶다.

검토

Event에 대한 API는 다음과 같다.

k get events -w -v 9                             
I0110 14:19:08.940823  467569 loader.go:375] Config loaded from file:  /home/song/.kube/config
I0110 14:19:08.946053  467569 round_trippers.go:423] curl -k -v -XGET  -H "User-Agent: kubectl/v1.19.4 (linux/amd64) kubernetes/d360454" -H "Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json;as=Table;v=v1beta1;g=meta.k8s.io,application/json" 'https://x.x.x.x:6443/api/v1/namespaces/default/events?limit=500'
I0110 14:19:08.967600  467569 round_trippers.go:443] GET https://10.185.60.20:6443/api/v1/namespaces/default/events?limit=500 200 OK in 21 milliseconds
I0110 14:19:08.967622  467569 round_trippers.go:449] Response Headers:
I0110 14:19:08.967634  467569 round_trippers.go:452]     Cache-Control: no-cache, private
I0110 14:19:08.967643  467569 round_trippers.go:452]     Content-Type: application/json
I0110 14:19:08.967649  467569 round_trippers.go:452]     Date: Mon, 10 Jan 2022 05:19:17 GMT
I0110 14:19:08.969068  467569 request.go:1097] Response Body:
...

기존 서비스

대부분 Event를 특정 포트에서 듣고 외부 data sink (s3, 등)으로 익스포트하는 서비스이다. 이 외에 'logger'들이 대부분 동작 방식이 비슷함.

컨트롤러

https://engineering.bitnami.com/articles/a-deep-dive-into-kubernetes-controllers.html

A control loop라는건 시스템의 상태를 제어하는 무한 루프임.

Go에서는

Informer/SharedInformer가 변경을 watch하고 이벤트를 WorkQueue로 보냄. Worker들이 이벤트가 도착하면 무언가를 함.

  • Informer
    • Object 상태 검사하기 위해서 obejct 정보나 이벤트를 계속 요청해야하는데, 그건 비싼 방법이므로 client-go에서 캐시를 사용하는 방법을 제공함.
    • Type
      • ListWatcher
      • Resource Event Handler
      • Recyncperiod
  • SharedInformer
    • 쿠버네티스에는 컨트롤러가 여러개 있으므로 Informer에서 사용하는 캐시가 중복될 수 있음.
    • Upstream server에서 변경사항을 쭉 캐시에 쓰고, 여러 컨트롤러 (downstream)에서 가져갈 수 있도록 함. + hook
    • Kubernetes api server에 요청없이도 이 캐시를 사용할 수 있다.
  • WorkQueue
    • SharedInformer 자체는 어떤 컨트롤러가 캐시를 가져가는지 신경x 컨트롤러가 알아서 캐시를 읽어갈 수 있게 큐잉을 써야함.

Key's life-cycle in Workqueue

Kubewatch에서는

Kubewatch는 Pod의 변경을 모니터하고 slack으로 알림 메세지를 보내는 컨트롤러임.

// Controller object
type Controller struct {
      logger       *logrus.Entry
      clientset    kubernetes.Interface // k8s api client
      queue        workqueue.RateLimitingInterface // 키 컴포넌트
      informer     cache.SharedIndexInformer // 키 컴포넌트
      eventHandler handlers.Handler // slack 메세지 보내는 handler
}

아이디어

아래의 역할을 하는 컨트롤러를 만든다.

for {
  changes := getResourceChangesFromEvents()
  letAppKnowTheChanges()
}

위를 위해서 아래 세 단계를 거친다.

  1. Construct a WorkQueue and a SharedInformer
  2. Start the controller
  3. Connect the controller to DB(MQ)

Go일 경우

KubeWatcher처럼 K8s의 client-go에서 workerQueue를 바로 사용할 수 있다.

Nodejs일 경우

Go에서 보이는 것처럼 process/thread pool를 관리하는 것보다는 event queue를 쓰는게 더 nodejs에 적합해보이는데 아직 잘 모르겠다.

WorkerThread를 쓰는게 나을까? CPU 집약적이지 않아 없어도 될 것 같은데 잘 모르겠음.

0개의 댓글