1. metalLB이란?
클라우드에서 제공하는 외부 로드밸런서가 필요하다. 내가 사용하고 있는 쿠버네티스 즉, 일반적인 환경에서는 로드 밸런서를 사용하게 되면 external-ip부분에 pending이 뜨고, 사용하지 못 한다. 이 환경을 온프레미스환경이라고 하는데, 여기서 로드밸런서를 사용하려면 내부에 로드밸런서 서비스를 받아주는 구성이 필요하다.
이를 지원하는 것이 MetalLB이다. MetalLB는 베어메탈(bare metal, 운영체제가 설치되지 않은 하드웨어)로 구성된 쿠버네티스에서도 로드밸런서를 사용할 수 있게 고안된 프로젝트이다. MetalLB는 특별한 네트워크 설정이나 구성이 있는 것이 아니라 기존의 **L2 네트워크(ARP/NDP)**와 **L3 네트워크(BGP)**로 로드밸런서를 구현한다.
2. metalLB의 configuration
MetalLB 의 로드 벨런싱 정책 설정은 관련 설정 정보를 담은 configmap 을 배포하여 설정할 수 있다.
- Layer 2 모드 : layer2모드는 하나의 노드가 로컬 네트워크에 서비스를 광고하는 책임을 맡는다.
- BGP 모드 : 클러스터의 각 노드는 네트워크 라우터와의 BGP 피어링 세션을 설정하고 해당 피어링 세션을 사용하여 외부 클러스터 서비스의 IP를 광고한다. 라우터가 다중 경로를 지원하도록 구성되어 있다.
위처럼 두 가지 모드가 있지만, 여기서는 layer2모드로 사용하고자 한다. 하나의 노드만 로드밸런싱할 것이기 때문이다.
3. Layer2의 동작원리
L2모드는 2계층 통신을 이용한다. 각 노드마다 speaker라는 데몬 셋이 생성되며, 이 speaker데몬 셋이 생성한 pod가 로드밸런서 ExternalIP를 2가지 방법으로 관리한다.
① 리더 sepaker pod를 선출한다.
② GARP프로토콜을 이용하여 speaker pod를 실행하는 노드로 ExternalIP 패킷이 오도록 설정한다.
리더 speaker pod이 실행하는 노드로 패킷이 오면, 해당 노드에서 iptables규칙에 따라서 분산되어 패킷이 pod로 전달된다. 노드까지 패킷이 도착하면 이후 과정은 nodeport동작과 비슷하다. NodePort SNAT이 적용되어 출발지(클라이언트)IP가 sepaker pod로 전달된 노드IP로 변경된다.
4. metalLB 설치하기
1) 초기 셋팅하기
IPVS 모드에서 kube-proxy를 사용하는 경우 Kubernetes v1.14.2 이후부터는 엄격한 ARP(strictARP) 모드를 사용하도록 설정해야 한다.
Kube-router는 기본적으로 엄격한 ARP를 활성화하므로 서비스 프록시로 사용할 경우에는 이 기능이 필요하지 않습니다.
엄격한 ARP 모드를 적용하기에 앞서, 현재 모드를 확인한다.
kubectl get configmap kube-proxy -n kube-system -o yaml | \\
grep strictARP
strictARP: false
위의 명령어를 쳤을 때 strictARP: false가 출력된다. 만약 true로 나올 경우 아래의 단계는 생략해도 된다.
kubectl get configmap kube-proxy -n kube-system -o yaml | \\
sed -e "s/strictARP: false/strictARP: true/" | \\
kubectl apply -f - -n kube-system
정상적으로 수행되면 다음과 같이 출력된다.
Warning: resource configmaps/kube-proxy is missing the kubectl.kubernetes.io/last-applied-configuration annotation which is required by kubectl apply. kubectl apply should only be used on resources created declaratively by either kubectl create --save-config or kubectl apply. The missing annotation will be patched automatically.configmap/kube-proxy configured
2) metalLB 설치하기
metalLB를 설치하기
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.11.0/manifests/metallb.yaml>
controller와 speaker가 잘 돌아가는지 확인하기
kubectl get pod -n metallb-system
위의 명령어를 입력하여 잘 running되는지를 확인해준다.
- metallb-system/controller : deployment 로 배포되며, 로드 벨런싱을 수행할 external IP 주소의 할당을 처리하는 역할을 담당한다.
- metallb-system/speaker : daemonset 형태로 배포되며, 외부 트래픽과 서비스를 연결해 네트워크 통신이 가능하도록 구성하는 역할을 담당합니다.
metallb_config 생성하기
# metallb_config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: default
protocol: layer2
addresses:
- 192.168.35.100-192.168.35.110 # IP 대역폭
Layer 2 모드를 사용할 경우 워커 노드의 네트워크 인터페이스에 IP를 바인딩 하지 않아도 된다. 로컬 네트워크의 ARP 요청에 직접 응답하여 컴퓨터의 MAC주소를 클라이언트에 제공하는 방식으로 작동하기 때문에 간단하게 사용할 IP 주소의 대역만 설정하면 된다.
kubectl apply -f metallb_config.yaml
위의 명령어를 입력하여 설정해준다.
ingress-nginx-controller의 type 변경하기
kubectl -n ingress-nginx patch service ingress-nginx-controller -p '{"spec":{"type":"LoadBalancer"}}'
ingress-nginx-controller의 type이 현재 NodePort로 설정되어 있기 때문에, LoadBalancer로 변경해준다.
kubectl -n ingress-nginx get service
위와 같이 external-ip가 할당됨을 확인할 수 있다.
잘 들어가지는지 확인하기
위와 같이 404 Not found가 떴다. 이를 해결하는 방법은 아래와 같이 설명할 것이다.
5. 404 Not found 해결하기
1) 원인 분석하기
내 경우 아래가 ingress.yaml 파일인데 host를 foo.bar.com으로 설정하였다. 즉, dns형식으로 설정하였다. 그런데 10.102.197.140는 ip형식이므로 404 Not found가 뜨는 것이다.
💡 ingress 파일에 설정한 host형식이 일치하지 않으므로 404 Not found가 발생한다.
2) 도메인없이 테스트하기
curl명령 사용하기
curl --resolve <host dns>:<port>:<external-ip> <요청하는 주소>
host dns의 포트 번호를 external-ip 변환하라는 명령어이다.
curl --resolve www.sohui.xyz:80:192.168.100.100 <http://www.sohui.xyz>
그럼 위와 같이 잘 나옴을 알 수 있다.
👇🏻 참고 사이트
https://malwareanalysis.tistory.com/271
https://nice-engineer.tistory.com/entry/Kubernetes-Ingress-인그레스
https://youngkyonyou.github.io/kubernetes/2021/08/01/Kubernetes-MetalLB-3.3.4.html
https://mlops-for-all.github.io/docs/appendix/metallb/#metallb_configyaml