[kubernetes-event-exporter] 오래된 쿠버네티스 이벤트 조회

쿠버네티스에서 애플리케이션 트러블슈팅을 할 때 쿠버네티스 이벤트(Kubernetes event)가 단서를 제공하는 경우가 많다. 하지만 etcd의 저장 공간 제한 때문에 길어도 며칠 정도밖에 보관되지 않아 시간이 지나면 이벤트를 확인할 수 없어서 원인 파악이 어려워지는 문제가 있다.

kubernetes-event-exporter를 활용하면 이벤트를 로그로 남겨 AWS CloudWatch Logs 나 Elasticsearch 같은 로그 처리 시스템에 저장하고 필요할 때 조회할 수 있다.

Note: 쿠버네티스 이벤트는 kubectl get event, kubectl describe 명령으로 확인할 수 있다.

kubernetes-event-exporter

https://github.com/resmoio/kubernetes-event-exporter/blob/master/README.md

위 가이드에선 이벤트를 모니터링해서 통보하는 설정을 좀 더 비중있게 다루고 있으나 이벤트는 로그로 남기는 것이 더 적합한 것 같다. 모니터링은 Prometehus metric 같은 것으로 하고 문제의 원인을 파악할 때 이벤트 로그를 꺼내보면 된다.

예제 구성

AWS의 CloudWatch Logs를 활용하는 예제이다.

  1. kubernetes-event-exporter는 표준 출력(standard output)으로 이벤트의 로그를 남긴다. 로그는 JSON 형식이다.
  2. DaemonSet으로 실행되는 fluent-bit가 kubernetes-event-exporter 의 표준 출력을 CloudWatch Logs로 전송한다.
  3. CloudWatch Logs Insights 의 쿼리를 사용해 문제가 발생한 시점의 이벤트를 조회한다.

Helm 차트 설치 방법

Bitnami에서 제공하는 Helm 차트를 설치하는 방법이다.

Note: 차트 버전 1.5.2 에서 테스트했으며 이 포스트를 쓰는 시점의 최신 차트 버전인 2.0.0 까지는 같은 방식으로 해야 하는 것을 확인했다.

아래 명령으로 설치할 수 있다.

 1helm repo add bitnami https://charts.bitnami.com/bitnami
 2
 3helm upgrade event-exporter bitnami/kubernetes-event-exporter \
 4  --install \
 5  --create-namespace \
 6  --namespace event-exporter \
 7  --version 1.5.2 \     
 8  --values values.yaml
 9
10kubectl apply -f more-rbac.yaml
11

values.yaml 내용 :

 1image:
 2  repository: public.ecr.aws/bitnami/kubernetes-event-exporter
 3rbac:
 4  create: true # view ClusterRole 을 바인딩하는데 이 권한만으론 부족함. more-rbac.yaml에서  권한을 추가로 부여한다.
 5 
 6config:
 7  logLevel: info
 8  route:
 9    routes:
10      - match:
11          - receiver: "dump"
12  receivers:
13    - name: "dump"
14      stdout: { }
15resources:
16  requests:
17    cpu: 10m
18    memory: 100Mi

more-rbac.yaml 내용:

 1apiVersion: rbac.authorization.k8s.io/v1
 2kind: ClusterRole
 3metadata:
 4  name: event-exporter
 5rules:
 6- apiGroups:
 7  - ""
 8  resources:
 9  - nodes
10  verbs:
11  - get
12  - list
13  - watch
14---
15apiVersion: rbac.authorization.k8s.io/v1
16kind: ClusterRoleBinding
17metadata:
18  name: event-exporter
19roleRef:
20  apiGroup: rbac.authorization.k8s.io
21  kind: ClusterRole
22  name: event-exporter
23subjects:
24  - kind: ServiceAccount
25    name: event-exporter
26    namespace: event-exporter

values.yaml 설명

쿠버네티스의 표준적인 방법대로 로그를 표준 출력으로 내보내게 설정한다. 아래 문서의 가이드대로 config 차트 파라미터를 설정하고 있다.

https://github.com/resmoio/kubernetes-event-exporter/blob/master/README.md#stdout

이렇게 설정하면 로그가 아래처럼 JSON형식으로 출력된다.

1{"metadata":{"name":"kube-proxy-hcctq.171fa332d0d2fca1","namespace":"kube-system","uid":"813df6a8-d912-49a1-9fa6-2d74b061a66f","resourceVersion":"311176937","creationTimestamp":"2022-10-20T01:37:05Z"},"reason":"NodeNotReady","message":"Node is not ready","source":{"component":"node-controller"},"firstTimestamp":"2022-10-20T01:37:05Z","lastTimestamp":"2022-10-20T01:37:05Z","count":1,"type":"Warning","eventTime":null,"reportingComponent":"","reportingInstance":"","involvedObject":{"kind":"Pod","namespace":"kube-system","name":"kube-proxy-hcctq","uid":"19adea83-7bec-4bd4-918d-ddc39e6c4c45","apiVersion":"v1","resourceVersion":"311176399","labels":{"controller-revision-hash":"f6b68b794","k8s-app":"kube-proxy","pod-template-generation":"4"}}} 

Note: 만약 config 파라미터를 설정하지 않으면 아래와 같이 로그의 내용이 빈 상태로 출력된다.

1{}

Helm 차트를 설치하면 아래처럼 기본 설정으로 이벤트를 표준 출력에 덤프한다는 메시지가 출력된다. 이 내용에 따르면 차트 파라미터를 따로 설정할 필요가 없는 것처럼 보이지만 실제로는 그렇지 않으니 주의해야 한다.

1By default, the kubernetes-event-exporter will dump events to stdout.
2To configure additional endpoints, redeploy the chart overwritting the field 'config' at your 'values.yml'.

more-rbac.yaml 설명

values.yaml에서 rbac 파라미터를 true로 설정하면 view ClusterRole을 사용한다. 그런데 그것만으론 권한이 부족헤 kubernetes-event-exporter의 로그에 아래와 같은 에러가 남은다. 부족한 권한을 more-rbace.yaml 로 부여하는 것이다.

12022-10-12T23:35:24Z ERR bitnami/blacksmith-sandox/kubernetes-event-exporter-0.11.0/src/github.com/opsgenie/kubernetes-event-exporter/pkg/kube/watcher.go:75 > Cannot list labels of the object error="nodes \"ip-10-255-14-142.ap-northeast-2.compute.internal\" is forbidden: User \"system:serviceaccount:event-exporter:event-exporter-kubernetes-event-exporter\" cannot get resource \"nodes\" in API group \"\" at the cluster scope"

more-rbac.yaml의 예제에선 nodes에 대한 권한을 부여하고 있는데 클러스터 설정에 따라 권한을 더 부여해야 할 수도 있다.

FluentBbit 로 AWS CloudWatch Logs 로 로그 전송

AWS CloudWatch Logs 에 application 로그를 전송하려면 아래 가이드를 따르면 된다. https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Container-Insights-setup-logs-FluentBit.html

이 가이드대로 FluentBit를 설정하면 로그 내용이 JSON 형식일 때 그 내용을 log_processed 필드로 쿼리할 수 있다. 다음 섹션의 쿼리 예제를 참고한다.

CloudWatch Logs 에서 로그를 조회하는 예제

아래처럼 CloudWatch Logs Insights 쿼리로 검색할 수 있다.

우선 조회할 로그 그룹을 /aws/containerinsights/<cluster-name>/application 으로 설정한다.

아래처럼 쿼리를 실행하면 된다.

1fields @timestamp, log_processed.involvedObject.kind as kind,
2 log_processed.involvedObject.namespace as namespace,
3 log_processed.involvedObject.name as object_name, log_processed.message as message 
4| filter kubernetes.container_name = 'event-exporter' and kind = 'Pod'
5| sort @timestamp asc

결과는 아래와 같다.

Note: 실제로 이벤트가 발생한 횟수보다 kubernetes-event-exporter 에 남는 로그 수가 더 적다. 쿠버네티스는 동일한 이벤트가 근접한 시간에 여러번 발생하면 기존에 etcd에 저장된 이벤트를 업데이트하는데 아마도 kubernetes-event-exporter가 이벤트가 새로 etcd에 생성되는 경우에만 로그를 남기기 때문인 것 같다.

comments powered by Disqus