쿠버네티스(Kubernetes, K8s) 실험과 배운 것들에 대한 회고록

2025. 12. 6. 20:31·Infra/DevOps

길고 길었다...

아주 길고 긴 이야기란다...

아래는 이번에 K8s를 직접 홈서버 4대에 구현하고 실험해보면서 느낀바를 정리한 내용이다


1. K8s는 nginx랑 전략이 다르다

- nginx 때는 Weighted round robin로 서버에 맞춰 튜닝했지만, K8s는 그런 식으로 튜닝할 수 없었다

- K8s의 장점은 '수평확장'

- 이 장점을 최대한 끌어내려면 그에 맞춰 구조를 변경해야했다

- 이전과 동일한 환경에서의 테스트는 불가하다는 것

- 각자의 장점과 쓰임이 다르다고 판단했음

- K8s의 최대 장점은 '수평확장'이니 이것을 극대화하기로 했다


2. 그럼에도 통일한 부분

맥미니 : 쿱네 전용 nginx 담당 / 나머지 : 노예

- 다만 이전 분산 시스템 튜닝과 비슷하게 하고 싶었던 점이 몇가지 있었다

- 우선 맥미니는 Ingress-nginx만 담당하게했다

- Ingress-nginx는 쿠버네티스 전용 nginx라고 이해하면 편함

- 나머지는 worker 노드로써만 동작하게 했다


3. 맥미니가 힘들다네요

맥미니 : 주겨줘...

- 레플리카(replica)는 초기엔 20개로 제한되어있었지만, 성능저하가 오길래 200개까지 늘렸다

- 이때 맥미니의 I/O가 병목이 되었다 (예전에는 맥미니가 로드밸런서만을 담당했고 튜닝도 되어있어서 문제가 없었다)

- 지금의 맥미니는 LB(Load Balancer, 로드 밸런서)가 아니라 Ingress-nginx pod(파드)를 위한 Node Port Gate Way가 됐기 때문이다

- 쉽게 말해서 nginx를 담당하는 pod에 도달하기 위한 통로일 뿐 그 외 어떠한 역할도 없다

[왼쪽] nginx 튜닝 / [오른쪽] 쿠버네티스 사용

- 근데 이것을 해결하고자 하니 Ingress-nginx pod 갯수를 늘려야했다

- 근데? 지금 Ingress-nginx가 맥미니에서만 생기니까 늘려도 의미가 없음

- 하드웨어적으로 같은 노드에서 파드를 추가해봤자 병목은 해소가 안됨 -> 하드웨어 리소스 부족으로 인한 병목이라서

- 실제로 좀 공부해보니 현재의 병목은 L7(nginx)단계가 아니라 L4(커널/NIC/커넥션 단) 문제라서 단순히 맥미니 노드의 Ingress-nginx 파드를 늘린다고 해결되지 않음

- 쉽게 말해 나는 팔이 2개뿐이라, 팔이 10개 달린 옷을 입혀도 2개밖에 못 넣는다


4. 정확히 문제가 무엇일까?

- 쉽게 말하면 아래와 같다

1) nginx로 일할 애들이 부족하다? 이것은 파드 증가로 해결 가능
2) 커널의 NIC interrupt / TCP accept Queue 문제 etc? 이런 것들은 파드 증가로 해결 불가능

- 즉, 현상황에서 필요한 것은 CPU, RAM 따위가 아니다

- NIC(네트워크 인터페이스), TCP accept Queue, 커널 Interrupt 따위임

- 이런 것들은 파드를 늘린다고 늘어나는 것이 아니니 의미가 없다 

- pod는 서버 자원을 공유해서 쓰고 있고, 현재 부족한 것은 하드웨어 리소스니까

- 이에 대한 증거가 K6 테스트에 떴던 에러들이다

'Cannot ssign requested address

- 이것들은 ephemered port 고갈, contact saturated, TCP Socket blocking overflow 오류 등

- 이것들은 곧 L4가 병목이라는 반증이다


5. 그럼 어떻게 해결할까?

흠냐링

- 이 부분을 해결하려면 K8s의 장점을 잘 살려야함

- 즉, 다른 노드(서버)들에도 Ingress-nginx 파드를 생성하는 것임

- 그렇게 되면 다른 노드들의 하드웨어 I/O를 가져다 쓸 수 있으니까

- 다만 각 서버는 하드웨어적으로 분리되어 있으니, 각 서버의 IP가 다를 수 있고, 여러 서버를 하나처럼 쓰기 위해서는 로드 밸런싱이 필요하다 

- 여기서 쓰는 것이 MetalLB임

- MetalLB는 온프레미스(on-premise) 환경에서도 Kubernetes Service를 사용할 수 있게 해주는 로드밸런서 솔루션이다


6. 주의해야할 점

- 어찌됐건 맥미니는 컨트롤 플레인(Control Plane, 일종의 관리자)임

- 관리자가 최전선에서 같이 일하다가 죽으면 다 터지기 때문에 맥미니엔 필수 pod을 제외한 worker pod 생성을 막아둬야 함

- 필수는 etcd, kube-apiserver, controller, scheduler 등등 많음

- 그래서 보통 마스터 노드 taint라는 것을 설정함

- 이 상태에서 각 노드에 Ingress-nginx를 Daemonset으로 설정함 (DaemonSet은 아래에 간단히 설명)

- 각 노드의 NIC가 직접  트래픽을 받게함

- 즉, 요청을 받는 입구를 여러 개로 늘려서 대용량 트래픽에도 쉽게 터지지 않게 함

- 결국 요청받는 중계기의 성능을 높이고 튜닝을 통해 대용량 트래픽을 찍어누르던 것이 지난번의 nginx LB 기반 분산 시스템

- 모든 트래픽을 모든 노드(서버)에서 분산해서 받는 구조로 안정성을 꾀하는게 K8s 기반 분산시스템

- 이때 LB를 담당하는 'MetalLB'는 외부에 이 여러 개의 노드들이 하나의 IP를 가진 것처럼 보이게 함

- 좀 더 정확히는 VIP(Virtual IP)를 어느 노드로 보낼지 결정함

- 이후에 노드 내부에서 어떤 pod로 보낼지는 Ingress-nginx가 결정함

- MetalLB가 특정 노드를 기준으로 설치되는 것이었다면, 똑같이 NIC가 터졌겠지만, 가상 라우터라서 '모든 곳에 있으면서도 어디에도 종속되지 않는다'

- 물론 MetalLB가 모든 노드에 설치되어 있지만 특정 '노드에만' 종속되어 있진 않다는 의미

- 그러니 이전 분산시스템처럼 별도의 LB 서버는 필요 없다

- 더군다나 이런 식으로 구현하는게 아니라면 Scale Up 되었을 때, 하나의 서버처럼 유기적으로 동작할 수 없을 것이다

(nginx는 서버가 늘어날 때마다 수동으로 서버 IP를 추가해주고, 가중치가 있다면 또 계산해서 배분해야 한다)


7. DaemonSet이란 옵션에 대한 간단한 설명

- DaemonSet = speaker이며 서버 갯수만큼 생김

- Daemonset은 모든 노드에 1개씩 판드시 파드를 띄우는 방식

- pod의 스케줄링 방식 중 하나이다

- Speaker라고 모든 노드에 배치하게 하는 얘가 있음 

- Speaker가 MetalLB에서는 DaemonSet임


8. 그래서 제 결론은요

- 결국 정리하면 기존의 nginx와 로드밸런스를 튜닝해서 얻은 LB 최적화 구조의 분산시스템은 K8s로 구현할 수 없었다 

- 또한 Pod 생성을 서버마다 가중치를 둬서 어느쪽에 더 많이 생성할지 편차도 줄 수 없었음

- 그러나 기본적으로 네트워크나 설계된 구조에 영향을 주지 않으면서 병렬 구조로 수평 확장을 해서 순간적인 성능을 끌어올림으로써 안정성이 유지될 수 있다는 점은 굉장히 인상 깊었음

- nginx와 LB 튜닝은 결국 서버가 추가될 때마다 IP를 등록해주고 튜닝값을 매번 손봐야 한다는 단점이 있다

- 또한, LB가 설치된 중계기의 성능을 찍어누를만큼의 대용량 트래픽이 들어오면 터질 수도 있음

- 반면에 똑같은 조건(서버의 성능, 갯수)이라면 이 모든 노드(서버)들의 NIC를 하나로 묶어 쓸 수 있는 K8s의 안정성이 더 높다는 것이다

- 물론 nginx는 중계기 하나에만 돈을 쓰지만 K8s는 MetalLB로 묶은 모든 노드들의 성능에 돈을 써야하는게 단점일 수 있겠다


9. 이 다음에 시도해볼 부분은?

- 일단은 K8s의 장점을 최대로 끌어내볼 것

- metalLB를 설치해서 각 노드들에 Ingress-nginx를 띄우는 것

- 그리고 다시 K6 부하 테스트를 해보는 것이 다음 목표이다

 

반응형

'Infra > DevOps' 카테고리의 다른 글

iptable-nft 환경에서 VPN 서버 구축하기 (feat. WireGuard)  (0) 2025.12.12
Flannel이란? (feat. 쿠버네티스, Kubernetes, K8s)  (2) 2025.12.07
쿠버네티스(Kubernetes, K8s) 구축 과정에 마주한 에러들  (0) 2025.12.03
홈서버 4대로 쿠버네티스(Kubernetes, K8s) 구축하기  (0) 2025.12.01
Prometheus, Out of Bound 해결방법 (feat. 서버 시간 통일 & TSDB 초기화)  (0) 2025.11.28
'Infra/DevOps' 카테고리의 다른 글
  • iptable-nft 환경에서 VPN 서버 구축하기 (feat. WireGuard)
  • Flannel이란? (feat. 쿠버네티스, Kubernetes, K8s)
  • 쿠버네티스(Kubernetes, K8s) 구축 과정에 마주한 에러들
  • 홈서버 4대로 쿠버네티스(Kubernetes, K8s) 구축하기
Ratatou2
Ratatou2
온갖 정보들을 기록해두는 메모보드 블로그
  • Ratatou2
    nak-z
    · Ratatou2 ·
  • 전체
    오늘
    어제
  • 공지사항

    • 블로그 이전 진행 중 (24.11.25 ~)
    • 분류 전체보기 (303) N
      • OS (89) N
        • Linux (39)
        • Window (24)
        • Mac (21) N
        • Android (5)
      • Infra (83) N
        • DevOps (38) N
        • Docker (14)
        • Jenkins (9)
        • n8n (13)
        • Nextcloud (8)
        • Rasberry Pi (1)
      • Dev (17)
        • JAVA (7)
        • Python (1)
        • DB (3)
        • Vue (2)
        • AI (4)
        • Git (0)
      • Tools (10)
      • Study (69)
        • Algorithm (66)
        • CS (3)
      • Game (10)
        • Project Zomboid (9)
        • Don't Starve Together (1)
      • etc (24)
        • Temp (0)
      • 개발 외 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 인기 글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
Ratatou2
쿠버네티스(Kubernetes, K8s) 실험과 배운 것들에 대한 회고록
상단으로

티스토리툴바