Cloud/MetalLB

[MetalLB] MetalLB를 통해 On-Prem k8s 클러스터에 외부 IP 할당하기

grayroom 2024. 5. 5. 21:58

배경

Kubernetes Service type중 LoadBalancer Type은 External IP를 할당받아 외부 트래픽을 내부 서비스로 Routing 하는 역할을 수행합니다. 하지만 CRD는 명세 되어있음에도 Bare-metal 환경에서 LoadBalancing이 구현 되어있지 않습니다. 따라서 CSP(AWS, Azure 등)를 사용하지 않으면 External IP를 할당받을 수 없습니다.

Kubeadm등으로 구성한 On-prem k8s cluster에는 별도의 Load Balancer를 도입해야 합니다. 이 문서에서는 그러한 환경에 Metal LB 를 구성하는 과정에 대해 다룹니다.

요구사항

Kubernetes 클러스터LoadBalancing 기능이 없는 1.13.0 버전 이상의 클러스터
k8s network addon Antrea, Calico, Canal, Cilium, Flannel, Kube-ovn, Kube-router, Weave Net
IPv4 Address MetalLB가 Service에 할당할 IP 대역(없다면 단일 서버 IP도 가능)
L2 Operating mode k8s 노드간 7946 포트(TCP&UDP)가 사용 가능해야함
BGP Operating mode 각 노드의 BGP 기능을 지원하는 라우터

설치

준비

IPVS모드에서 kube-proxy를 경우, k8s v1.14.2이후부터 strict ARP모드를 활성화 해야 합니다.

더보기

💡kube-proxy, IPVS, ARP, strict ARP가 무엇인가요?

kube-proxy

Pod에 클러스터 내부 IP를 할당 및 추적하는 요소입니다. 동시에, 서비스에 대한 네트워크 트래픽을 서비스를 구성하는 여러 Pod중 하나로 분산시키는 로드밸런싱을 수행합니다.

IPVS

kube-proxy가 동작하는 세가지 모드(User space, iptables, IPVS)중 하나로, 다른 두가지 모드에 비해 높은 성능을 보입니다.

ARP

논리주소(IP)를 물리주소(MAC)으로 변환하는 프로토콜입니다.

Strict ARP

kube-proxy는 k8s리소스(Service, Pod)에 대한 가상 논리주소(VIP), 가상 물리주소(VMAC)를 알고 있으므로, 일반적인 ARP처럼 ARP 요청을 모든 Cilent에게 브로드캐스트하여 MAC주소를 받을 필요가 없습니다. 따라서, kube-proxy가 직접 ARP에 대한 응답을 하게 합니다.

먼저, strictARP모드가 활성화 되어있는지 확인합니다.

# see what changes would be made, returns nonzero returncode if different
kubectl get configmap kube-proxy -n kube-system -o yaml | \\
grep strictARP

 

아래 명령어를 통해 kube-proxy configmap을 수정합니다.

kubectl edit configmap -n kube-system kube-proxy

 

아래와 같이 설정합니다.

apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
ipvs:
  strictARP: true

 

또는 아래와 같은 명령어를 통해 변경합니다.

# actually apply the changes, returns nonzero returncode on errors only
kubectl get configmap kube-proxy -n kube-system -o yaml | \\
sed -e "s/strictARP: false/strictARP: true/" | \\
kubectl apply -f - -n kube-system

Manifest File로 설치

kubectl apply -f <https://raw.githubusercontent.com/metallb/metallb/v0.11.0/manifests/namespace.yaml>
kubectl apply -f <https://raw.githubusercontent.com/metallb/metallb/v0.14.3/manifests/metallb.yaml> 

Configuration

IP Address Pool 설정

서비스에 할당할 IP를 정의하기 위해 IPAddressPool이라는 CR(Custom Resourece)를 정의해야 합니다. cluster에 할당된 IP만을 사용할 수 있다는 점에 주의하세요.

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: first-pool
  namespace: metallb-system
spec:
  addresses:
  - 192.168.10.0/24
  - 192.168.9.1-192.168.9.5
  - fc00:f853:0ccd:e799::/124

 

이렇게 정의한 metallb_ipaddresspool.yaml 을 아래와 같이 적용합니다.

kubectl apply -f metallb_ipaddresspool.yaml

Istio Gateway

Istio-ingress gateway를 기존에 사용하고있던 경우, ClusterIP타입 서비스를 LoadBalancer타입으로 변경하여 클러스터 외부 IP를 할당할 수 있습니다.

kubectl edit svc/istio-ingressgateway -n istio-system
spec:
  type: LoadBalancer # ClusterIP -> LoadBalancer
  loadBalancerIP: 192.168.10.0 # IP를 명세

spec.loadBalancerIP를 명세하면 명시적으로 특정 IP를 사용할 수 있습니다. 명세하지 않는다면 IPAddressPool에 명세된 주소중 사용되지 않은 주소가 순차적으로 할당됩니다.