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

Kubernetes 리소스 감시(Watching)

원문 보기 위키 갱신

Kubernetes 백엔드 플러그인은 KubernetesWatcher 인터페이스에 watchResource() 메서드를 제공해요. 이 메서드는 플러그인 작성자가 Kubernetes API에서 리소스 변경을 실시간으로 스트리밍할 수 있게 해줘요. 이것은 기존 get과 list 연산의 감시(watch) 대응물이며 같은 오류 처리 패턴을 따릅니다.

출처: 문서

본문

Kubernetes 백엔드 플러그인은 KubernetesWatcher 인터페이스에 watchResource() 메서드를 제공해요. 이 메서드는 플러그인 작성자가 Kubernetes API에서 리소스 변경을 실시간으로 스트리밍할 수 있게 해줘요. 이것은 기존 get과 list 연산의 감시(watch) 대응물이며 같은 오류 처리 패턴을 따릅니다.

작동 방식

이 메서드는 ?watch=true와 함께 Kubernetes API에 장기 실행 HTTP 연결을 열고 이벤트를 비동기 이터레이터로 산출(yield)해요. 각 이벤트는 클러스터의 리소스에 대한 단일 변경(생성, 수정, 삭제)을 나타내요.

스트림 처리 파이프라인은 다음과 같아요.

  • ?watch=true가 있는 HTTP GET이 스트리밍 연결을 열어요.
  • 응답 본문이 줄 구분 JSON 파서를 통해 파이프되요.
  • 각 줄이 파싱되어 KubernetesWatchEvent로 변환돼요.
  • 이벤트가 async generator를 통해 호출자에게 산출돼요.

사용법

// The watcher is available through the KubernetesWatcher interface
// from @backstage/plugin-kubernetes-node
for await (const event of watcher.watchResource(
  {
    clusterDetails,
    credential,
    group: '', // empty string for core API group
    apiVersion: 'v1',
    plural: 'pods',
  },
  { namespace: 'default', labelSelector: 'app=myapp' },
)) {
  if (event.type === 'ERROR') {
    logger.error(`Watch error: ${event.error.errorType}`);
    break;
  }
  const obj = event.object as any;
  logger.info(`${event.type}: ${obj.metadata.name}`);
}

이벤트 유형

Kubernetes API는 다음 이벤트 유형을 보내며, 모두 지원돼요.

Event type Description
ADDED A resource was created or already exists at watch start.
MODIFIED A resource was updated.
DELETED A resource was removed.
BOOKMARK A checkpoint for the current resource version (minimal object).
ERROR An error occurred, such as an expired resource version.

ADDED, MODIFIED, DELETED 이벤트는 object 필드에 완전한 Kubernetes 객체를, resourceVersion 필드에 리소스 버전을 포함해요. BOOKMARK 이벤트는 최소 객체(일반적으로 metadata.resourceVersion만)를 포함해요. ERROR 이벤트는 errorType과 statusCode를 가진 구조화된 KubernetesFetchError를 포함해요.

감시 옵션(Watch options)

KubernetesWatchOptions 인터페이스는 다음 매개변수를 지원해요.

Option Type Description
namespace string Namespace to watch (omit for cluster-scoped resources).
labelSelector string Label selector to filter resources.
resourceVersion string Resource version to start watching from.
timeoutSeconds number Server-side timeout for the watch connection.
allowWatchBookmarks boolean Enable bookmark events for efficient version tracking.
sendInitialEvents boolean Begin the stream with synthetic events reproducing current state, ending with a bookmark annotated k8s.io/initial-events-end. Requires Kubernetes 1.32+ (Beta).
resourceVersionMatch 'NotOlderThan' | 'Exact' How the resource version constraint is applied. Set to NotOlderThan when using sendInitialEvents so the server can serve from its watch cache.
signal AbortSignal Abort signal to cancel the watch from outside the iteration loop.

그룹화된 API 리소스 감시

이름 있는 API 그룹의 리소스를 감시하려면 그룹, 버전, 복수형 이름을 제공하세요.

for await (const event of watcher.watchResource(
  {
    clusterDetails,
    credential,
    group: 'stable.example.com',
    apiVersion: 'v1',
    plural: 'crontabs',
  },
  { namespace: 'production' },
)) {
  // handle events
}

오류 처리

watch 메서드는 기존 get과 list 연산이 사용하는 것과 같은 errors-as-data 패턴을 따라요. 오류는 예외로 던져지는 대신 이벤트로 산출되므로, 소비자는 같은 for await 루프에서 처리해요.

오류에는 세 가지 범주가 있어요.

  • HTTP 오류(예: 401 Unauthorized, 404 Not Found): 메서드는 단일 ERROR 이벤트를 산출하고 중지해요. 오류 유형은 get/list 연산과 같은 상태 코드 매핑으로 매핑돼요.
  • Kubernetes API의 스트림 오류(예: 리소스 버전 만료에 대한 410 Gone): 이는 스트림에서 ERROR 유형 이벤트로 도착하며 소비자에게 산출돼요.
  • 잘못된 JSON: 잘못된 줄은 기록되고 스트림을 방해하지 않고 건너뛰어져요.

인증

watch 메서드는 Kubernetes 백엔드 플러그인의 나머지와 같은 인증 메커니즘을 재사용해요. 서버 측 인증 프로바이더(serviceAccount, googleServiceAccount, aws, azure, localKubectlProxy)는 watch 연결과 함께 작동해요. 클라이언트 측 인증 프로바이더(google, oidc, aks)는 watcher가 장기 실행 백엔드 연결로 실행되며 브라우저 매개 자격 증명을 새로 고칠 수 없기 때문에 지원되지 않아요.

취소(Cancellation)

반복 루프 밖에서 watch를 중지하려면 AbortSignal을 전달하세요.

const controller = new AbortController();
// Cancel the watch after 30 seconds
setTimeout(() => controller.abort(), 30_000);
for await (const event of watcher.watchResource(
  {
    clusterDetails,
    credential,
    group: '',
    apiVersion: 'v1',
    plural: 'pods',
  },
  { namespace: 'default', signal: controller.signal },
)) {
  // handle events — loop ends cleanly when signal fires
}

for await 루프에서 벗어나는 것도 watch를 중지하고 기본 HTTP 연결을 정리해요.

제한 사항

  • 자동 재연결 없음. watch 연결이 끝나면(시간 초과, 네트워크 오류, 서버 측 연결 끊김으로) 소비자가 재연결해야 해요. 변경을 놓치지 않고 재개하려면 마지막으로 받은 이벤트의 resourceVersion을 사용하세요.
  • informer 동작 없음. 이것은 저수준 watch 프리미티브예요. 로컬 캐시를 유지하지 않고, 자동 list-watch 초기화를 수행하지 않으며, 주기적 재동기화를 처리하지 않아요. 이런 고수준 패턴은 watch API 위에 구축할 수 있어요.
  • 호출당 단일 리소스 유형. 각 watchResource() 호출은 하나의 리소스 유형을 감시해요. 여러 리소스 유형을 감시하려면 별도의 호출을 하세요.

더 알아보기 (Learn more)