Computing

Pod 네트워크 (4) : LoadBalancer와 MetalLB (load balancing 개념, MetalLB 역할) 본문

Cloud/Kubernetes

Pod 네트워크 (4) : LoadBalancer와 MetalLB (load balancing 개념, MetalLB 역할)

jhson989 2023. 3. 27. 22:07

이전글

Pod 네트워크 (1) : Service 필요성과 개념, 종류 (ClusterIP, NodePort, LoadBalancer)

- Pod 네트워크 (2) : Service 내부 구현 분석 (kube-proxy와 iptables)

- Pod 네트워크 (3) : kube-proxy와 CNI plugin 차이

 

이전 포스터에서 Pod를 내, 외부 네트워크에 공개하는 Service 개념에 대해서 정리하였다. 이번 포스터에서는 Service들 중 LoadBalancer type Service의 개념과 이것을 사용하기 위해 필요한 MetalLB에 대해서 정리하고자 한다.

 

 

 

Load Balancing과 Load Balancer

Load Balancing, 부하 분산[2]은 여러 개의 프로세싱 유닛(CPU core 단위가 되었든, 서버 단위가 되었든)에 일(부하)를 나누는 기술을 의미한다. 인터넷 웹사이트를 예로 들면 사용자 수천 명이 웹사이트에 접속하는 경우를 생각해보자. 수천 개의 웹사이트 요청 하나하나를 일(load, 부하)이라고 하고, 이를 웹사이트 서버(호스트) 여러 대에 나눠주는 일을 load balancing이라고 한다. 웹사이트 요청을 처리하는 서버가 10대가 있다고 할 때, 10대의 컴퓨터에 고르게 일을 배분하는 것이 매우 중요한 일이 될 것이다.

 

Fig 1. Load Balancer 개념 [3]

 

Fig 1.은 load balancing 기능을 수행하는 load balancer의 역할을 보여주는 그림이다. Fig 1.과 같이 다양한 Clients가 접속하는 네트워크 상의 엔트리가 되며, 각각의 Client들은 load balancer에 사용자 요청(트래픽)을 전송한다. Load balancer는 내부 load balancing 규칙에 따라 들어오는 사용자 요청을 내부 Server들에게 배분한다.

 

Load balancing algorithm은 구체적으로 두 가지 타입, static load balancing, dynamic load balancing으로 구분된다. Static load balancing은 미리 작업의 양과 프로세싱 유닛의 능력 등, 전반적인 정보를 모두 알고 있는 상황에서 사용하는 기법으로 미리 일을 어떻게 배분할 것인가 규칙을 세워둔다. 반면에 dynamic load balancing은 일의 양을 모르는 상태(일이 얼만큼 들어올 지, 하나의 일이 얼마만큼 시간이 걸릴 지 등)에서 사용하는 기법으로 실시간으로 프로세싱 유닛의 상태를 확인하며 일을 배분한다. 대부분의 IT 서비스는 일의 양을 모르는 경우가 많기에 dynamic load balancing 기법을 사용할 것이다.

 

Fig 2. Round Robin 방식의 load balancing 알고리즘 [3]

 

간단하게 load balancing 알고리즘을 소개하자면 다음과 같다. 가장 기본적으로 Fig 2.와 같이 Round Robin 방식의 load balancing이 있을 것이다. Round Robin 방식의 경우 들어오는 트래픽을 서버들에게 순차적으로 배분한다. 해당 서버가 바쁘든 상관없이 순서가 되면 일을 할당한다. 간단히 구현할 수 있지만 가장 효율적이지는 않을 것이다. 다음으로 least response time 방식의 load balancing 알고리즘도 있다. Load balancer가 서버들에게 상태 확인을 위한 요청을 날렸을 때 가장 빨리 반응하는 서버에게 일을 할당하는 방식이다. 가장 빨리 반응한 서버가 현재 가장 여유롭다는 것을 가정하고 작동하는 알고리즘으로 Round Robin에 비해서는 조금 더 효율적일 것이다.

 

Load balancer는 실제 물리적인 하드웨어로 존재할 수도 있고, 혹은 서버에 소프트웨어로 설치될 수도 있다. Load balancing 전용 하드웨어로 존재하는 경우 아무래도 일반적으로 성능이 더 좋다. 다만 이 경우 하드웨어를 구매해야 하기에 운영 측면에서 비용이 발생한다. 비용을 아끼고 싶다면 컴퓨터에 설치하는 소프트웨어로 load balancer를 구현할 수도 있다. 다만 이 경우에는 전용 하드웨어가 아니기에 성능 상의 한계가 분명히 존재할 것이다.

 

 

 

LoadBalancer Type Serivce

이전 포스터에서 Pod 서비스를 외부에 공개하기 위한 Service 리소스에 대해서 정리하였다. 외부 클라이언트는 Service 리소스를 통해 Pod의 애플리케이션 워크로드에 접근할 수 있다. Service 리소스 중에는 ClusterIP, NodePort, LoadBalancer 타입이 있다. ClusterIP는 쿠버네티스 클러스터 내 고정된 가상 IP를 Pod에 제공하는 Service이다. NodePort는 쿠버네티스의 각 노드의 포트를 예약하여, 해당 포트로 들어오는 트래픽을 Pod로 제공하는 Service이다.

 

오늘 포스터에서 정리할 LoadBalancer는 같은 애플리케이션을 서비스하는 Pod들에 가상의 IP(Virtual IP, VIP)를 제공해주는 서비스이다. 이때 이 VIP는 외부에서 접근가능한 IP이다. LoadBalancer라는 이름에서 알 수 있다시피, VIP(load balancer의 IP와 마찬가지 개념)로 들어온 트래픽을 쿠버네티스는 같은 애플리케이션을 서비스하는 Pod들의 집단에 배분하는 역할을 수행한다. 앞서 설명한 Load balancer와 마찬가지 역할을 수행한다.

 

LoadBalancer 타입 서비스는 같은 동작을 수행하는 여러 개의 Pod들을 하나의 애플리케이션으로 제공하는 목적으로 사용된다. 즉 Deployment로 배포된 같은 이미지의 여러 복제본을 하나의 VIP로 묶어서 사용자들에게 제공하는 용도로 많이 사용된다. 애플리케이션을 구성하는 실제 Pod의 숫자가 아무리 많더라도 LoadBalancer 타입 서비스를 이용하면 하나의 애플리케이션을 하나의 IP로 제공할 수 있게 된다. 이를 통해 개발자는 쉽게 scale-out하거나 중단 없는 서비스를 제공할 수 있고, 실제 사용자들 입장에서도 하나의 IP만 보이기에 사용하기 편리하다.

 

 

 

MetalLB 

LoadBalancer 타입 서비스를 사용하기 위해서는 실제 물리적인 External Load balancer 혹은 MetalLB[1]가 필요하다. 구글이나 아마존과 같은 클라우드 플랫폼 회사는 자체 Load balaner를 지원하나, 직접 쿠버네티스를 구축한 경우 (Bare-metal 환경)에는 LoadBalancer 타입 서비스를 이용하기 위해서 MetalLB를 쿠버네티스 상에 배포해야만 한다.

 

실제로 직접 쿠버네티스 클러스터를 구축한 상황에서 LoadBalancer 타입 서비스를 이용할 경우 상태가 "Pending"으로 고정된 채 작동하지 않는 것을 확인할 수 있다. 이는 쿠버네티스가 내부적으로 LoadBalancer 타입 서비스를 위한 구현을 직접하지 않기 때문으로, 쉽게 생각하면 쿠버네티스는 자체적으로는 어떤 VIP를 LoadBalancer에 할당해야 할 지 모른다. 따라서 LoadBalancer 타입 서비스는 VIP를 할당받지 못한 채 Pending 상태로 머물러 있게 된다.

 

쿠버네티스 내에서 MetalLB의 역할은 크게 다음과 같은 2가지이다.

    (1) Address allocation

    (2) Exterenal Announcement

 

 

[Address allocation]

LoadBalancer 타입 서비스는 외부에서 접근할 수 있는 public IP를 VIP로 할당받아야 제대로 작동할 수 있다. 문제는 쿠버네티스는 어떤 IP를 사용할 수 있는 지 알 수 없다. MetalLB는 쿠버네티스를 대신하여 LoadBalancer에 외부에서 접근할 수 있는 VIP를 할당하는 역할을 수행한다.

 

다만 당연한 말이게도 MetalLB는 public IP 자체를 생성하지는 못한다. Public IP 자체는 인터넷 사업자만이 개인에게 부여해줄 수 있고, 우리는 이를 돈을 주고 구매하여 미리 public IP를 준비해야 한다. MetalLB는 미리 준비된 IP 중 하나를 쿠버네티스의 LoadBalancer에게 할당하는 역할을 수행한다.

 

예를 들어 내가 100.0.0.0/24 대역의 256개의 IP를 돈을 주고 할당받았다고 하자. 이를 MetalLB에 알려주면, 추후 LoadBalancer가 생성될 때 MetalLB가 100.0.0.0/24 대역의 IP 중 하나를 해당 서비스에 할당한다. LoadBalancer가 종료되며 자동으로 해당 IP를 회수한다. 즉 MetalLB는 준비된 public IP 대역을 기반으로 자동으로 LoadBalancer에게 IP를 할당 및 해제하는 역할을 수행한다. 

 

 

[Exterenal Announcement]

LoadBalancer에 외부 IP 주소가 할당된 이후에는 쿠버네티스 뒤에 있는 네트워크에게 해당 IP가 "살아있음"을 알려야 한다. 그래야 라우터가 해당 IP로 들어오는 패킷을 해당 IP로 전송해 줄 수 있다. 해당 IP가 살아있음을 알리는 방법에는 ARP, NDP, or BGP 모드가 있다는데 가장 간단한 ARP 모드[4] 기반으로 설명하면 다음과 같다.

 

ARP 모드에서는 쿠버네티스 내 여러 노드 중 하나가 해당 IP의 주인이 된다. 즉 쉽게 생각하면 해당 노드는 자기 자신의 원래 IP 뿐만 아니라, LoadBalancer의 IP를 동시에 가지게 되는 것과 똑같다. 따라서 LoadBalancer의 IP로 들어오는 트래픽은 해당 IP의 주인이 된 노드로 전송된다. 그 노드는 내부적으로 NodePort를 통해 최종 Pod로 트래픽을 전송한다.

 

이때 ARP(Address Resolution Protocol)은 주소 결정을 위해 사용되는 프로토콜이다. LoadBalancer IP로 들어온 트래픽을 받은 라우터는 해당 트래픽이 어디로 전송되어야 하는 지, 주소를 찾기 위해 ARP 프로토콜을 사용한다. 라우터가 LoadBalancer IP가 어디로 가야하는 지 ARP 프로토콜을 통해 물어보면 MetalLB에 의해 주인이된 노드가 자신으로 보내달라고 라우터에게 알리는 방식으로 작동한다.

 

 

 

Reference

[1] https://metallb.universe.tf/concepts/

[2] https://ko.wikipedia.org/wiki/%EB%B6%80%ED%95%98%EB%B6%84%EC%82%B0

[3] https://phoenixnap.com/kb/load-balancing

[4] https://ko.wikipedia.org/wiki/%EC%A3%BC%EC%86%8C_%EA%B2%B0%EC%A0%95_%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C