✔️ Service - LoadBalancer
LoadBalancer = 외부용 LoadBalancer + NodePort + ClusterIp
클라우드 공급자의 로드 밸런서를 사용하여 서비스를 외부에 노출시킨다.
외부 로드 밸런서가 라우팅되는 NodePort와 ClusterIP 서비스가 자동으로 생성된다.
클라이언트들에게 192.168.100.100:31313, 192.168.100.101:31313, 192.168.100.102:31313 로 서비스를 제공하는 것은 의미가 없다.
외부용 DNS를 사용하면(www.abc.com) ip 영역은 커버할 수 있지만 포트까지는 해결할 수 없다.
사용자들이 www.abc.com:31313 으로 접근하는 것은 매우 불편하다.
따라서 우리는 다음과 같이 LB라는 서비스를 부여할 수 밖에 없다.
클라이언트는 LB를 이용해 서비스에 접근하며 서비스는 실제 파드에 연결시켜준다.
myweb-svc-lb.yaml
apiVersion: v1
kind: Service
metadata:
name: myweb-svc-lb
spec:
type: LoadBalancer
selector:
app: web
ports:
- port: 80
targetPort: 8080
nodePort: 31313
vagrant@k8s-node1 ~/svc/lb kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.233.0.1 <none> 443/TCP 17h
myweb-svc-lb LoadBalancer 10.233.47.233 <pending> 80:31313/TCP 37s
LoadBalancer = 외부용 LoadBalancer + NodePort + ClusterIp
로드밸런서의 주소로 들어오면 호스트의 31313 포트로 전달해주고
전달된 요청은 서비스의 포트인 80으로 들어가며 해당 요청은 다시 파드의 8080으로 들어간다.
하지만 LoadBalacer를 아무리 기다려도 계속 <pending>상태이다.
이것은 쿠버네티스가 제어할 수 있는 영역이 아니다.
노드가 3개 있을 때 포트를 여는 것까지는 리눅스 운영체제를 통해 할 수 있지만, LB는 만들어줘야 한다.
로드밸런서 타입은 클라우드를 위해서 만든 것이다.
클라우드에서 실제 외부에 로드밸런서를 만들어야 한다.
결국은 AWS라고 하면 ALB나 NLB를 만들어야하고 ALB 또는 NLB의 백엔드에 인스턴스의 포트를 연결하면 인스턴스에 부여된 ip가 <pending> 영역에 찍히게 되는 것이다.
하지만 on-prem 에서는 해당 작업을 할 수 없다.
어떻게 해결 할 수 있을까 ? METALLB를 사용한다.
✔️ METALLB - Addon
https://metallb.universe.tf/METALLB
- 베어메탈 시스템에서 로드밸런서를 구현해준다.
베어메탈 시스템 쿠버네티스 클러스터에서 로드밸런서를 구현해준다.
실제로 외부에는 없으나 내부에 로드밸런서 기능을 하는 파드로 띄운다.
METALLB
는 아직 단 한번도 major 버전이 업데이트된 적은 없지만 실제 프로덕션 환경에 많이 사용될 정도로 검증돼 있다.
✔️ METALLB 설치
MTEALLB
공식 문서를 보고 설치하는 방법 https://metallb.universe.tf/installation/
~/kubespray/inventory/mycluster/group_vars/k8s_cluster/addons.yml
138 # MetalLB deployment
139 metallb_enabled: true
140 metallb_speaker_enabled: true
141 metallb_ip_range:
142 - "192.168.100.240-192.168.100.249"
168 metallb_protocol: "layer2"
~/kubespray/inventory/mycluster/group_vars/k8s_cluster/k8s-cluster.yml
129 kube_proxy_strict_arp: true
다음과 같이 변경한다.
vagrant@k8s-node1 ~/kubespray ➦ e7508d7d pwd
/home/vagrant/kubespray
vagrant@k8s-node1 ~/kubespray ➦ e7508d7d ansible-playbook -i inventory/mycluster/inventory.ini cluster.yml -b
다음 명령으로 설치한다.
vagrant@k8s-node1 ~/svc/exname kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.233.0.1 <none> 443/TCP 19h
myweb-svc-lb LoadBalancer 10.233.47.233 192.168.100.240 80:31313/TCP 86m
weather-ext-svc ExternalName <none> www.naver.com <none> 36m
정상적으로 설치가 완료되면 <pending>
영역이 10.233.47.233 ip 주소로 변경된다.
vagrant@k8s-node1 ~/svc/exname kubectl get ns
NAME STATUS AGE
default Active 5d8h
dev Active 4d6h
kube-node-lease Active 5d8h
kube-public Active 5d8h
kube-system Active 5d8h
metallb-system Active 8h
설치가 완료되면 metallb-system
라는 NS가 만들어진다.
vagrant@k8s-node1 ~/svc/exname kubectl get po -n metallb-system
NAME READY STATUS RESTARTS AGE
controller-77c44876d-dcv29 1/1 Running 0 8h
speaker-987lb 1/1 Running 0 8h
speaker-fnpnb 1/1 Running 0 8h
speaker-zstnm 1/1 Running 0 8h
vagrant@k8s-node1 ~/svc/exname kubectl get ds -n metallb-system
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
speaker 3 3 3 3 3 kubernetes.io/os=linux 8h
metallb-system
의 파드를 보면 speaker
를 확인할 수 있다.speaker
는 데몬셋이다. 각 노드에 speaker
라는 파드가 뜨게된다.
트래픽을 받아 controller
에 연결시킨다.
vagrant@k8s-node1 ~/svc/exname kubectl get po -n metallb-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
controller-77c44876d-dcv29 1/1 Running 0 8h 10.233.92.90 node3 <none> <none>
speaker-987lb 1/1 Running 0 8h 192.168.100.102 node3 <none> <none>
speaker-fnpnb 1/1 Running 0 8h 192.168.100.101 node2 <none> <none>
speaker-zstnm 1/1 Running 0 8h 192.168.100.100 node1 <none> <none>
파드의 ip 정보를 보면 호스트의 ip이다.controller
가 실제 로드 밸런서 역할을 해준다.
vagrant@k8s-node1 ~/svc/exname kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.233.0.1 <none> 443/TCP 27h
myweb-svc-lb LoadBalancer 10.233.47.233 192.168.100.240 80:31313/TCP 9h
weather-ext-svc ExternalName <none> www.naver.com <none> 8h
myweb-svc-lb
에 192.168.100.240 ip가 부여된다.
vagrant@k8s-node1 ~/svc/exname curl 192.168.100.240
Hello World!
myweb-rs-l8kp9
vagrant@k8s-node1 ~/svc/exname curl 192.168.100.240
Hello World!
myweb-rs-t2q4z
vagrant@k8s-node1 ~/svc/exname curl 192.168.100.240
Hello World!
myweb-rs-zknfd
해당 ip로 접속이 잘되며 외부에서도 접근이 가능하다.
LoadBalancer
타입은 NodePort
타입을 같이 사용한다.
다시 한번 정리하자면
📌 LoadBalancer
= LoadBalancer
+ NodePort
+ ClusterIP
📌 NodePort
= NodePort
+ ClusterIP
📌 ClusterIP
= ClusterIP
vagrant@k8s-node1 ~/svc/exname curl 192.168.100.100:31313
Hello World!
myweb-rs-l8kp9
vagrant@k8s-node1 ~/svc/exname curl 192.168.100.100:31313
Hello World!
myweb-rs-zknfd
vagrant@k8s-node1 ~/svc/exname curl 192.168.100.100:31313
Hello World!
myweb-rs-t2q4z
로드 밸런서의 ip지만 NodePort
의 기능을 가지므로 해당 ip와 port로 접속해도 NodePort
로도 작동한다.
vagrant@k8s-node1 ~/svc/exname kubectl run nettool -it --image ghcr.io/c1t1d0s7/network-multitool --rm
If you don't see a command prompt, try pressing enter.
/ # curl myweb-svc-lb
Hello World!
myweb-rs-zknfd
/ # curl myweb-svc-lb
Hello World!
myweb-rs-l8kp9
/ # curl myweb-svc-lb
Hello World!
myweb-rs-t2q4z
마찬가지로 myweb-svc-lb
SVC 이름으로 접근이 가능하며 즉, ClusterIP 타입으로도 접근 가능하다.
✔️ METALLB 작동방식
METALLB의 operating mode는 2가지 방식이있다.
- Layer2(default)
- BGP
✔️ Layer2 모드
노드가 3개 있다. 스위치가 존재하고 라우터를 통해 내부로 연결되는 부분이 있다.
각 노드에 데몬셋 형태로 모든 노드에 speaker
라고 하는 파드가 뜬다.
NodePort
가 speaker
역할을 하는 파드와 연결되며 NodePort
가 listen한다.
그리고 speaker
와 함께 로드 밸런서 역할을 하는 controller
라는 파드가 설치된다.
controller
(로드밸런서)는 192.168.100.240 ~ 192.168.100.249 사이의 ip 하나를 사용하게 된다.
controller
의 ip를 192.168.100.240이라고 해보자
외부에서 192.168.100.240를 치고 들어오면 어떤 노드로 들어오던 상관없이 speaker
가 controller
로 연결시키며 controller
는 다시 NodePort
로 분배한다.
그리고 NodePort
는 내부의 SVC로 다시 연결시켜준다. 최종적으로 SVC가 파드에 연결시킨다.
- 외부에서 192.168.100.240이라고 하는 로드 밸런서 ip로 접속한다.
- 라우터와 스위치를 통해 NodePort 중 아무곳으로 연결된다.
- NodePort로 들어온 요청은 speaker가 받는다.
- speaker는 로드 밸런서 역할을 하는 controller로 연결시킨다.
- controller(LB)는 다시 NodePort에 연결시킨다.
- NodePort는 다시 SVC에 연결시킨다.
- SVC가 파드로 연결시킨다.
on-prem 에서는 외부에 로드 밸런서를 만들 수 없기 때문에 이를 대신해서 내부에 파드 형태로 구현한다.
✔️ BGP 모드
BGP 모드로 작동시키기 위해서는 쿠버네티스 클러스터 외부에 L3 스위치가 있어야 한다.
그래서 현재로서는 작동시킬 수 없다.
우리가 일반적으로 말하는 스위치는 L2 스위치이다.
L3 스위치는 라우터 기능을 가진 스위치이다.
우선 L2 모드와 기본적인 개념은 같다.
다른점은 L2 모드에서는 노드에 speaker
가 존재하지만 BGP 모드에는 없다.
외부에서 L3 스위치(라우터)의 ip로 접속하면 BGP 프토토콜로 구현된 L3 스위치는 LB 역할을 한다.
BGP 라우팅 테이블이 세팅된다. L3 스위치가 SVC까지 라우팅하여 SVC를 연결시킨다.
그리고 SVC는 파드로 연결시킨다.
L2 모드는 10대 미만의 소규모에 BGP 모드는 10대 이상의 대규모 네트워크에서 사용한다.
'DevOps > Kubernetes' 카테고리의 다른 글
[Kubernetes] Ingress (인그레스) (0) | 2022.05.29 |
---|---|
[Kubernetes] Service - ExternalName (0) | 2022.05.23 |
[Kubernetes] Service - NodePort (1) | 2022.05.23 |
[Kubernetes] Service - Service Discovery (2) (0) | 2022.05.21 |
[Kubernetes] Service - Service Discovery (1) (0) | 2022.05.21 |
영차영차 성장 블로그
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!