'데이터 엔지니어'로 성장하기

정리하는 걸 좋아하고, 남이 읽으면 더 좋아함

기타/K8S

K8S) 망가진 클러스터 심폐소생술 하기_disk,memory부족

MightyTedKim 2024. 9. 30. 00:43
728x90
반응형

평화로운 오후 갑자기, 회사 K8S가 이상하다는 연락이 옵니다

회사 서버실에 있는 쿠버네티스
나는 1년 동안 들어가본적이 없는 쿠버네티스
하지만 내가 살려야하는 쿠버네티스


 

돌이켜보면 별거 없지만, 클러스터 되살린 과정을 적어보려고 합니다.
 
예상 독자는 아래와 같습니다

1. k8s 리소스 정리가 필요한 분
2. worker disk pressure, memory 부족이 발생하는 분
3. k8s 이슈 발생시, 확인

환경은 아래와 같습니다.

1. 온프렘

2. master 3, worker 3

3. k8s 1.30 /// ubuntu 22.04

 

(스포) 를 원하시면 아래 [더 보기]를 눌러주세요

더보기

[상황 파악]

  1. 무슨 이유에서 인지, ceph에서 문제 발생  (ceph core 덤프 파일이 /var/lib/rook-ceph에 저장)

     -> 디스크 부족

  2. /var/lib/docker에 영향을 주며 containerd-shim이 정신을 못차림 (pod이 제대로 지워지지 않고, 리소스를 계속 소모)

     -> 메모리 부족

[문제 해결] 

  1.  /var/lib/rook-ceph 의 core 파일 살제 

     -> 디스크 부족 해결

  2. containerd 재시작, image 삭제, container 삭제

     -> 메모리 부족 해결


자 이제 상황을 파악해봅시다 ㅜ

(대충, 왜 내가 이걸하는지 모르는 짤)

1. 진단하기

그라파나도 내려가있었기 때문에, CLI로 확인해봅니다.

 

$ k get po -A 
> 너무 에러가 많아 잠시 외면합니다.
 
$ k top nodes
> worker memory 이슈 확인

$k top nodes
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
k8sm01.hgkim.biz 211m 5% 7384Mi 46%
k8sm02.hgkim.biz 218m 5% 6714Mi 42%
k8sm03.hgkim.biz 563m 14% 5830Mi 36%
k8sw01.hgkim.biz 1983m 24% 91196Mi 94%
k8sw02.hgkim.biz 1502m 18% 59698Mi 61%
k8sw03.hgkim.biz 1040m 13% 76341Mi 79%

 
$ k get event -w
> disk 이슈도 있군요! 어질어질 합니다.

$k get event -w
LAST SEEN TYPE REASON OBJECT MESSAGE
3m8s Warning EvictionThresholdMet node/k8sw01.hgkim.biz Attempting to reclaim ephemeral-storage

 
$ k get po -n kube-system
> metric이 떠있긴한데, pod당 3~4기가를 실행합니다. 쎄합니다.


심호흡을 하고 다시 들여다봅니다.
뭘하다가 이렇게 망가질 때까지 혹사 시켰을까.

$ helm ls -A
redis, mongodb, stackable, strimzi, kafka, superset, cvat, mlrun, kiali stackable-stable, metallb flink-operator, mysql-operator, mairadb-operator, spark-operator, openebs 등
> 원인이 풀렸습니다. 이것 저것 설치하고, 제대로 안지운 분들이 계셨군요
 
$ k get ns / k get crd / k get pv / k get crd
> 여기도 상황이 크게 다르지 않았어요.
cluster가 error를 뱉으면 울부짖어도 최근까지 test를 하셨더라고요
 
이쯤 되면 그냥 "지우고 다시 깔까?" 라는 생각을 하게됩니다.
하지만 고쳐보고 싶은 욕구가 생기더라고요


2. 정밀 진단하기

살리기로 결정했으니, 좀 더 뜯어보죠

[memory 관련]

$ k describe node k8sw01
> memory pressure 발생했으나, worker에는 사용률이 거의 0%임

 분명 k8s는 memory 부족하다고 node 상세는 멀쩡하데요

Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits Age
--------- ---- ------------ ---------- --------------- ------------- --- 
auth dex-594d497cfb-2dn75 0 (0%) 0 (0%) 0 (0%) 0 (0%) 19d
kube-flannel kube-flannel-ds-m8g27 100m (1%) 0 (0%) 50Mi (0%) 0 (0%) 121d
kube-system fluentd-rvb89 100m (1%) 0 (0%) 200Mi (0%) 200Mi (0%) 18d
kube-system kube-proxy-hm2h2 0 (0%) 0 (0%) 0 (0%) 0 (0%) 139d
rook-ceph csi-cephfsplugin-pjvck 0 (0%) 0 (0%) 0 (0%) 0 (0%) 398d
rook-ceph csi-rbdplugin-qrhxh 0 (0%) 0 (0%) 0 (0%) 0 (0%) 398d
rook-ceph rook-ceph-crashcollector-k8sw01.hgkim-549b679f8b-9tcjj 0 (0%) 0 (0%) 0 (0%) 0 (0%) 31d
rook-ceph rook-ceph-mon-u-65d779884-6rjf7 0 (0%) 0 (0%) 0 (0%) 0 (0%) 31d
rook-ceph rook-ceph-osd-0-79d994df4b-9l6dx 500m (6%) 1 (12%) 1025Mi (1%) 3Gi (3%) 37d 

직접 서버에 들어가서 리소스를 확인해봅니다.


$ (k8sw01) top

> worker가 살려달라고 부르는군요.

또 이상해요.

pod 들 실행되는것 다 내렸는데 93% 메모리를 사용하고 있어요.
active process 1개에, 221개는 sleeping고...

 

일단 메모리 이슈는 싱크가 안맞는구나라고 추정하고 넘깁니다.

디스크도 봐야하니까요

[disk 관련]

디스크를 봅니다.

$ df -h
> 음 왜 root 32G나 잡혓는데 29G를 쓰는걸까

 

조금 더 자세히 봅니다.

$ du -d 1 -h /var/lib
> 이제 어디가 문제인지 찾으러 들어가봅시다.

$ du -d 1 -h ./ 
(생략)
/var/lib/rook/rook-ceph/log 24G

$ls -alh | grep G 합계 24G
-rw------- 1 167 167 1.1G 8월 12 11:13 core.10020
-rw------- 1 167 167 1.3G 8월 11 13:11 core.11395
-rw------- 1 167 167 1.1G 6월 2 23:57 core.14002
(생략) 

rook-ceph에서 log 쌓는 위치를  root로 했군요..
왜 그랬을까요 어쨋든 진단은 완료했습니다

 

1. 무슨 이유에서 인지, ceph에서 문제 발생

2. ceph core 덤프 파일이 snapshot 들이 debugging을 위해 계속 저장이되었고
3. 공교롭게 /var/lib/rook-ceph에 저장되며 root disk가 부족
4. /var/lib/docker에 영향을 주며 containerd-shim이 정신을 못차림
5. pod이 제대로 지워지지 않고, 리소스를 계속 소모함
6. k8s worker01 ephemoral 발생

 

> 결론: 디스크는 부족한게 맞는데, 메모리는 넉넉하다. 


3. 조치하기

[memory 관련]

containerd-shim이 너무 많은 리소스를 사용하고 있어요.
라이프사이클 확인하는 친구가 너무 높은 건 말이 매우 이상해요
>  containerd가 이상하다는 결론을 내려봅니다.
 
$ crictl ps -a
> 없어져야하는 pod들이 다 떠있어요
 
$ crtictl stop 4b 
> 삭제가 안되요

WARN[0000] runtime connect using default endpoints: [unix:///run/containerd/containerd.sock unix:///run/crio/crio.sock unix:///var/run/cri-dockerd.sock].
As the default settings are now deprecated, you should set the endpoint instead. E0912 13:29:28.644952 48339 remote_runtime.go:366] "StopContainer from runtime service failed" err="rpc error: code = Unknown desc = failed to kill container \"4b9b153ae9b4fa4af759b820e4320ac986327cd983c08ac9f8b27e0f6d8fcfd1\": unknown error after kill: open /dev/null: too many open files: <nil>: unknown" containerID="4b9" FATA[0000] stopping the container "4b9": rpc error: code = Unknown desc = failed to kill container "4b9b153ae9b4fa4af759b820e4320ac986327cd983c08ac9f8b27e0f6d8fcfd1": unknown error after kill: open /dev/null: too many open files: <nil>: unknown

 
ulimit 확인해보니 too many files 이슈는 아니에요
 
$ sudo systemctl restart containerd
> containerd를 재시작해줍니다
 
$ crictl ps -a | grep Exited
> 다시 시작했는데도 찌거기가 남아있어요
주로 storage pod 관련 이라서, ephemeroral-storage 에러가 발생했음을 기억했어요

 
$ crictl rm $(crictl ps -a --state Exited -q)
> 귀찮으니까 한번에 다 지워줍니다.

[disk 관련]

아까 /var/lib/rook-ceph가 문제였죠
$ sudo rm -f /var/lib/rook/rook-ceph/log/core.*

# before
$df -h
Filesystem      Size  Used Avail Use% Mounted on/dev/xvda2       32G   29G  2.8G  92% /
# after
$df -h
Filesystem      Size  Used Avail Use% Mounted on/dev/xvda2       32G  5.4G   27G  17% /

 

[기타]

$ k get po -A 
> 정상이네요 ㅎㅎ
 

어 근데 리소스 과하게 쓰는게 있어요
$ k top po -A  | grep kube-system
> metrics 가 이상해요

kube-system kube-apiserver-k8sm01.hgkim.biz 67m 3503Mi 
kube-system kube-apiserver-k8sm02.hgkim.biz 73m 3407Mi
kube-system kube-apiserver-k8sm03.hgkim.biz 332m 3445Mi

 

$ kubectl get --raw "/metrics" | grep apiserver_request_total
# 지워지지 않은 찌거기들까지 계속 call 합니다.
 
하나씩 지워줍니다
$ kubectl get crd | grep kubeflow | awk '{print $1}' | xargs kubectl delete crd
# kubectl delete crd kialis.kiali.io profiles.kubeflow.org runners.actions.summerwind.dev zookeeperznodes.zookeeper.stackable.tech

 
함참을 지워줍니다. finalize로 안지워지는것들도, hpa 들도 안쓰는건 다 지워줍니다.

kube-apiserver-k8sm01.hgkim.biz 54m 1778Mi
kube-apiserver-k8sm02.hgkim.biz 56m 1776Mi
kube-apiserver-k8sm03.hgkim.biz 111m 1755Mi

 
정상화는 되었고, pod rebalancing은 따로하지는 않앗어요

NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
k8sm01.hgkim.biz 199m 4% 5984Mi 37%
k8sm02.hgkim.biz 278m 6% 4936Mi 31%
k8sm03.hgkim.biz 453m 11% 4008Mi 25%
k8sw01.hgkim.biz 337m 4% 28178Mi 29%
k8sw02.hgkim.biz 1269m 15% 79605Mi 82%
k8sw03.hgkim.biz 2396m 29% 73705Mi 76%

후기

재발 방지를 위해 이제 배포는 argocd로 진행하기로 했어요.
물론 급하다고 다른 방식으로 설치하겠죠 ㅜ
 
온프렘 서버도, rancher 이용해서 k8s 자동화해야하나 싶네요

728x90
반응형