Kubernetes Watch
kubernetes.io/docs/reference/using-api/api-concepts/
쿠버네티스는 리소스의 변경을 효율적으로 감지할 수 있는 watch 기능을 제공한다. 기본적으로 watch는 리소스의 생성, 삭제, 업데이트에 대한 알림을 반환한다.
위 docs를 참고하면, 모든 쿠버네티스 객체는 resourceVersion 필드를 가지고 있으며, 이는 DB에 저장된 리소스의 버전을 나타낸다. watch 기능 사용시 resourceVersion을 같이 넘겨주면, 해당 resourceVersion 이후에 발생한 모든 변경 사항을 반환한다.
Example
쿠버네티스 docs에서 제공하는 example이다.
GET /api/v1/namespaces/test/pods?watch=1&resourceVersion=10245
---
200 OK
Transfer-Encoding: chunked
Content-Type: application/json
{
"type": "ADDED",
"object": {"kind": "Pod", "apiVersion": "v1", "metadata": {"resourceVersion": "10596", ...}, ...}
}
{
"type": "MODIFIED",
"object": {"kind": "Pod", "apiVersion": "v1", "metadata": {"resourceVersion": "11020", ...}, ...}
}
...
간단히 설명하자면, resourceVersion=10245 부터의 이벤트(변경 사항)를 반환한다.
type은 이벤트 타입이라고 볼 수 있으며, ADDED(생성) / MODIFIED(수정) / DELETE(삭제) 3종류이다.
각 type과 함께 해당 resource의 정보(metadata)를 함께 반환한다.
주의해야할 사항으로, 쿠버네티스 서버는 제한된 시간 동안만 변경 내역을 보존한다. etcd3를 사용하는 클러스터는 기본적으로 지난 5분 동안의 변경 사항을 보존한다. 만약 요청한 resource의 버전이 유효하지 않으면, 클라이언트는 410 Gone 에러를 반환한다.
Kubernetes Python API
앞에서 본 예제와 같이, wath는 기본적으로 List에 해당하는 쿠버네티스 rest API 들의 query parameter로 제공된다.
GET /apis/batch/v1/namespaces/{namespace}/jobs?watch=true
쿠버네티스 API docs를 참고하면 다음과 같이 watch parameter을 확인할 수 있다.
watch | Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion. |
resourceVersion도 필요시 query parameter로 사용한다.
resourceVersion | resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. Defaults to unset |
따라서 python client에서도 api 사용시 watch parameter를 넘겨주면 된다.
from kubernetes import client, config
config.load_kube_config()
v1 = client.BatchV1Api()
ret = v1.list_namespaced_job(namespace=namespace, watch=True)
kubernetes python client는 watch기능을 wrapping하여 API로 제공한다.
아래와 같이 watch 기능을 사용하고자하는 api를 넘겨주면, 쉽게 stream으로 확인 가능하다.
from kubernetes import client, config, watch
if __name__ == '__main__':
config.load_kube_config()
v1= client.BatchV1Api()
w = watch.Watch()
for e in w.stream(v1.list_namespaced_job, namespace="test"):
print(e)
=>
{'type': 'ADDED', 'object': {'api_version': 'batch/v1',
'kind': 'Job',
'metadata': {'annotations': None,
...
}
API 호출 이후에 발생한 이벤트도 stream으로 출력된다.
참고
watch api 사용하면서 주의해야했던 점들을 남겨보았다.
1. resourceVersion = None
위 예제와 같이 resourceVerison을 함께 넘겨주지 않은 경우, 해당 namepsace에 존재하는 객체들을 ADDED 타입으로 반환한다. '생성되어있는' resource의 의미로 받아들이면 될 것 같다.
2. 410 Error
kubernetes.client.exceptions.ApiException: (410)
Reason: Expired: The resourceVersion for the provided watch is too old.
일정 시간동안 추가 이벤트가 발생하지 않을 경우, 앞서 말했던 410 gone 에러가 발생한다. 해당 에러에도 불구하고 지속적인 이벤트 watch가 필요할 경우 에러 발생시 wath api를 재호출하는 로직 등을 추가하는 방법이 있다.
3. 타입과 상태
watch가 제공하는 type에 따라 어떠한 로직을 추가하고 싶은 경우, 객체의 phase와 같은 상태를 함께 확인하는 것을 추천한다. watch는 3가지 이벤트 타입을 구분하므로 객체의 상태를 확인함으로서 어떠한 이벤트인지 파악하는 과정이 필요하다.
'DevOps > Kubernetes' 카테고리의 다른 글
[CKA] CKA 자격증 준비 자료 정리 4 (Application Lifecycle Management) (0) | 2021.12.11 |
---|---|
[CKA] CKA 자격증 준비 자료 정리 3 (Logging & Monitoring) (0) | 2021.12.07 |
[CKA] CKA 자격증 준비 자료 정리 2 (Scheduling) (0) | 2021.12.06 |
[CKA] CKA 자격증 준비 자료 정리 1 (Core Concepts) (2) | 2021.11.15 |
[kubernetes] 쿠버네티스의 로깅 아키텍쳐와 python client를 통한 로그 수집 (0) | 2021.04.12 |