Provisioning, MetalLB

Jeonghak Cho·2025년 3월 1일

Provisioning

목록 보기
5/44

MetalLB 개요

MetalLB는 Kubernetes 환경에서 LoadBalancer 서비스를 제공하는 오픈소스 네트워크 로드 밸런서이다. 기본적으로 Kubernetes의 LoadBalancer 타입 서비스는 클라우드 환경(GCP, AWS, Azure 등)에서만 동작하는데, MetalLB를 사용하면 온프레미스(베어메탈) 환경에서도 LoadBalancer 서비스를 사용할 수 있다.

MetalLB 아키텍처

Controller

Kubernetes API를 감시하며 LoadBalancer 서비스가 생성되었을 때 적절한 외부 IP를 할당.

Speaker

  • 할당된 IP를 네트워크에 알리고 트래픽을 전달.
  • Layer 2 또는 BGP 모드 중 선택하여 동작.

    Layer 2 모드: 특정 노드가 외부 IP를 직접 통지하는 방식 (ARP/NDP 활용).
    BGP 모드: MetalLB가 라우터와 BGP 세션을 맺고 외부 네트워크에 IP를 통지.

MetalLB 설치

strictARP true로 변경한다.

kubectl edit configmap -n kube-system kube-proxy
vagrant@master:~$ kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.14.4/config/manifests/metallb-native.yaml

namespace/metallb-system created
customresourcedefinition.apiextensions.k8s.io/bfdprofiles.metallb.io created
customresourcedefinition.apiextensions.k8s.io/bgpadvertisements.metallb.io created
customresourcedefinition.apiextensions.k8s.io/bgppeers.metallb.io created
customresourcedefinition.apiextensions.k8s.io/communities.metallb.io created
customresourcedefinition.apiextensions.k8s.io/ipaddresspools.metallb.io created
customresourcedefinition.apiextensions.k8s.io/l2advertisements.metallb.io created
customresourcedefinition.apiextensions.k8s.io/servicel2statuses.metallb.io created
serviceaccount/controller created
serviceaccount/speaker created
role.rbac.authorization.k8s.io/controller created
role.rbac.authorization.k8s.io/pod-lister created
clusterrole.rbac.authorization.k8s.io/metallb-system:controller created
clusterrole.rbac.authorization.k8s.io/metallb-system:speaker created
rolebinding.rbac.authorization.k8s.io/controller created
rolebinding.rbac.authorization.k8s.io/pod-lister created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:controller created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:speaker created
configmap/metallb-excludel2 created
secret/metallb-webhook-cert created
service/metallb-webhook-service created
deployment.apps/controller created
daemonset.apps/speaker created
validatingwebhookconfiguration.admissionregistration.k8s.io/metallb-webhook-configuration created

워커노드 확인

가용 노드 IP를 확인한다.

vagrant@master:~$ k get no -owide
NAME     STATUS     ROLES           AGE   VERSION    INTERNAL-IP      EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
master   Ready      control-plane   13d   v1.28.15   192.168.56.10    <none>        Ubuntu 20.04.6 LTS   5.4.0-189-generic   containerd://1.7.25
slave1   Ready      <none>          13d   v1.28.15   192.168.56.101   <none>        Ubuntu 20.04.6 LTS   5.4.0-189-generic   containerd://1.7.25
slave2   Ready      <none>          13d   v1.28.15   192.168.56.102   <none>        Ubuntu 20.04.6 LTS   5.4.0-189-generic   containerd://1.7.25
slave3   NotReady   <none>          13d   v1.28.15   192.168.56.103   <none>        Ubuntu 20.04.6 LTS   5.4.0-189-generic   containerd://1.7.25
slave4   Ready      <none>          13d   v1.28.15   192.168.56.104   <none>        Ubuntu 20.04.6 LTS   5.4.0-189-generic   containerd://1.7.25

IP Address Pool 설정

MetalLB가 사용할 IP 범위를 설정한다.

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: mypool-01
  namespace: metallb-system
spec:
  addresses:
  - 192.168.56.101-192.168.56.104
  • 적용
vagrant@master:~$ k apply -f mypool-01.yml
ipaddresspool.metallb.io/mypool-01 created

L2Advertisement 적용

Layer 2 모드는 ARP(IPv4) 또는 NDP(IPv6)를 사용하여 특정 노드가 외부 IP를 광고한다. L2Advertisement가 있어야 MetalLB가 IP를 네트워크에 알리고, 트래픽을 특정 노드로 라우팅할 수 있다. 만약 L2Advertisement를 설정하지 않으면, MetalLB는 Layer 2 모드에서 LoadBalancer 서비스를 동작시키지 않는다.

apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  namespace: metallb-system
  name: example
spec:
  ipAddressPools:
  - mypool-01
  nodeSelectors:
  - matchLabels:
      kubernetes.io/hostname: slave1		
  - matchLabels:
      kubernetes.io/hostname: slave2
  • 적용
vagrant@master:~$ k apply -f l2a.yml
l2advertisement.metallb.io/example created

메탈LB 적용 후 nginx controller의 EXTERNAL-IP가 채워진것을 확인

vagrant@master:~$ k get svc -n nginx-controller
NAME                                               TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)                      AGE
nginx-ingress-ingress-nginx-controller             LoadBalancer   10.110.48.246   192.168.56.102   80:31565/TCP,443:32482/TCP   47m

인그레스

k edit ing mynginx 로 확인해 보니 하단 status에 IP가 부여된 것을 알 수 있다. 이제 노드 IP로 브라우저에서 화면 확인이 가능하다.

...
spec:
  ingressClassName: nginx
  rules:
  - host: nginx.mydomain
    http:
      paths:
      - backend:
          service:
            name: nginx
            port:
              number: 80
        path: /
        pathType: Prefix
status:
  loadBalancer:
    ingress:
    - ip: 192.168.56.101

hosts 파일에 내부 도메인명을 등록하여 인그레스에서 호스팅 기반으로 라우팅 하게 한다.

sudo vi /etc/hosts

192.168.56.101 nginx.mydomain

vagrant@master:~$ ping nginx.mydomain
PING nginx.mydomain (192.168.56.101) 56(84) bytes of data.
64 bytes from nginx.mydomain (192.168.56.101): icmp_seq=1 ttl=64 time=1.44 ms
64 bytes from nginx.mydomain (192.168.56.101): icmp_seq=2 ttl=64 time=0.697 ms
  • 확인
vagrant@master:~$ k get ing
NAME      CLASS   HOSTS                ADDRESS          PORTS   AGE
mynginx   nginx   nginx.mydomain   192.168.56.101   80      12d
vagrant@master:~$ curl nginx.mydomain
<H1>hello</H1>

윈도우에서 C:\Windows\System32\drivers\etc\hosts 파일을 수정하면 브라우저에서 확인이 가능하다.

192.168.56.101 nginx.mydomain

0개의 댓글