Kubernetes Service - MetalLB
목차
온프레미스 클러스터는 Load Balancer를 구매하지 않는 한 부하분산 기능 및 외부연견용 IP 제공하는 리소스가 필요
MetalLb는Bare Metal 환경(가상화 하지 않고 사용한느 고성능 물리 서버)에서 사용 할 수 있는 Loda Balancer 기능을 제공(CNCF 오픈소스 프로젝트)
MetalLb는 네트워크 로드 밸런서를 통해 “외부 IP 주소 풀”을 사용하여 온프레미스 및 VM등의 가상 환경 클러스터에서 외부 서비스 접근 가능
—
MetalLB 특징
온프레미스 환경에서 Service “type:LoadBalancer”의 EXTERNAL-IP\<pending\> 할당
Load Balencer IP로 전달되는 트래픽을 Node로 전달 하면 MetalLB의 역할은 끝남
제공되는 서비스 IP(EXTERNAL-IP)는 ping 작동 안되며 서비스에 대한 동작은 제동된 IP를 통해 애플리케이션에 액세스하여 확인 가능
MetalLB 모드
Layer2 mode (https://metallb.universe.tf/concepts/layer2/)
- 클러스터 노드 중 하나(리더 노드)가 외부에서 접속 가능한 IP의 ARP request를 네트워크 인터페이스에서 할당처리
- ARP(Address Resolution Protocol)?
- IP주소를 MAC주소와 매칭 시키기 위한 프로토콜
- 구성이 단순하여 대용량 처리에 부하가 심하여 테스트용으로 권장
BGP mode (https://metallb.universe.tf/concepts/bgp/)
- 고가용성이 구성가능하여 운영환경에서 주로 사용
MetalLB 구성요소
Controller(Deployment)
- 구성된 IP pool에서 로드 밸런싱을 수행할 EXTERNAL_IP 주소를 할당하는 역할
Speaker(DaemonSet)
- Layer2 or BGP모드를 통해 할당된 IP를 알리는 역할 수행
- speak pod는 node IP를 사용
서비스 계정(컨트롤러 및 스피커)
- 서비스 계정은 컨트롤러 및 스피커 구성요서 작동에 필요한 RABC 사용 권한이 포함
MetalLB L2모드
사용할 IP 주소의 대역 설정을 통해 IP제공
설치 후 필수 → “EXTERNAL_IP 대역”, “설정 모드” 지정을 위한 configmap 배포
Node NIC에 IP를 바인딩 하지 않고 로컬 네트워크의 ARP 요청에 응답하여 컴퓨터의 MAC주소를 클라이언트에게 제공하는 방식으로 작동
LoadBalancer 생성 → MetalLB L2 Controller는 APIserver를 통해 EXTERNAL-IP를 리더 Speaker pod에 할당→ Speaker pod는 소유하고 있다는 것을 ARP를 이용해 모든 노드 Speak Pod에 전파
Service type: LoadBalancer ?
- Node앞에 위치해 각 Node들로 트래픽을 분산하는역할
- L4 LoadBalancer가 생성되고 ClusterIP서비스 및 NodePort 서비스 가 암시적으로 생성됨
- NodePort(30000\~32767)서비스 위에 적용
- Public으로 사용 가능한 IP주소 및 DNS주소를 제공을 통해 Private IP 주소 및 NodePort포트로 클러스터의 Node에 트래픽을 Load Balanceing 하고 전달
- 웹 애플리케이션이나 API와 같이 높은 트래픽 양을 처리햐애 하는 애플리케이션에 유용
- 클라우드 환경이 아닌 온프레미스(VM)환경에서 LoadBalancer를 사용할경우 Public주소를 제공 할 수 있는 MetalLB(bare metal load balacer)모듈을 설치해주어야 한다.
설치
#설정
$ kubectl edit configmap -n kube-system kube-proxy
apiVersion: v1
data:
...
ipvs:
excludeCIDRs: null
minSyncPeriod: 0s
scheduler: \"\"
strictARP: true #false -> true로 변경
#설치
#아래의 코드가 작동하지 않으면
#https://metallb.universe.tf/installation/
#Installation By Manifest
#To install MetalLB, apply the manifest:
#여기서 주소 복사하여 설치
$ kubectl apply -f kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.14.4/config/manifests/metallb-native.yaml
#확인
#Pod IP와 Node IP가 같은 것을 확인
$ kubectl get po -n metallb-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
controller-756c6b677-5p8rl 1/1 Running 0 25s 10.109.131.6 k8s-node2 <none> <none>
speaker-ddps6 0/1 Running 0 25s 10.10.10.90 k8s-master <none> <none>
speaker-jw4n7 0/1 Running 0 25s 10.10.10.92 k8s-node2 <none> <none>
speaker-tjsks 0/1 Running 0 25s 10.10.10.91 k8s-node1 <none> <none>
$ kubectl get no -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
k8s-master Ready control-plane 3d22h v1.28.8 10.10.10.90 <none> Ubuntu 22.04.4 LTS 6.5.0-26-generic containerd://1.6.28
k8s-node1 Ready <none> 3d22h v1.28.8 10.10.10.91 <none> Ubuntu 22.04.4 LTS 5.15.0-101-generic containerd://1.6.28
k8s-node2 Ready <none> 3d22h v1.28.8 10.10.10.92 <none> Ubuntu 22.04.4 LTS 5.15.0-101-generic containerd://1.6.28- - ip-pool.yaml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: ip-pool
namespace: metallb-system
spec:
addresses:
- 10.10.10.192/26
# 10.10.10.192 ~ 10.10.10.255- l2-pool.yaml
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: network-l2-lb
namespace: metallb-system
spec:
ipAddressPools:
- ip-pool
#ip pool 파일 만들어서 추가 가능$ kubectl apply -f ip-pool.yaml
$ kubectl apply -f l2-pool.yaml
#확인
$ kubectl get all -n metallb-system
NAME READY STATUS RESTARTS AGE
pod/controller-756c6b677-5p8rl 1/1 Running 0 39m
pod/speaker-ddps6 1/1 Running 0 39m
pod/speaker-jw4n7 1/1 Running 0 39m
pod/speaker-tjsks 1/1 Running 0 39m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/metallb-webhook-service ClusterIP 10.102.2.6 <none> 443/TCP 39m
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/speaker 3 3 3 3 3 kubernetes.io/os=linux 39m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/controller 1/1 1 1 39m
NAME DESIRED CURRENT READY AGE
replicaset.apps/controller-756c6b677 1 1 1 39m
#테스트
$ kubectl create deployment metallb-deploy --image=traefik/whoami --replicas=3 --port=80
$ kubectl expose deployment metallb-deploy --name=metallb-deploy-svc --type=LoadBalancer --port=80 --target-port=80
$ kubectl get events -w