들어가며
- Kubelet은 클러스터 노드(서버)의 CPU, 메모리, 디스크 공간, 파일시스템 inode와 같은 자원을 모니터링하며 이 때 자원 중 하나 이상이 특정 자원 소모 수준에 도달하면, 자원 고갈을 방지하기 위해 kubelet은 하나 이상의 파드를 중단시켜 자원을 회수합니다.
- 위와 같이 노드 자원을 확보하기 위한 노드-압박 추출이 이루어 질 때 중단 된 Pod는 자원이 충분한 다른 노드로 이동하게 됩니다.
- 만약 단일 노드 이거나 모든 노드가 노드-압박 추출 임계값에 도달 한다면 Pod가 중단 되기 때문에 정상적인 운영이 되지 않는 상황이 발생할 수 있습니다.
- 특히 단일 노드의 경우 노드-압박 축출이 발생 했을 경우 장애가 발생할 수 있기 때문에 운영 담당자는 디스크 및 메모리 자원의 모니터링이 필요합니다.
자세한 쿠버네티스 노드-압박 추출 참고 URL
https://kubernetes.io/ko/docs/concepts/scheduling-eviction/node-pressure-eviction
관련 아티클
[ 그림 1]
모니터링 대상
쿠버네티스에서 노드-압박 추출 모니터링 대상은 Memory, Disk, PID 사용량 이며 기본 임계값 및 모니터링 대상을 알아봅니다.
축출 회수량 기본값(Minimum eviction reclaim)
memory.available<100Mi nodefs.available<10% imagefs.available<15% nodefs.inodesFree<5%
◪ Memory 사용량 모니터링
메모리의 경우 100Mi 이하 일 경우로 기본 값이 설정 되어 있어 노드(서버) 모니터링 시 메모리가 80-90% 이상 사용 시 경고를 통해 메모리로 인한 Pod 축출이 일어나지 않도록 Pod 들의 자원 소비량을 확인 합니다.
◪ 디스크 사용량 모니터링
디스크 사용량의 경우 kubelet의 root 폴더(/k8s_images/k8s) 의 디스크 및 /var/lib/kubelet 폴더가 있는 디스크 사용량을 모니터링 해야합니다.
모니터링 대상은 /k8s_images/k8s 와 /var/lib/kubelet mount 된 디스크의 디스트 사용량을 모니터링 합니다.
주의할 점은 폴더의 마운트 대상의 디스크를 모니터링 해야하며
df 명령어를 사용하여 디스크의 마운트 포인트를 확인 마운트 대상을 확인합니다.
아래 예의 경우
imagefs의 경우 / 사용량(Use%) 85% 이상일 경우 축출 진행되며
nodefs의 경우 /var 사용량(Use%) 90% 이상일 경우 축출 진행 됩니다.
# imagefs df -h /k8s_images/k8s Filesystem Size Used Avail Use% Mounted on /dev/mapper/centos-root 68G 42G 27G 62% / # nodefs df -h /var/lib/kubelet Filesystem Size Used Avail Use% Mounted on /dev/mapper/var-log 68G 42G 27G 62% /var
◪ PID 사용량 모니터링
PID 압박 축출의 경우 PID max 값(/proc/sys/kernel/pid_max)에 도달했을 경우를 기준으로 축출이 이루어지며 /proc/sys/kernel/pid_max 값은 운영 시스템 환경에 맞게 충분하게 할당해야합니다.
[그림 2]
PID 사용량 확인 시 ps -ef | wc -l 와 같이 ps 를 사용할 경우 cAdvisor에서 수집하는 통계가 다릅니다.
Kubelet에서 pid 사용량은 syscall 함수의 Sysinfo의 procs 값을 사용합니다.
Kubernetes go 소스 참고
package pidlimit import ( "io/ioutil" "strconv" "syscall" "time" "k8s.io/apimachinery/pkg/apis/meta/v1" statsapi "k8s.io/kubernetes/pkg/kubelet/apis/stats/v1alpha1" ) // Stats provides basic information about max and current process count func Stats() (*statsapi.RlimitStats, error) { rlimit := &statsapi.RlimitStats{} if content, err := ioutil.ReadFile("/proc/sys/kernel/pid_max"); err == nil { if maxPid, err := strconv.ParseInt(string(content[:len(content)-1]), 10, 64); err == nil { rlimit.MaxPID = &maxPid } } var info syscall.Sysinfo_t syscall.Sysinfo(&info) procs := int64(info.Procs) rlimit.NumOfRunningProcesses = &procs rlimit.Time = v1.NewTime(time.Now()) return rlimit, nil }
cAdviosr metric 내용을 확인하고자 할 경우 마스터 노드에서 https://localhost:10250/metrics URL를 호출하여 metric 데이터를 확인할 수 있습니다.
[그림 3]의 각 축출 신호의 available 값은 metric 데이터를 통해 확인 할 수 있습니다.
[그림 3]
# Metric 데이터 확인 예 curl -isb -H "Accept: application/json" \ https://localhost:10250/stats/summary \ -k --cert /etc/kubernetes/pki/apiserver-kubelet-client.crt \ --key /etc/kubernetes/pki/apiserver-kubelet-client.key
결과 예
"fs": { "time": "2022-11-17T05:54:44Z", "availableBytes": 28068655104, "capacityBytes": 72464121856, "usedBytes": 44395466752, "inodesFree": 34799521, "inodes": 35393536, "inodesUsed": 594015 }, "runtime": { "imageFs": { "time": "2022-11-17T05:54:44Z", "availableBytes": 28068655104, "capacityBytes": 72464121856, "usedBytes": 33406909624, "inodesFree": 34799521, "inodes": 35393536, "inodesUsed": 594015 } }, "rlimit": { "time": "2022-11-17T05:54:45Z", "maxpid": 32768, "curproc": 2696 }
마무리
- 쿠버네티스 환경에서 모니터링이 필요한 자원을 확인해 보았습니다.
- 쿠버네티스 운영 시 모니터링 대상을 참고하여 조금이나마 장애를 미연에 방지할 수 있는데 도움이 되었으면 합니다 :)
아티클이 유용했나요?
훌륭합니다!
피드백을 제공해 주셔서 감사합니다.
도움이 되지 못해 죄송합니다!
피드백을 제공해 주셔서 감사합니다.
피드백 전송
소중한 의견을 수렴하여 아티클을 개선하도록 노력하겠습니다.