쿠버네티스

[AEWS] 4주차 Kubernetes 이상징후에 알람 받기 (kwatch, botkube)

안녕유지 2025. 3. 2. 04:37
Cloudnet AWES 4주차 스터디를 진행하며 정리한 글입니다.

 

이번 포스팅에서는 쿠버네티스에서 이상징후가 발생하였을 때 알람을 받을 수 있는 도구인 kwatch와 botkube에 대해 알아보도록 하겠습니다.

 

kwatch

kwatch는 Kubernetes 클러스터의 모든 변경 사항을 모니터링하고, 실행 중인 앱의 Crash을 실시간으로 감지하고, 알람을 전송하는 오픈소스입니다.

https://github.com/abahmed/kwatch

 

GitHub - abahmed/kwatch: :eyes: monitor & detect crashes in your Kubernetes(K8s) cluster instantly

:eyes: monitor & detect crashes in your Kubernetes(K8s) cluster instantly - abahmed/kwatch

github.com

 

❯ NICK=hellouz818

❯ cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Namespace
metadata:
  name: kwatch
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: kwatch
  namespace: kwatch
data:
  config.yaml: |
    alert:
      slack:
        webhook: 'https://hooks.slack.com/services/xxx'
        title: $NICK-eks
    pvcMonitor:
      enabled: true
      interval: 5
      threshold: 70
EOF

❯ kubectl apply -f https://raw.githubusercontent.com/abahmed/kwatch/v0.8.5/deploy/deploy.yaml
namespace/kwatch unchanged
clusterrole.rbac.authorization.k8s.io/kwatch created
serviceaccount/kwatch created
clusterrolebinding.rbac.authorization.k8s.io/kwatch created
deployment.apps/kwatch created

 

슬랙 채널에 알람이 추가되었습니다.

 

이제 kwatch가 어떤 상황을 파악하고 알람을 보내주는지 예시 상황을 실습해보겠습니다.

 

우선 첫 번째로, 잘못된 이미지를 실행하는 파드를 배포 하고 kwatch에서 알람이 가는지 확인해보겠습니다.

❯ cat <<EOF | kubectl apply -f -                                                                                   
apiVersion: v1
kind: Pod
metadata:
  name: nginx-19
spec:
  containers:
  - name: nginx-pod
    image: nginx:1.19.19  # 존재하지 않는 이미지 버전
EOF
pod/nginx-19 created

 

슬랙으로 컨테이너가 imagepullback에러가 나는 것을 확인하고 알람이 온 것을 알 수 있습니다.

 

kwatch 파드에도 해당 로그가 남았습니다.

 ❯ ❯ kubectl logs kwatch-587f97fb7f-9829r -n kwatch                                                        ○ myeks 03:49:41
time="2025-03-01T18:45:39Z" level=info msg=":tada: kwatch@v0.8.5 just started!"
time="2025-03-01T18:45:39Z" level=info msg="initializing slack with webhook url: https://hooks.slack.com/services/xxx"
time="2025-03-01T18:45:39Z" level=info msg="sending message: :tada: kwatch@v0.8.5 just started!"
time="2025-03-01T18:45:40Z" level=info msg="starting pod-crash controller"
time="2025-03-01T18:45:40Z" level=info msg="sending message: :tada: A newer version <https://github.com/abahmed/kwatch/releases/tag/v0.10.1|v0.10.1> of Kwatch is available! Please update to the latest version."
time="2025-03-01T18:45:40Z" level=info msg="pod-crash controller synced and ready"
time="2025-03-01T18:48:12Z" level=warning msg="failed to get logs for container nginx-19 in pod nginx-pod@default: the server rejected our request for an unknown reason (get pods nginx-19)"
time="2025-03-01T18:48:12Z" level=info msg="sending event: {Name:nginx-19 Container:nginx-pod Namespace:default Reason:ErrImagePull Events:[2025-03-01 18:48:10 +0000 UTC] Scheduled Successfully assigned default/nginx-19 to ip-192-168-3-43.ap-northeast-2.compute.internal\n[2025-03-01 18:48:11 +0000 UTC] Pulling Pulling image \"nginx:1.19.19\"\n[2025-03-01 18:48:12 +0000 UTC] Failed Failed to pull image \"nginx:1.19.19\": rpc error: code = NotFound desc = failed to pull and unpack image \"docker.io/library/nginx:1.19.19\": failed to resolve reference \"docker.io/library/nginx:1.19.19\": docker.io/library/nginx:1.19.19: not found\n[2025-03-01 18:48:12 +0000 UTC] Failed Error: ErrImagePull\n[2025-03-01 18:48:12 +0000 UTC] BackOff Back-off pulling image \"nginx:1.19.19\"\n[2025-03-01 18:48:12 +0000 UTC] Failed Error: ImagePullBackOff Logs:previous terminated container \"nginx-pod\" in pod \"nginx-19\" not found Labels:map[]}"
time="2025-03-01T18:48:12Z" level=info msg="sending to slack event: &{nginx-19 nginx-pod default ErrImagePull [2025-03-01 18:48:10 +0000 UTC] Scheduled Successfully assigned default/nginx-19 to ip-192-168-3-43.ap-northeast-2.compute.internal\n[2025-03-01 18:48:11 +0000 UTC] Pulling Pulling image \"nginx:1.19.19\"\n[2025-03-01 18:48:12 +0000 UTC] Failed Failed to pull image \"nginx:1.19.19\": rpc error: code = NotFound desc = failed to pull and unpack image \"docker.io/library/nginx:1.19.19\": failed to resolve reference \"docker.io/library/nginx:1.19.19\": docker.io/library/nginx:1.19.19: not found\n[2025-03-01 18:48:12 +0000 UTC] Failed Error: ErrImagePull\n[2025-03-01 18:48:12 +0000 UTC] BackOff Back-off pulling image \"nginx:1.19.19\"\n[2025-03-01 18:48:12 +0000 UTC] Failed Error: ImagePullBackOff previous terminated container \"nginx-pod\" in pod \"nginx-19\" not found map[]}"
time="2025-03-01T18:48:46Z" level=info msg="pod default/nginx-19 does not exist anymore\n"

 

두 번째로 PVC의 저장 공간을 70% 이상 채운 뒤 PVC 알람이 가는지 확인해보겠습니다.

PVC와 pod을 배포하겠습니다. 

# PVC, Pod 생성
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
    - name: test-container
      image: ubuntu
      command: ["/bin/bash", "-c", "sleep infinity"]
      volumeMounts:
        - mountPath: "/data"
          name: storage
  volumes:
    - name: storage
      persistentVolumeClaim:
        claimName: test-pvc
        
# /data 용량 확인
root@test-pod:/# df -h /data
Filesystem      Size  Used Avail Use% Mounted on
/dev/nvme1n1    960M   40M  921M   5% /data

# Pod 접근 후 PVC 용량 채우기
❯ kubectl exec -it test-pod -- bash

# 데이터 생성
fallocate -l 700M /data/testfile.img

# /data 확인
df -h /data
root@test-pod:/# df -h /data
Filesystem      Size  Used Avail Use% Mounted on
/dev/nvme1n1    960M  740M  221M  77% /data

# 100M 추가 후 확인
root@test-pod:/data# df -h /data
Filesystem      Size  Used Avail Use% Mounted on
/dev/nvme1n1    960M  840M  121M  88% /data

 

알람은 오지 않았습니다..

PVC threshold도 70프로로 주었지만, 알람이 오지 않았는데 이유가 무엇일까? (w/GPT)

pvcMonitor 코드를 보고 예상하기로는 kubelet의 /stats/summary API에서 PVC 사용량을 가져와 계산하는 방식인데, kubelet의 /stats/summary API의 PVC 사용량을 kubelet이 제대로 수집하지 못하고, 특히 AWS EBS CSI 볼륨을 사용하는 경우 usedBytes 값이 0이라고 나온다고 하는데,, 아시는 분은 댓글 부탁드립니다.

 

 

 

botkube

Kubernetes 이벤트를 모니터링하고 알람을 보내는 도구입니다.

다만, kwatch와 다른 점은 쿠버네티스 명령어를 실행하여 kubernetes 정보를 조회 가능하다는 것입니다. 또한 커스텀 리소스 기반 알람도 가능하다는 점에서 차이를 가집니다.

 

Discord 채널에서 botkube를 연동해보도록 하겠습니다.

https://docs.botkube.io/installation/discord/

 

Discord | Botkube

You can use Discord app to connect Botkube to your Discord Server.

docs.botkube.io