CloudNet 가시다님이 진행하는 Kubernetes Advanced Network Study 5주차 정리입니다.
[ 실습 환경 구성 ]
: CloudFormation 스택 배포 후 EC2 SSH 접속
LoadBalancer 소개
- Exposes the Service externally using an external load balancer.
- Kubernetes does not directly offer a load balancing component
- you must provide one, or you can integrate your Kubernetes cluster with a cloud provider.
- To implement a Service of type:LoadBalancer, Kubernetes typically starts off by making the changes that are equivalent to you requesting a Service of type : Nodeport. The cloud-controller-manager component then configures the external load balancer to forward traffic to that assigned node port.
- You can configure a load balanced Service to omit assigning a node port, provided that the cloud provider implementation supports this.
- Disabling load balancer NodePort allocation : k8s v1.24 [ stable]
AWS LoadBalancer
1. LoadBalancer 종류
1) CLB (Classic Load Balancer)
- 클래식 로드밸런서
- NLB/ALB에 비해서 가장 적은 기능을 제공하며 가장 오래된 로드밸런서
2) NLB (Network Load Balancer)
- 네트워크 로드밸런서
- CLB/ALB에 비해서 처리 속도가 가장 빠르고 Layer 4 계층에서 동작
- TCP/UDP/TLS 트래픽을 처리
3) ALB (Application Load Balancer)
- 애플리케이션 로드밸런서
- HTTP/HTTPS/gPRC 트래픽 처리하며 Layer7 계층에서 동작
2. LoadBalancer 동작 방식
1) 외부 클라이언트는 로드밸런서에 접속하고, 로드밸런서는 파드가 있는 노드들로 부하분산해서 전달
: NodePort를 목적지 포트로 전달하며 노드의 NodePort로 인입 후에는 iptables에 의해서 파드로 랜덤 부하분산
2) 로드밸런서에서 파드의 IP로 직접 부하분산 전달
: 별도의 로드밸런서 컨트롤러를 구성하고 해당 로드밸런서 컨트롤러가 로드밸런서에게 파드의 IP를 동적으로 전달
MetalLB 소프트웨어 LoadBalancer (온프레미스 환경)
ARP??
서비스(Service) LoadBalancer Type 통신 흐름
요약 : 외부 클라이언트가 '로드밸런서' 접속 시 부하분산 되어 노드 도달 후 iptables 룰로 목적지 파드와 통신됨
- 외부에서 로드밸런서 (부하분산) 처리 후 -> 노드(NodePort) 이후 기본 과정은 NodePort 과정과 동일하다!
- 노드는 외부에 공개되지 않고 로드밸런서만 외부에 공개되어, 외부 클라이언트는 로드밸런서에 접속을 할 뿐 내부 노드의 정보를 알 수 없다.
- 로드밸런서가 부하분산하여 파드가 존재하는 노드들에게 전달한다, iptabels 룰에서는 자신의 노드에 있는 파드만 연결한다
(externalTrafficPolicy : local) - DNAT 2번 동작 : 첫번째(로드밸런서 접속 후 빠져 나갈때), 두번째(노드의 iptables 룰에서 파드IP 전달 시)
- 외부 클라이언트 IP 보존(유지) : AWS NLB는 타겟이 인스턴스일 경우 클라이언트 IP를 유지, iptables 룰 경우도 externalTrafficPolicy로 클라이언트 IP를 보존
- 쿠버네티스는 Service(LB Type) API만 정의하고 실제 구현은 add-on 에 맡김
부하분산 최적화 : 노드에 파드가 없을 경우 '로드밸런서'에서 노드에 헬스 체크(상태 검사)가 실패하여 해당 노드로는 외부 요청 드래픽을 전달하지 않는다
서비스(LoadBalancer) 부족한 점
- 서비스(LoadBalancer) 생성 시 마다 LB(ex. AWS NLB)가 생성되어 자원 활용이 비효율적임 => HTTP 경우 인그레스(Ingress)를 통해 자원 활용 효율화 가능
- 서비스(LoadBalancer)는 HTTP/HTTPS 처리에 일부 부족함(TLS 종료, 도메인 기반 라우팅 등) => 인그레스(Ingress)를 통해 기능 동작 가능!
- (참고) 온프레미스 환경에서 제공 불가능? => MetalLB 혹은 OpenELB(구 PorterLB)를 통해서 온프레미스 환경에서 서비스(LoadBalancer) 기능 동작 가능!
0. MetalLB 요약
MetalLB - Layer2 모드
- 리더 파드가 선출되고 해당 리더 파드가 생성된 노드로만 트래픽이 인입되어 해당 노드에서 iptables 분산되어 파드로 접속
- 권장 사용 환경 : 테스트 및 소규모의 환경(동일 네트워크 1개 사용)에서 클라이언트 IP 보존이 필요 없을 때
MetalLB - BGP 모드
- speaker 파드가 BGP로 서비스 접속(EXTERNAL-IP)를 전파 후, 외부에서 라우터를 통해 ECMP 라우팅 으로 부하 분산 접속
- 권장 사용 환경 : 규모가 있고, 클라이언트 IP 보존과 장애 시 빠른 절체가 필요하며, 네트워크 팀 협조가 가능할 때
1. MetalLB 소개
1.1 MetalLB
* MetalLB (bareMetal Load Balancer)
- MetalLB = BareMetal Load Balancer
- 온프레미스 한경에서 사용 가능한 서비스 타입
- 데몬셋으로 speaker POD를 생성하여 External IP를 전파
- BGP 데몬의 경우 BGP 업데이트를 받지 않음
- 클라우드 플랫폼 호환 X
- 일부 CNI와 연동 불가
* MetalLB (baremetal load balancer) - L2 mode
- GARP를 사용
- ARP가 가진 태생적 한계 존재
- Speaker POD에 부하 집중
- fail-over 시 arp 전파 및 갱신까지 Loss 발생
* MetalLB (baremetal load balnacer) - BGP Mode
- POD IP는 host route로 전파 ( packet trombone 방지를 위한 host route 광고 범위 및 상위 network aggregation 고민 필요 )
- Speaker는 bgp 광고를 받지 않음 (Service POD network만 광고)
- community, LP 등 다양한 옵션 사용 가능 (ToR의 자동화 설정 고민 필요 - BGP Listen range, community permit 등)
- fail-over 빠름 (POD 절체 시 bgp update 전파)
- MetalLB는 온프레미스 환경(IDC)에서 사용할 수 있는 서비스(로드밸런서 타입)입니다 <= 클라우드 환경의 서비스(로드밸런서 타입)와는 동작이 조금 다르다!
- 서비스(로드 밸런서)의 'External IP'전파를 위해서 표준 프로토콜인 ARP(IPv4)/NDP(IPv6), BGP를 사용합니다.
- 데몬셋으로 speaker 파드를 생성하여 'External IP' 전파합니다
- 일반적으로 BGP 데몬과 다르게 BGP 업데이트(외부에서 광고하는 네트워크 대역)을 받지 않습니다
- Unlike standard BGP daemons, MetalLB BGP speakers do not accept any incoming updates
- 클라우드 플랫폼 호환 : 대부분의 클라우드 플랫폼과 호환되지 않습니다
- CNI(네트워크 플러그인) 호환 : 일부 CNI와 연동 이슈가 있습니다
- 예) Calico IPIP(BGP)와 MetalLB BGP 모드를 상단 라우터와 동시 사용 시 문제 발생
1.2 Layer2 모드(ARP/NDP)
▶ 모드 소개 : 리더 파드가 선출되고 해당 리더 파드가 생성된 노드로만 트래픽이 인입되어 해당 노드에서 iptables 분산되어 파드로 접속
- 서비스(로드밸런서) 'Extenral IP' 생성 시 speaker 파드 중 1개가 리더가 되고, 리더 speaker 파드가 존재하는 노드로 서비스 접속 트래픽이 인입되게 됩니다
- 데몬셋으로 배포된 speaker 파드는 호스트 네트워크를 사용합니다 -> "NetworkMode": "host"
- 리더는 ARP(GARP, Gratuitous ARP)로 해당 'External IP'에 대해서 자신이 소유라며 동일 네트워크에 전파를 합니다
- 만약 리더(노드)가 장애 발생 시 자동으로 나머지 speaker 파드 중 1개가 리더가 됩니다
- 멤버 리스터 및 장애 발견은 hashicorp의 memberlist를 사용 - Gossip based membership and failure detection
- Layer 2에서 멤버 발견 및 자동 절체에 Keepalived(VRRP)도 있지만 사용하지 않은 이유
▶ 제한 사항 : single-node bottlenecking, potentially slow failover
- single-node bottlenecking : 서비스 1개 생성 사용 시, 모든 서비스 접근 트래픽은 리더 파드가 존재하는 노드로만 인입되어 부하가 집중
=> 외부 라이터에서 접근 시 ECMP로 부하 분산이 가능 - potentially slow failover : 리더(노드)가 장애 시 나머지 노드 리더가 선출되고, ARP 전파 및 갱신완료 전까지는 장애가 발생됨( 대략 10초 ~ 20초정도)
=> 외부 라이터에서 노드(ㅍ드) 장애 헬스 체크로 빠르게 절체 가능
1.3 BGP 모드
▶ 모드 소개 : speaker 파드가 BGP로 서비스 정보(EXTERNAL-IP)를 전파 후, 외부에서 라우터를 통해 ECMP 라우팅으로 부하 분산 접속
- speaker 파드에 BGP가 동작하여 서비스 정보(EXTERNAL-IP)를 전파한다
- 기본은 IP주소 (32bit)를 전파하며, 설정으로 축약된 네트워크 정보를 전파할 수 있다 -> bgp -> advertisements에 aggregation-length 설정
- BGP 커뮤니티, localpref 등 BGP 관련 설정을 할 수 있다
- IP 주소 마지막이 0과 255를 처리를 못하는 라우터 장비가 있을 경우 avoid-buggy-ips:true 옵션으로 할당되지 않게 할 수 있다
- 외부 클라이언트에서 SVC(서비스, EXTERNAL-IP)로 접속이 가능하며, 라우터에서 ECMP 라우팅을 통해 부하 분산 접속을 할 수 있다
- 일반적으로 ECMP는 5-tuple(프로토콜, 출발지IP, 목적지IP, 출발지 Port, 목적지Port) 기준으로 동작합니다.
- 물론 라우터 장비에 따라 다양한 라우팅(분산) 처리가 가능합니다.
▶ 제한 사항 : 라우터에서 서비스로 인입이 되기 때문에, 라우터의 관련 설정이 중요한 만큼 네트워크팀과 협업을 적극 권장
- 노드(speaker) 파드 장애 시 BGP Timer 설정 등 구성하고 있는 네트워크 환경에 맞게 최적화 작업이 필요
- ECMP 부하 분산 접속 시 특정 파드에 물리거나 혹은 세션 고정, flapping 등 다양한 환경에 대응이 필요
- BGP 라우팅 설정 및 라우팅 전파 관련 최적화 설정이 필요
1.4 실습 환경 소개
▶ 기본 정보 확인
▶ 파드 접속 확인
2. MetalLB - Layer 2 모드
2.1 MetalLB 설치
- 설치 방법 지원 : Kubernetes manifests, using Kusomize, or using Helm
- 참고 : kube-proxy의 ipvs 모드 사용 시 'strictARP : true' 설정 필요
▶ 간단하게 mainfests로 설치 진행
- 컨피그맵 생성 : 모드 및 서비스 대역 지정
- 서비스(External-IP) 대역을 노드가 속한 eth0의 대역이 아니여도 상관없다 -> 다만 이 경우 GW 역할의 라우터에서 노드들로 라우팅 경로 지정 필요
- 로그 확인 : 아래 로그 -f 모니터링 해두기
2.2 서비스 생성 및 확인
▶ 서비스 확인 및 리더 Speaker 파드 확인
: EXTERNAL-IP가 서비스마다 할당
: LoadBalancer 타입의 서비스는 NodePort와 ClusterIP를 포함한 - 'allocateLoadBalancerNodePorts : true' 기본 값
: ExternalIP로 접속 시 사용하는 포트는 PORT(S)의 앞에 있는 값을 사용(위의 경우 TCP 80)
: 만약 노드의 IP에 NodePort로 접속 시 사용하는 포트는 PORT(S)의 뒤에 있는 값을 사용(위의 경우 32561)
: LoadBalancer 타입은 기본적으로 NodePort를 포함 사용. NodePort는 ClusterIP를 포함 사용
: 클라우드사업자 LB Type이나 온프레미스환경 HW LB Type 경우 LB 사용 시 NodePort 미사용 설정 가능
ARP 프로토콜? ARP(Address Resolution Protocol) 프로토콜이란 소프트웨어적으로 할당된 논리 주소인 IP 주소를(L3, 네트워크 계층) 실제적인 물리 주소인 MAC 주소(Media Access Control / L2, 데이터링크 계층)로 바꾸어주는 역할을 하는 '주소 해석 프로토콜'을 의미합니다. ( 반대로 MAC 주소를 가지고 IP주소를 알아내는 프로토콜은 RARP 프로토콜이라고 합니다.) * ARP 프로토콜 동작 순서 - 같은 네트워크에 있을 때 같은 네트워크 내에 있는 단말 들의 MAC 주소는 중계 장치가 MAC 주소 테이블 정보를 저장하고 관리하고 있으므로 내부에서 단말들이 MAC 주소를 가지고 통신을 할 수 있게 된다. - 같은 네트워크에 없을 때 같은 네트워크에 있는 중계 장비의 MAC 주소 테이블에 존재하지 않는 다른 네트워크 대역에 있는 단말과 통신을 해야 하는 경우, IP주소를 이용하여 통신하게 되므로 ARP 프로토콜을 통해 IP 주소와 MAC 주소 간 변환을 통해 통신을 하게 됩니다. |
: 실제 LoadBalancer 서비스의 ExternalIP에 대해서 MetalLB 리더 스피커 파드가 선정되고, 해당 파드가 ARP 응답을 처리합니다. 결국 LoadBalancer 서비스의 ExternalIP와 통신을 하기 위해서는, 리더 스피커 파드가 배포된 워커노드로 트래픽이 들어오게 됩니다.
2.3 서비스 접속 테스트
☞ k8s 클러스터 외부에서 노드의 IP를 감추고 VIP/Port를 통해 k8s 클러스터 내부의 애플리케이션에 접속할 수 있다!
▶ 클라이언트(mypc, mypc2) -> 서비스(External-IP) 접속 테스트
: LoadBalancer Type은 기본값으로 NodePort 포함. NodePort 서비스는 ClusterIP를 포함
: NodePort:PORT 및 CLUSTER-IP:PORT로 접속 가능
- 클라이언트 -> 서비스(EXTERNAL-IP) 접속 시 : 리더 파드가 존재하는 노드 인입 후 Service에 매칭된 iptables rules에 따라 랜덤 부하 분산되어서(SNAT) 파드로 접속!
▶ iptables 정책 적용 확인 : NodePort와 거의 동일!
2.4 Failover 테스트
▶ 리더 Speaker 파드가 존재하는 노드를 재부팅! -> curl 접속 테스트 시 10초 ~ 20초 정도의 장애시간이 발생하였다
=> 이후 자동 원복되며, 원복 시 5초 정도 장애 시간 발생!
: 리더 speaker 파드가 존재하는 노드(실제는 컨테이너)를 중지
2.5 externalTrafficPolicy:Local 테스트
▶ 클라이언트 -> 서비스(External-IP) 접속 테스트 : 리더 speaker 파드가 존재하는 노드에 위치한 애플리케이션 파드로만 접속되며, 클라이언트 IP 보존!
다만 부하분산이 되지 않아 비효율적이며, 만약 리더 노드에 애플리케이션 파드가 없을 시는 접속 불가(타임 아웃)로 문제가 발생한다 => 해당조합의 설정은 하지 말것을 권장!!