쿠버네티스 로깅에 대한 대략적인 내용과 python client를 통해 log를 가져오는 과정을 정리해보았다. 로깅 아키텍처에 대한 내용은 공식 docs와 참조에 있는 글을 일부 가져와 정리하였다.
Kubernetes Log with kubectl
쿠버네티스는 기본적으로 pod단위의 로그만 제공한다. kubectl log를 통해 간단하게 로그를 확인할 수 있다.
$ kubectl logs <pod> -n <namespace>
kubectl logs 명령은 해당 노드에서 kubelet 서비스를 호출해서 로그를 검색하고 보여준다. kubectl을 통해서는 한 번에 하나의 pod에 대한 로그만 볼 수 있기 때문에, single 스트림으로 많은 pod들을 모아햐할 경우, 별도의 작업 또는 모듈이 필요하다.
Kubernetes Logging Architecture
쿠버네티스 docs와 쿠버네티스 로깅에 대한 가이드 글(logz.io/blog/a-practical-guide-to-kubernetes-logging/)에 대한 내용을 기반으로 정리한 쿠버네티스 로깅 아키텍처이다.
쿠버네티스의 노드 로깅
쿠버네티스에서 실행되는 컨테이너가 stdout 또는 stderr 스트림에 로그를 기록하면, 해당 노드에서 돌고 있는 kubelet 서비스에 의해 로그가 선택되고 , 쿠버네티스에 구성된 로깅 드라이버를 기반으로 처리하기 위해 컨테이너 엔진에 위임된다.
대부분의 경우, 도커 컨테이너 로그는 호스트의 /var/log/container 디렉토리에 저장된다. Docker는 여러 로깅 드라이버를 지원하지만, 쿠버네티스 API는 드라이버 구성을 지원하지 않는다.
컨테이너가 종료되거나 다시 시작되면 kubelet은 노드에 해당 로그를 저장한다. 컨테이너가 노드에서 제거되면, 해당 로그 파일도 제거된다.
operating system과 호스트에서 돌고있는 추가적인 서비스들에 따라, 추가적인 로그를 확인해야되는 경우가 있을 수 있다. 예를 들어, 리눅스 journald log는 journalctl 커맨드를 통해 검색할 수 있다.
$ journalctl -u docker
도커 컨테이너 런타임은 해당 로그를 journald에 기록한다.
노드 레벨에서의 중요한 쿠버네티스 시스템 프로세스는 kubelet과 kube-proxy이다.
kubelet은 로그가 journald에 기록되고, kube-proxy는 각각의 노드에서 실행되는 network proxy로 로그가 /var/log에 기록된다. 쿠베네티스 운영을 하다보면, 이 kubelet 로그 또한 확인할 일이 있으니 참고해두는 것이 좋다.
쿠버네티스의 시스템 컴포넌트 로깅
kubelet과 kube-proxy같은 노드 서비스외에도, 로깅되는 쿠버네티스 클러스터 자체 레벨의 control plane 컴포넌트들과, event나 audit logs같은 추가적인 데이터 타입이 있다. 이런 다양한 유형의 데이터를 활용하면 쿠버네티스가 시스템으로서 수행되는 방식을 이해할 수 있다.
쿠버네티스 control plane의 주요 시스템 컴포넌트
- kube-apiserver : 클러스터에 대한 access point 역할을 하는 API 서버
- kube-scheduler : 컨테이너를 어디에서 실행시킬지 결정하는 스케줄러
- etcd : 쿠버네티스 클러스터의 confiuration 저장소로 사용되는 key-value 저장소
몇몇의 컴포넌트들은 컨테이너로 돌고, 몇몇은 operating system 레벨에서 돈다(대부분 systemd 서비스이다.).
systemd 서비스들은 journald에 기록되고, 컨테이너로 도는 컴포넌트들은 /var/log 디렉토리의 .log 파일에 로그가 기록된다. 컨테이너 내부의 시스템 컴포넌트는 항상 /var/log 디렉토리에 기록된다.
Kubernetes Event
쿠버네티스 이벤트는 리소스의 상태 변경 및 에러, 정보 메시지등을 보여준다.
$ kubectl get events -n <namespace>
Kubernete Log with Python Client
python client의 read log 사용시 몇가지 주의해야할 점이 있어 정리하였다.
우선 python client를 사용한 간단한 로그 수집 코드이다.
from kubernetes import client, config
try:
api = client.CoreV1Api()
response = api.read_namespaced_pod_log(name=pod_name, namespace='default')
print(response)
except ApiException as e:
print('Failed to get pod logs')
호출 시까지 쌓인 로그를 반환하는 간단한 코드이다.
stream으로 log를 지속적으로 받아오고 싶으면 follow 옵션을 사용한다.
이때 follow=True 설정과 함께 _preload_content=False 를 지정해주어야 정상적으로 stream으로 받을 수 있다.
_preload_content 옵션은 urllib3.HTTPResponse 데이터를 decoding해주는 옵션이다.
from kubernetes import client, config
try:
api = client.CoreV1Api()
# get logs with stream
response = api.read_namespaced_pod_log(name=pod_name, namespace='default',
follow=True, _preload_content=False)
for log in response:
print(log)
except ApiException as e:
print('Failed to get pod logs')
kubernetes api 문서를 확인해보면, 다양한 parameter를 사용할 수 있다. 그 중에 sinceSeconds 에 대한 설명은 다음과 같다.
kubernetes.io/docs/reference/generated/kubernetes-api/v1.21/
sinceSeconds | A relative time in seconds before the current time from which to show logs. If this value precedes the time a pod was started, only logs since the pod start will be returned. If this value is in the future, no logs will be returned. Only one of sinceSeconds or sinceTime may be specified. |
sinceSeconds는 말그대로 지정한 몇초 이전 부터의 로그를 반환하는 옵션이고, 설명에 있는 sinceTime 옵션은 지정한 '시간' 부터의 로그를 반환하는 옵션이다.
kubectl logs 옵션에서는, 두가지 옵션 둘 다 제공한다.
--since=0s: Only return logs newer than a relative duration like 5s, 2m, or 3h. Defaults to all logs. Only one of
since-time / since may be used.
--since-time='': Only return logs after a specific date (RFC3339). Defaults to all logs. Only one of since-time /
아쉬운 점은, python client에서는 sinceTime 옵션을 사용할 수 없다.
kubernetes api 코드를 확인해보면, sinceTime, sinceSeconds 둘다 존재하고 kubectl도 해당 api로 옵션을 둘 다 제공하지만, python client에서는 sinceSeconds parameter만 존재한다.
from kubernetes import client, config
try:
api = client.CoreV1Api()
# Only logs from 100 seconds ago
response = api.read_namespaced_pod_log(name=pod_name, namespace='default', since_seconds=100)
print(response)
except ApiException as e:
print('Failed to get pod logs')
since_seconds parameter을 다음과 같이 지정시 100초 전부터의 log만 반환한다.
git issue에 해당 이슈에 대한 요청이 있지만, 아직 반영되지 않은 것 같다.
이후 이슈가 해결되면 내용을 추가하겠다.
github.com/kubernetes-client/python/issues/1351
참조
쿠버네티스의 로깅에 대한 가이드 : 로깅 아키텍처
logz.io/blog/a-practical-guide-to-kubernetes-logging/
Kubernetes Python Client 코드
raw.githubusercontent.com/kubernetes-client/python/master/kubernetes/client/api/core_v1_api.py
Kubernetes API 코드(go)
'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] 쿠버네티스 watch API 사용하기 (python) (0) | 2021.04.05 |