Dev / App

K8s Network - MetalLB L2 Mode

K8s Network

6 min read
K8s Network - MetalLB L2 Mode

MetalLB

MetalLB는 Cloud가 아닌 환경에서 Loadbalancer를 사용할 수 있는 솔루션입니다.
L2 및 BGP 모드를 지원하고 있으며, 무료로 사용 가능합니다.

MetalLB는 왜 등장했을까요?

이유는 Service의 Loadbalancer 타입에 있습니다.
해당 타입을 사용하기 위해서는 반드시 CSP의 LB가 필요합니다.

클러스터의 외부와 통신하기 위해서는 LB가 없이도 Nodeport 타입을 설정하면 통신이 가능합니다.
그러나, Nodeport 타입을 사용하면 <Node IP>:<Nodeport>와 같이 IP에 Port를 붙혀야 정상적으로 시스템이 인식합니다.

MetalLB L2 모드

동작 원리

MetalLB의 L2모드는 모드 명 처럼, 2계층 통신을 사용합니다. 클러스터에 구성 시, speaker라는 daemonset이 생성되며, 노드마다 배포된 파드는 LB의 외부IP(ExternalIP)를 2가지 방법을 통해 제어합니다.

GARP 프로토콜을 사용하여, 리더 speaker 파드를 실행하는 노드로 ExternalIP 패킷이 전송되도록 설정
==> 리더로 선출된 speaker 파드는 LB의 External IP를 관리하게 됩니다.

MetalLB에서 GARP 프로토콜 역할 흐름

어떻게 리더 speaker 파드를 실행하는 노드로 ExternalIP 패킷이 전송되도록 할 수 있는 것일까요?

해답은 GARP 프로토콜에 있습니다.
먼저, GARP 프로토콜은 자신의 IP가 네트워크 망에서 자기 IP에 해당하는 MAC 주소를 알리는 ARP Reply(ARP 프로토콜 방식)없이 브로드캐스트를 하는 것입니다.

<흐름 순서 정리>
1. 리더 speaker 파드가 External IP를 가짐

  1. GARP 패킷을 브로드캐스트
  1. 결과적으로 트래픽을 유도함

MetalLB & iptabels

MetalLB 또한 iptables를 활용합니다.

리더 speaker 파드가 실행되는 노드의 External IP로 패킷이 접근하면, 해당 노드의 iptables 규칙에 의해 각 노드의 파드로 분산되어 패킷이 전달됩니다.

L2 모드 단점

가장 큰 첫 번째 단점은 리더 speaker 파드를 가진 노드에 대한 부하도가 증가하는 것입니다.
GARP를 통해 모든 External IP로 접근하는 패킷을 리더 speaker 파드로 전달하기에, 당연한 수순입니다.

두 번째 단점은 가용성 부족입니다. 리더 speaker에 대한 장애 발생 시, 네트워크 순단이 생길 수 밖에 없는 구조이고, 새로운 리더가 선출되기 전까지 통신되지 않습니다.

MetalLB 실습

실습을 위한 전제 조건이 있는데, VM을 클러스터링 맺은 경우 같은 서브넷 대역에 존재해야합니다.

  1. MetalLB 설치
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.12/config/manifests/metallb-native.yaml
  1. Layer2 모드 설정(configmap or CRD)
    IP Address Pool과 L2Advertisement 리소스를 생성합니다.
코드 보기
# metallb-config.yaml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: my-pool
  namespace: metallb-system
spec:
  addresses:
  - 192.168.0.240-192.168.0.250   # 이 IP 대역은 클러스터 외부와 충돌 없어야 함
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: l2
  namespace: metallb-system
spec: {}
  
  1. NodePort 타입 Service 배포처음에 LB 타입으로 구성해보았으나, 로드밸런서가 클라우드 업체의 장비라 mac주소를 알 수 없다고 판단하여, nodeport 타입으로 변경하여 진행합니다.
코드 보기
# nginx-lb.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-lb
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
  1. 배포 확인
kubectl get svc nginx-lb

Share This Post

Check out these related posts

개발팀의 애자일 도입 이야기2

개발팀의 애자일 도입 이야기 1

Lambda@Edge 고급 로깅 제어 기능