본문 바로가기
Backend

[k8s] kubectl 명령어가 동작하지 않을 때 (왜 쿠버네티스는 스왑 메모리 사용을 허용하지 않는가?)

by 뜨거운 개발자 2024. 9. 17.

문제 상황

kubectl get pods

kubectl 명령을 실행했는데 갑자기 다음과 같은 로그가 나왔다.

E0826 15:09:19.548029    5807 memcache.go:265] couldn't get current server API group list: Get "https://192.168.64.4:6443/api?timeout=32s": dial tcp 192.168.64.4:6443: connect: connection refused
E0826 15:09:19.548319    5807 memcache.go:265] couldn't get current server API group list: Get "https://192.168.64.4:6443/api?timeout=32s": dial tcp 192.168.64.4:6443: connect: connection refused
E0826 15:09:19.550173    5807 memcache.go:265] couldn't get current server API group list: Get "https://192.168.64.4:6443/api?timeout=32s": dial tcp 192.168.64.4:6443: connect: connection refused
E0826 15:09:19.550289    5807 memcache.go:265] couldn't get current server API group list: Get "https://192.168.64.4:6443/api?timeout=32s": dial tcp 192.168.64.4:6443: connect: connection refused
E0826 15:09:19.551557    5807 memcache.go:265] couldn't get current server API group list: Get "https://192.168.64.4:6443/api?timeout=32s": dial tcp 192.168.64.4:6443: connect: connection refused
The connection to the server 192.168.64.4:6443 was refused - did you specify the right host or port?

 

쿠버네티스 공식 페이지에 다음과 같은 이슈가 있었다.

 

https://discuss.kubernetes.io/t/the-connection-to-the-server-host-6443-was-refused-did-you-specify-the-right-host-or-port/552/8

 

The connection to the server <host>:6443 was refused - did you specify the right host or port?

I’m facing the same problems mentioned here. Running 3 node cluster on Digital Ocean. Running CentOS 7.5 droplet as the base OS, and installed the latest Kubernetes (1.12.0) Everything was working fine until I rebooted the server/droplet. Then the ‘con

discuss.kubernetes.io

해결

sudo -i
swapoff -a
exit
strace -eopenat kubectl version

위의 사이트에서 다음과 같은 명령으로 해결했다.

 

문제 원인

 

문제의 원인은 컴퓨터를 재부팅하면서 비활성화했던 스왑 메모리가 다시 활성화되었기 때문이다. 쿠버네티스는 스왑을 지원하지 않기 때문에, 스왑 메모리가 활성화되면 문제가 발생한다.

쿠버네티스는 인스턴스를 가능한 한 최적으로 배치하여 자원을 100% 활용하는 것을 목표로 한다. 모든 배포는 CPU와 메모리 제한을 설정하고, 그 범위 내에서 동작하도록 설계된다. 스케줄러가 포드를 배치할 때 스왑 메모리를 사용하지 않도록 설정해야 하며, 스왑을 사용하면 시스템 성능이 저하되기 때문에 사용하지 않는 것이 기본 원칙이다.


스왑 사용에 대한 논의

1. 스왑을 사용하지 않는 이유 (성능 문제)
스왑을 사용하면 디스크로 메모리가 스와핑되면서 시스템 성능이 급격히 떨어질 수 있다. 따라서 쿠버네티스는 주 메모리만으로 포드를 동작시키는 것을 기본 원칙으로 삼고 있다. 스왑이 성능 저하를 유발할 수 있기 때문에 이를 사용하지 않는 것이 권장된다.

2. 스왑 사용에 대한 반대 의견
스왑을 완전히 사용하지 않는 것은 비효율적이라는 의견도 있다. 리눅스 커널은 스왑을 활용하도록 설계되어 있으며, 메모리 부족 시 OOM(Out of Memory) 킬러가 프로세스를 종료하는 것보다 스왑을 적절히 사용하는 것이 낫다는 주장도 있다. 메모리를 분석하고 스왑 없이 운영하는 것이 이상적이지만, 특정 상황에서는 스왑을 적절히 사용하는 것이 더 나은 해결책이 될 수 있다.

최선의 방법은 포드를 주 메모리에 고정시키고, 필요할 때만 스왑이 발생하도록 설정하는 것이다. 이렇게 하면 성능 저하를 최소화하면서도 메모리 부족 상황을 효과적으로 관리할 수 있다.

3. 쿠버네티스가 스왑을 비활성화하는 이유
쿠버네티스의 kubelet은 스왑 상황을 처리할 수 있도록 설계되지 않았다. 쿠버네티스 팀은 스왑 지원을 구현할 계획이 없으며, 포드는 반드시 호스트의 메모리 내에서만 동작해야 한다는 기본 원칙을 가지고 있다. 스왑 지원은 복잡한 문제이며, 보장된 리소스를 사용하는 포드는 스왑을 사용할 필요가 없다. 반면, BestEffort 포드는 보장된 자원이 없기 때문에 예측 불가능한 메모리 관리가 필요하지만, 현재 kubelet은 포드 간 예측 가능한 행동을 제공하는 데 집중하고 있다.

이와 같은 이유로 쿠버네티스는 스왑을 비활성화하는 것을 기본으로 한다.

728x90