LoadBalancer 서비스는 클러스터 외부에 L4 로드밸런서를 따로 두고, Kubernetes 에서 이 로드밸런서를 연동하여 사용하는 것이다. Amazon EKS, GKE, AKS 등의 퍼블릭 클라우드 프로바이더가 제공하는 AWS EKS, GKE 등의 플랫폼에서는 AWS NLB, GCP LB, Azure LB 등의 L4 로드 밸런서와의 연동을 기본 제공한다.(베어메탈 LoadBalancer 구현체인 MetalLB 등으로 온프레미스에서도 사용 가능함) 예를 들어, GKE 에서 LoadBalancer 서비스를 생성하면 GCP LB(Google Cloud Platform Load Balancer)가 자동 생성되고, 여기에 가상 IP가 할당되며, 쿠버네티스 클러스터 내의 노드들과 연결된다.

 

NodePort 나 ClusterIP - ExternalIPs 를 사용하면 진입점이 특정 노드가 되기 때문에, 해당 노드 장애시에는 서비스가 불가능해진다. 하지만 LoadBalancer 서비스를 사용하면 별도의 외부 로드밸런서가 진입점이 되기 때문에 안정성이 제고된다. 외부 로드 밸런서가 쿠버네티스 클러스터의 NodePort 서비스를 통해 여러 노드에 걸쳐 로드밸런싱을 하는 구조이다.

LoadBalancer 서비스를 생성하면, 내부적으로는 외부 로드밸런서에서 각 노드로 들어오는 트래픽을 수신하기 위해 NodePort 가 생성되고, 목적지 파드로 트래픽을 전송하기 위해 ClusterIP 도 생성된다.(실제 서비스 리소스가 생성되는 것은 아니고, NAT 규칙이 설정되는 개념)

 

1. LoadBalancer 생성

아래와 같은 매니페스트로 생성한다.

apiVersion: v1
kind: Service
metadata:
  name: sample-lb
spec:
  type: LoadBalancer
  ports:
    - name: "http-port"
      protocol: "TCP"
      port: 8080
      targetPort: 80
      nodePort: 30082
  selector:
    app: sample-app

 

spec.ports[] 하위에 지정하는 포트 번호들은 아래와 같은 의미를 가진다.

항목 의미
spec.ports[].nodePort 모든 노드 IP에서 수신할 Port 번호
spec.ports[].port LoadBalancer 에 할당된 가상 IP 와 ClusterIP 에서 수신할 Port 번호
spec.ports[].targetPort 목적지 파드(컨테이너) 포트 번호

 

각각의 포트가 사용되는 구간을 그림으로 보면 아래와 같다.

 

생성 후에 아래 커맨드로 조회가 가능하다.

$ kubectl get services
NAME              TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)          AGE
sample-lb         LoadBalancer   10.96.78.27   172.18.0.7    8080:30082/TCP   13m

 

sample-lb 서비스 이름으로 클러스터 내부에서 통신시 자동으로 설정된 ClusterIP 에서 DNS 해석을 진행하는 것을 볼 수 있다.

$ kubectl run --image=amsy810/tools:v2.0 --restart=Never --rm -i testpod --command -
- dig sample-lb.default.svc.cluster.local
...
;; QUESTION SECTION:
;sample-lb.default.svc.cluster.local. IN	A

;; ANSWER SECTION:
sample-lb.default.svc.cluster.local. 30	IN A	10.96.78.27
...
pod "testpod" deleted

 

2. 로드 밸런서 가상 IP 정적 지정 방법

실제 운영 서비스에서는 서비스의 엔드포인트가 되는 로드 밸런서의 주소를 IP 가 아닌 의미있는 도메인을 할당해서 사용하기 때문에 DNS 설정 등을 위해 고정 IP 를 할당하는 경우가 많다. 이때는 spec.loadBalancerIP 항목에 예약한 IP 주소를 입력한다.

apiVersion: v1
kind: Service
metadata:
  name: sample-lb
spec:
  type: LoadBalancer
  loadBalancerIP: xxx.xxx.xxx.xxx # 여기에 로드 밸런서의 IP로 사용할 주소를 입력
  ports:
    - name: "http-port"
      protocol: "TCP"
      port: 8080
      targetPort: 80
  selector:
    app: sample-app

 

3. 로드 밸런서 방화벽 정책 설정

LoadBalancer 서비스를 생성하여 로드 밸런서를 사용하면 기본적으로 전세계에서 접속할 수 있는 상태가 된다. AWS EKS 나 GKE 에서는 spec.loadBalancerSourceRanges 에 접속을 허가할 IP 범위를 지정하면, 클라우드 프로바이더가 제공하는 방화벽 기능을 사용하여 접속을 제한할 수 있다. 기본값이 0.0.0.0/0 이기 때문에 제한이 없는 상태이다.

spec:
...
  loadBalancerSourceRanges:
  - 10.0.0.0/8
...

 

클라우드 프로바이더가 제공하는 방화벽이 없는 경우에 이 설정을 적용하면 쿠버네티스 노드의 iptables 를 사용하여 접속 제한이 이루어진다.

블로그 이미지

망원동똑똑이

프로그래밍 지식을 자유롭게 모아두는 곳입니다.

,