Back to Notes

Notes

MetalLB Layer2와 BGP

bare-metal Kubernetes 환경에서 MetalLB가 VIP를 외부 네트워크에 노출하는 방식을 OSI 계층 관점에서 정리하고, Layer2 mode, BGP mode, 외부 L4 Load Balancer 구성의 차이를 비교한다.

Published
Updated
Area
Computer Networks
Type
concept
Series
Kubernetes Networking
Category
Notes
MetalLBLayer2BGPECMPL4 Load BalancerKubernetes ServiceIngressk3sVIPARPNDP

MetalLB의 위치

bare-metal 또는 k3s 같은 온프레미스 Kubernetes 환경에서는 Service type: LoadBalancer를 만들어도 AWS ELB, GCP Load Balancer, Azure Load Balancer 같은 cloud load balancer가 자동으로 생성되지 않는다.

이때 MetalLB는 Kubernetes LoadBalancer Service에 외부에서 접근 가능한 VIP(Virtual IP)를 할당하고, 해당 VIP를 네트워크에 알리는 역할을 한다.

중요한 구분은 다음과 같다.

MetalLB:
  "이 VIP로 들어오는 트래픽을 어느 노드로 보내야 하는가?"

kube-proxy / CNI / Service:
  "노드에 도착한 트래픽을 어느 Pod로 전달할 것인가?"

Ingress Controller:
  "HTTP Host, path, TLS 기준으로 어느 Service로 보낼 것인가?"

즉, MetalLB는 보통 L7 reverse proxy도 아니고, 엄밀한 의미의 L4 Load Balancer도 아니다. MetalLB의 핵심 역할은 VIP를 외부 네트워크에 advertise하는 방식이다.


OSI 계층 관점에서 보기

OSI Layer주요 개념Kubernetes/MetalLB와의 관계
L1 Physical케이블, 전기 신호, NIC, 포트MetalLB가 직접 다루지 않음
L2 Data LinkEthernet, MAC, ARP, NDP, switchingMetalLB Layer2 mode가 주로 사용하는 계층
L3 NetworkIP, routing table, next-hop, BGPMetalLB BGP mode가 주로 사용하는 계층
L4 TransportTCP, UDP, port, connectionService port, NodePort, 외부 L4 Load Balancer와 관련
L7 ApplicationHTTP, Host, path, TLS, gRPCTraefik, NGINX Ingress, Envoy Gateway 등이 담당

MetalLB의 두 대표 mode는 이 표에서 다음 위치에 놓인다.

Layer2 mode:
  ARP/NDP를 이용해 VIP -> 특정 노드 MAC 매핑을 알림

BGP mode:
  BGP를 이용해 VIP prefix -> 노드 next-hop 경로를 라우터에 알림

Layer2 mode

핵심 개념

MetalLB의 Layer2 mode는 VIP를 실제로 특정 장비의 NIC에 고정으로 부여하는 방식이 아니라, 특정 노드가 ARP 또는 NDP 응답을 대신 수행하여 외부 네트워크가 해당 VIP를 그 노드의 MAC 주소로 보내도록 만드는 방식이다.

IPv4에서는 ARP가 사용되고, IPv6에서는 NDP가 사용된다.

예시를 위해 문서용 IP 대역을 사용하면 다음과 같다.

Client: 203.0.113.10

node-a:
  Node IP: [REDACTED]
  MAC: aa:aa:aa:aa:aa:aa

node-b:
  Node IP: [REDACTED]
  MAC: bb:bb:bb:bb:bb:bb

node-c:
  Node IP: [REDACTED]
  MAC: cc:cc:cc:cc:cc:cc

VIP:
  203.0.113.240

203.0.113.240 VIP의 현재 leader가 node-a라고 하면, 흐름은 다음과 같다.

1. Client가 203.0.113.240:443으로 접속하려고 함

2. Client가 ARP 요청을 보냄
   "Who has 203.0.113.240?"

3. node-a의 MetalLB speaker가 응답
   "203.0.113.240 is at aa:aa:aa:aa:aa:aa"

4. Client의 ARP cache에 다음 매핑이 저장됨
   203.0.113.240 -> aa:aa:aa:aa:aa:aa

5. 이후 Client는 Ethernet frame의 destination MAC을 node-a의 MAC으로 설정

6. 패킷이 node-a에 도착

7. node-a의 kube-proxy 또는 CNI datapath가 Kubernetes Service 규칙에 따라 Pod로 전달

그림으로 나타내면 다음과 같다.

Client
  |
  | ARP: Who has VIP?
  v
node-a MetalLB speaker
  |
  | ARP Reply: VIP is at node-a MAC
  v
Client ARP cache
  |
  | TCP 443 packet
  v
node-a
  |
  | kube-proxy / Service
  v
Pod on node-a / node-b / node-c

왜 Layer2 mode라고 부르는가

외부 클라이언트가 어떤 IP로 통신하려면 최종적으로 Ethernet frame의 destination MAC이 필요하다.

IP 통신 전 준비:
  "이 IP의 MAC 주소가 무엇인가?"

ARP의 역할:
  IP -> MAC 매핑 조회

MetalLB Layer2 mode는 이 지점에서 VIP에 대한 ARP/NDP 응답을 대신한다.

즉, 핵심은 다음과 같다.

VIP에 대한 routing 자체를 바꾸는 것이 아니라,
VIP -> leader node MAC
매핑을 ARP/NDP로 알려준다.

그래서 이 방식을 Layer2 mode라고 부른다.

VIP당 leader가 하나인 이유

같은 VIP에 대해 여러 노드가 동시에 ARP 응답을 하면 문제가 생긴다.

node-a: 203.0.113.240 is at aa:aa
node-b: 203.0.113.240 is at bb:bb
node-c: 203.0.113.240 is at cc:cc

이런 상황에서는 클라이언트와 스위치가 VIP의 MAC을 일관되게 판단하지 못한다. 결과적으로 ARP flux, MAC flap, 간헐적 연결 문제 등이 발생할 수 있다.

따라서 MetalLB Layer2 mode는 보통 VIP 하나당 하나의 speaker 노드가 ARP/NDP 응답을 맡는다.

VIP 203.0.113.240 -> node-a
VIP 203.0.113.241 -> node-b
VIP 203.0.113.242 -> node-c

여러 VIP를 사용하면 VIP별로 leader가 달라질 수 있으므로 서비스 단위 분산은 가능하다. 하지만 하나의 VIP에 대한 외부 진입점은 하나의 노드가 된다.

병목 지점

Layer2 mode에서 203.0.113.240:80, 203.0.113.240:443을 모두 하나의 ingress VIP로 사용한다면 외부 트래픽은 먼저 현재 leader 노드로 들어온다.

Client
  -> VIP
  -> leader node
  -> kube-proxy
  -> Pod

이때 병목 후보는 다음과 같다.

병목 후보설명
leader node NICVIP로 들어오는 ingress traffic이 한 노드의 NIC를 통과
conntrackconnection tracking 부하 증가 가능
kube-proxyiptables/IPVS/eBPF datapath 처리량 영향
CPU interrupt네트워크 패킷 처리로 인한 CPU 부하
cross-node forwardingleader 노드에 도착한 뒤 다른 노드의 Pod로 재전달될 수 있음

Layer2 mode는 간단하고 안정적이지만, 하나의 VIP에 대해 여러 노드가 동시에 ingress traffic을 받는 구조는 아니다.

장애 발생 시

기존 leader가 node-a였고 장애가 발생했다고 하자.

기존:
  203.0.113.240 -> node-a MAC

장애 후:
  203.0.113.240 -> node-b MAC

새로운 leader인 node-b는 네트워크에 Gratuitous ARP 또는 NDP update를 보내 VIP의 MAC 매핑을 갱신시킨다.

node-b:
  203.0.113.240 is at bb:bb:bb:bb:bb:bb

주의할 점은 일부 클라이언트, 스위치, 방화벽 장비의 ARP cache 갱신이 지연될 수 있다는 것이다. 이 경우 failover 직후 짧은 연결 지연이 발생할 수 있다.


BGP mode

핵심 개념

MetalLB의 BGP mode는 ARP/NDP를 이용해 MAC 매핑을 조작하는 방식이 아니다.

대신 MetalLB speaker가 라우터 또는 L3 switch와 BGP peering을 맺고, VIP로 가는 route를 advertise한다.

node-a speaker <---- BGP ----> router
node-b speaker <---- BGP ----> router
node-c speaker <---- BGP ----> router

BGP mode에서 라우터는 다음과 같은 경로를 배울 수 있다.

203.0.113.240/32 via node-a
203.0.113.240/32 via node-b
203.0.113.240/32 via node-c

라우터가 ECMP(Equal-Cost Multi-Path)를 지원하면 같은 VIP에 대한 여러 next-hop을 동시에 사용할 수 있다.

Client A -> router -> node-a
Client B -> router -> node-b
Client C -> router -> node-c

즉 BGP mode의 핵심 장점은 외부 트래픽의 진입점 자체를 여러 노드로 분산할 수 있다는 점이다.

패킷 흐름 예시

Client
  -> Router
  -> ECMP hash 결과에 따라 node-a / node-b / node-c 중 하나
  -> kube-proxy / CNI
  -> Pod

라우터는 일반적으로 다음과 같은 값들을 기반으로 flow hash를 계산한다.

source IP
destination IP
source port
destination port
protocol

따라서 하나의 TCP connection 내부 패킷은 보통 같은 노드로 유지된다. 반면 connection이 여러 개면 서로 다른 노드로 분산될 수 있다.

Layer2 mode와의 차이

구분Layer2 modeBGP mode
주 계층L2L3 control plane
핵심 기술ARP/NDPBGP route advertisement
VIP당 외부 진입 노드1개여러 개 가능
분산 방식VIP별 leaderRouter ECMP
네트워크 장비 요구일반 스위치/공유기에서도 가능BGP 가능한 라우터 또는 L3 switch 필요
장애 전환Gratuitous ARP/NDPBGP route withdraw/update
운영 난이도낮음중간 이상
확장성제한적상대적으로 좋음

BGP mode의 주의점

BGP mode는 강력하지만 네트워크 장비와 운영 지식이 필요하다.

확인해야 할 항목은 다음과 같다.

항목확인 내용
Router supportBGP peering 가능 여부
ASNMetalLB ASN, router ASN 설계
ECMP여러 next-hop을 동시에 사용하는지
Route policyadvertise할 prefix 제한
Failure behaviornode 장애 시 route withdraw 동작
FirewallBGP session TCP 179 허용 여부
ObservabilityBGP session 상태와 advertised route 모니터링

externalTrafficPolicy와의 관계

MetalLB mode만큼 중요한 설정이 externalTrafficPolicy다.

spec:
  externalTrafficPolicy: Cluster

또는:

spec:
  externalTrafficPolicy: Local

Cluster

externalTrafficPolicy: Cluster에서는 트래픽을 받은 노드가 전체 endpoint 중 하나로 전달할 수 있다.

Client
  -> VIP
  -> node-a
  -> Pod on node-a / node-b / node-c

장점은 Pod 전체를 대상으로 분산할 수 있다는 점이다. 단점은 source IP가 보존되지 않거나 cross-node forwarding이 생길 수 있다는 점이다.

Local

externalTrafficPolicy: Local에서는 트래픽을 받은 노드의 local endpoint로만 전달한다.

Client
  -> VIP
  -> node-a
  -> Pod on node-a only

장점은 source IP 보존과 불필요한 node 간 hop 감소다. 단점은 해당 Service의 Pod가 없는 노드는 트래픽을 처리할 수 없다는 점이다.

mode별 조합

MetalLB modeexternalTrafficPolicy동작특징
Layer2ClusterVIP leader 노드가 받은 뒤 전체 Pod로 전달간단하지만 leader 노드가 ingress 병목 가능
Layer2LocalVIP leader 노드의 local Pod로만 전달source IP 보존, 하지만 leader 노드의 Pod만 활성 처리
BGPCluster여러 노드가 route를 advertise하고 각 노드가 전체 Pod로 전달진입점 분산 가능, cross-node hop 가능
BGPLocallocal endpoint가 있는 노드만 advertise하고 local Pod로 전달운영상 가장 깔끔한 구조 중 하나, Pod 배치 균형 필요

BGP mode에서 externalTrafficPolicy: Local을 사용할 경우, local endpoint가 있는 노드만 route를 advertise하게 구성할 수 있어 트래픽 흐름이 단순해진다.

Client
  -> Router ECMP
  -> ingress pod가 있는 node
  -> local ingress pod
  -> backend Service

다만 이 경우 라우터의 분산 단위는 보통 Pod 단위가 아니라 노드 단위다. 예를 들어 node-a에 Pod 2개, node-b에 Pod 1개가 있다면 node 단위 50:50 분산 결과로 Pod 부하가 불균형해질 수 있다.

node-a:
  pod-1: 25%
  pod-2: 25%

node-b:
  pod-1: 50%

따라서 podAntiAffinity, topologySpreadConstraints, DaemonSet 형태 배치 등을 함께 고려해야 한다.


외부 L4 Load Balancer와의 비교

MetalLB와 외부 L4 Load Balancer는 역할이 다르다.

외부 L4 Load Balancer는 VIP를 직접 소유하고 TCP/UDP connection을 여러 backend node로 분산한다.

Client
  -> External L4 Load Balancer VIP
  -> node-a:NodePort
  -> node-b:NodePort
  -> node-c:NodePort

예시는 다음과 같다.

VIP: 203.0.113.240:443

Backends:
  node-a:[REDACTED_NODEPORT]
  node-b:[REDACTED_NODEPORT]
  node-c:[REDACTED_NODEPORT]

비교하면 다음과 같다.

방식VIP 소유 주체분산 위치장점단점
MetalLB Layer2Kubernetes nodeVIP별 leader단순함, 홈랩/소규모에 적합VIP당 한 노드 병목
MetalLB BGPRouter가 route 학습Router ECMP진입점 분산 가능BGP 장비와 운영 지식 필요
External L4 LBLB 장비/소프트웨어LB가 TCP/UDP 분산성숙한 운영 기능, health check, policy 가능별도 장비/VM/운영 비용 필요

일반적인 운영 구성

홈랩 또는 소규모 k3s

가장 현실적인 구성은 다음과 같다.

MetalLB Layer2
+ Traefik 또는 NGINX Ingress
+ VIP 1개 또는 소수
+ 내부 DNS
+ 관리 서비스는 VPN 또는 내부망 전용

예시 구조:

Client
  -> VIP:443
  -> Traefik
  -> Kubernetes Service
  -> Pod

권장 방향:

항목권장 구성
Public ingress80443 redirect, 실제 서비스는 443 중심
Admin UI내부망 또는 VPN only
VIP poolDHCP 범위와 겹치지 않는 별도 대역
관리 서비스Nexus, Longhorn, Grafana, ArgoCD 등은 외부 공개 지양
인증SSO, basic auth, IP allowlist, VPN 등 추가 보호

VIP:80VIP:443을 노출하는 것 자체가 위험한 것은 아니다. 위험은 보통 다음에서 발생한다.

관리용 서비스가 인증 없이 외부 공개됨
기본 계정 또는 약한 비밀번호 사용
Ingress rule이 지나치게 넓음
내부 서비스가 public Host로 노출됨
TLS 설정이 부실함

따라서 80/443은 ingress 입구로 사용하되, 어떤 Service를 외부에 노출할지 엄격히 제한해야 한다.

중간 규모 사내망

사내망에서는 두 가지 선택지가 있다.

선택지 A: Layer2 + 서비스별 VIP 분산

VIP A -> Ingress
VIP B -> Registry
VIP C -> Object Storage API
VIP D -> Monitoring Internal

이 방식은 BGP 없이도 서비스별로 leader가 달라질 수 있어 어느 정도 분산 효과를 얻을 수 있다.

단, 하나의 VIP에 대한 ingress traffic은 여전히 한 노드에 먼저 들어온다.

선택지 B: BGP 가능한 라우터 도입

라우터나 L3 switch가 BGP와 ECMP를 지원한다면 MetalLB BGP mode를 사용할 수 있다.

Router
  BGP peer node-a
  BGP peer node-b
  BGP peer node-c

VIP
  advertised by node-a/node-b/node-c

이 경우 ingress VIP 하나에 대해서도 여러 노드가 동시에 진입점이 될 수 있다.

프로덕션 온프레미스

프로덕션에서는 보통 다음 요소를 함께 고려한다.

1. 이중화된 router 또는 L4 Load Balancer
2. MetalLB BGP 또는 외부 L4 LB
3. Ingress Controller 다중 replica
4. externalTrafficPolicy: Local 검토
5. Pod anti-affinity 또는 topology spread
6. TLS 인증서 자동화
7. 관리 UI의 VPN/SSO/IP allowlist 보호
8. NetworkPolicy로 namespace 간 접근 제한
9. BGP session, route advertisement, ingress traffic 모니터링
10. 장애 시 failover 검증

프로덕션에 가까운 구조는 다음과 같다.

Client
  -> Firewall / Router / L4 LB
  -> Kubernetes node
  -> Ingress Controller
  -> Service
  -> Pod

BGP mode를 사용한다면 다음 구조가 자연스럽다.

Client
  -> Router ECMP
  -> node with local ingress endpoint
  -> Ingress Controller
  -> Backend Service

예시 설정

MetalLB Layer2 예시

아래 예시는 실제 내부 IP를 사용하지 않고 문서용 주소로 표현했다. 실제 환경에서는 DHCP 범위와 겹치지 않는 내부 대역을 사용해야 한다.

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: example-pool
  namespace: metallb-system
spec:
  addresses:
    - 203.0.113.240-203.0.113.250
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: example-l2
  namespace: metallb-system
spec:
  ipAddressPools:
    - example-pool

MetalLB BGP 예시

실제 ASN, router IP, node IP는 환경에 따라 달라지므로 아래 값은 예시로만 봐야 한다.

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: bgp-pool
  namespace: metallb-system
spec:
  addresses:
    - 203.0.113.240/28
---
apiVersion: metallb.io/v1beta2
kind: BGPPeer
metadata:
  name: router-peer
  namespace: metallb-system
spec:
  myASN: 64500
  peerASN: 64501
  peerAddress: "[REDACTED_ROUTER_IP]"
---
apiVersion: metallb.io/v1beta1
kind: BGPAdvertisement
metadata:
  name: bgp-advertisement
  namespace: metallb-system
spec:
  ipAddressPools:
    - bgp-pool

Ingress용 LoadBalancer Service 예시

apiVersion: v1
kind: Service
metadata:
  name: ingress-controller
  namespace: ingress-system
  annotations:
    metallb.io/loadBalancerIPs: 203.0.113.240
spec:
  type: LoadBalancer
  externalTrafficPolicy: Local
  selector:
    app.kubernetes.io/name: ingress-controller
  ports:
    - name: http
      port: 80
      targetPort: 8000
      protocol: TCP
    - name: https
      port: 443
      targetPort: 8443
      protocol: TCP

externalTrafficPolicy: Local은 source IP 보존과 트래픽 경로 단순화에 유리하지만, ingress pod가 배치된 노드만 트래픽을 처리할 수 있다는 점을 고려해야 한다.


검증 포인트

MetalLB를 구성한 뒤에는 다음을 확인해야 한다.

검증 항목확인 방법
LoadBalancer IP 할당kubectl get svc -A
MetalLB speaker 상태kubectl get pods -n metallb-system
Layer2 ARP 응답client 또는 같은 L2 network에서 ARP cache 확인
BGP session 상태router 또는 FRR에서 BGP neighbor 확인
VIP 접근성curl -vk https://<VIP>
source IP 보존ingress access log 또는 application log 확인
failoverleader node drain/shutdown 후 VIP 접근성 확인
부하 분산여러 connection에서 node별 ingress traffic 관찰
보안 노출면외부에서 80/443 외 불필요한 port 접근 차단 확인

예시 명령:

kubectl get svc -A
kubectl get pods -n metallb-system -o wide
kubectl describe svc -n ingress-system ingress-controller

Layer2 mode라면 클라이언트 측에서 ARP cache를 확인한다.

arp -a

BGP mode라면 router 또는 FRR 쪽에서 neighbor와 route를 확인한다.

show bgp summary
show bgp ipv4 unicast

주의할 점

80/443 노출 자체보다 중요한 것

VIP:80VIP:443을 여는 것 자체는 일반적인 운영 방식이다. 문제는 그 뒤에 어떤 서비스가 붙어 있는지다.

위험한 예시는 다음과 같다.

Longhorn UI public exposure
Kubernetes Dashboard public exposure
Grafana public exposure without SSO
Nexus admin UI public exposure
MinIO console public exposure
ArgoCD public exposure without strong auth

권장 구조는 다음과 같다.

public:
  80  -> 443 redirect
  443 -> Ingress

internal only:
  admin UI
  storage UI
  registry admin
  monitoring
  dashboard

Layer2 mode의 한계

Layer2 mode는 단순하고 편하지만, 하나의 VIP에 대해 active ingress node가 하나다.

VIP 203.0.113.240 -> node-a

따라서 트래픽이 커지면 다음을 고려한다.

서비스별 VIP 분산
BGP mode 전환
외부 L4 Load Balancer 도입
Ingress Controller 배치 최적화

BGP mode의 운영 부담

BGP mode는 확장성이 좋지만 운영 부담이 있다.

BGP session 관리
ASN 설계
route policy
ECMP 확인
장애 시 route withdraw 검증
라우터 설정 백업

BGP mode를 도입하기 전에는 라우터가 ECMP를 실제로 지원하는지, 그리고 여러 next-hop을 기대한 방식으로 사용하는지 확인해야 한다.


선택 기준

환경추천
단일 노드 또는 매우 작은 홈랩MetalLB Layer2
3~5대 k3s 홈랩MetalLB Layer2 + VIP 분산
BGP 가능한 라우터가 있는 사내망MetalLB BGP 검토
트래픽이 큰 온프레미스MetalLB BGP + ECMP 또는 External L4 LB
강한 운영 통제와 health check가 필요한 환경External L4 LB
관리 UI가 많은 환경Ingress + VPN/SSO/IP allowlist

요약

MetalLB를 이해할 때 핵심은 다음이다.

Layer2 mode:
  ARP/NDP를 이용해 VIP -> 특정 노드 MAC 매핑을 알린다.
  VIP 하나당 진입점은 하나의 leader node다.
  단순하지만 큰 트래픽에서는 병목이 될 수 있다.

BGP mode:
  BGP를 이용해 VIP route를 라우터에 advertise한다.
  ECMP를 통해 여러 node가 동시에 진입점이 될 수 있다.
  확장성은 좋지만 BGP 가능한 네트워크 장비와 운영 지식이 필요하다.

External L4 Load Balancer:
  LB가 VIP를 소유하고 TCP/UDP connection을 node:port로 분산한다.
  성숙한 운영 기능을 제공하지만 별도 장비 또는 소프트웨어 운영이 필요하다.

k3s 기반 홈랩이나 소규모 사설망에서는 우선 다음 구성이 현실적이다.

MetalLB Layer2
+ Ingress Controller
+ VIP 1개 또는 서비스별 VIP 분산
+ 관리 서비스는 내부망/VPN 전용

이후 네트워크 트래픽이 커지거나 라우터가 BGP/ECMP를 안정적으로 지원한다면 다음 단계로 확장한다.

MetalLB BGP
+ ECMP
+ externalTrafficPolicy: Local
+ ingress pod의 노드별 균등 배치