외부 로드 밸런서 만들기

외부 로드 밸런서 만들기 (Create an External Load Balancer)

이 페이지는 외부 로드 밸런서를 만드는 방법을 보여줘요.

Service를 만들 때 클라우드 로드 밸런서를 자동으로 만들 수 있는 옵션이 있어요. 이는 외부에서 접근 가능한 IP 주소를 제공해 클러스터 노드의 올바른 포트로 트래픽을 보내줘요. 단, 클러스터가 지원되는 환경에서 실행되고 올바른 클라우드 로드 밸런서 제공자 패키지로 구성된 경우에 한해요.

Service 대신 Ingress를 사용할 수도 있어요. 자세한 내용은 Ingress 문서를 참고해요.

출처: 문서

본문

시작하기 전에 (Before you begin)

쿠버네티스 클러스터가 있어야 하고, kubectl 명령줄 도구가 클러스터와 통신하도록 구성되어 있어야 해요. 이 튜토리얼은 제어 플레인 호스트로 동작하지 않는 노드가 최소 두 개 있는 클러스터에서 실행하는 것이 권장돼요. 아직 클러스터가 없다면 minikube로 만들거나 다음 쿠버네티스 플레이그라운드 중 하나를 사용할 수 있어요:

클러스터는 외부 로드 밸런서 구성 지원이 이미 있는 클라우드나 다른 환경에서 실행 중이어야 해요.

Service 만들기

매니페스트로 Service 만들기

외부 로드 밸런서를 만들려면 Service 매니페스트에 다음 줄을 추가해요:

    type: LoadBalancer

그러면 매니페스트는 다음과 같이 보일 수 있어요:

apiVersion: v1
kind: Service
metadata:
  name: example-service
spec:
  selector:
    app: example
  ports:
    - port: 8765
      targetPort: 9376
  type: LoadBalancer

kubectl로 Service 만들기

kubectl expose 명령과 그 --type=LoadBalancer 플래그로 Service를 만들 수도 있어요:

kubectl expose deployment example --port=8765 --target-port=9376 \
        --name=example-service --type=LoadBalancer

이 명령은 참조된 리소스(위 예시의 경우 이름이 exampleDeployment)와 같은 셀렉터를 사용해 새 Service를 만들어요.

선택적 플래그를 포함한 자세한 내용은 kubectl expose reference를 참고해요.

IP 주소 찾기

kubectl 로 서비스 정보를 가져와 Service에 대해 생성된 IP 주소를 찾을 수 있어요:

kubectl describe services example-service

출력은 다음과 비슷해야 해요:

Name:                     example-service
Namespace:                default
Labels:                   app=example
Annotations:              <none>
Selector:                 app=example
Type:                     LoadBalancer
IP Families:              <none>
IP:                       10.3.22.96
IPs:                      10.3.22.96
LoadBalancer Ingress:     192.0.2.89
Port:                     <unset>  8765/TCP
TargetPort:               9376/TCP
NodePort:                 <unset>  30593/TCP
Endpoints:                172.17.0.3:9376
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

로드 밸런서의 IP 주소는 LoadBalancer Ingress 옆에 나열돼요.

참고:

Minikube에서 서비스를 실행 중이라면 다음으로 할당된 IP 주소와 포트를 찾을 수 있어요:

minikube service example-service --url

클라이언트 소스 IP 유지하기

기본적으로 대상 컨테이너에서 보이는 소스 IP는 클라이언트의 원래 소스 IP가 아니에요. 클라이언트 IP 보존을 활성화하려면 Service의 .spec 에서 다음 필드를 구성할 수 있어요:

  • .spec.externalTrafficPolicy — 이 Service가 외부 트래픽을 노드 로컬 엔드포인트로 라우팅할지 클러스터 전체 엔드포인트로 라우팅할지를 나타내요. Cluster(기본값)와 Local 두 가지 옵션이 있어요. Cluster 는 클라이언트 소스 IP를 숨기고 다른 노드로의 두 번째 홉을 일으킬 수 있지만, 전반적으로 좋은 부하 분산을 가져야 해요. Local 은 클라이언트 소스 IP를 보존하고 LoadBalancer·NodePort 유형 Service에서 두 번째 홉을 피하지만, 잠재적으로 불균형한 트래픽 분산의 위험이 있어요.
  • .spec.healthCheckNodePort — 서비스의 헬스 체크 노드 포트(숫자 포트 번호)를 지정해요. healthCheckNodePort 를 지정하지 않으면 서비스 컨트롤러가 클러스터의 NodePort 범위에서 포트를 할당해요. 그 범위는 API 서버 명령줄 옵션 --service-node-port-range 로 구성할 수 있어요. Service type 이 LoadBalancer로 설정되고 externalTrafficPolicyLocal 로 설정된 경우에만, healthCheckNodePort 값을 지정하면 Service가 사용자 지정 값을 사용해요.

Service 매니페스트에서 externalTrafficPolicy 를 Local로 설정하면 이 기능이 활성화돼요. 예:

apiVersion: v1
kind: Service
metadata:
  name: example-service
spec:
  selector:
    app: example
  ports:
    - port: 8765
      targetPort: 9376
  externalTrafficPolicy: Local
  type: LoadBalancer

소스 IP 유지 시 주의 사항과 제한

일부 클라우드 제공자의 로드 밸런싱 서비스는 각 대상에 서로 다른 가중치를 구성하게 해주지 않아요.

노드에 트래픽을 보내는 측면에서 각 대상이 균등하게 가중치가 매겨지면, 외부 트래픽은 서로 다른 Pod에 걸쳐 균등하게 로드 밸런싱되지 않아요. 외부 로드 밸런서는 각 노드에서 대상으로 사용되는 Pod의 수를 알지 못해요.

NumServicePods << NumNodes 또는 NumServicePods >> NumNodes 인 경우 가중치가 없어도 상당히 균등에 가까운 분산이 보일 거예요.

내부 pod-to-pod 트래픽은 모든 Pod에 걸쳐 동일한 확률로 ClusterIP 서비스와 비슷하게 동작해야 해요.

로드 밸런서 가비지 컬렉션

일반적으로 LoadBalancer 유형 Service가 삭제된 직후 클라우드 제공자의 연관 로드 밸런서 리소스가 정리돼야 해요. 하지만 관련 Service가 삭제된 후 클라우드 리소스가 고아가 되는 다양한 코너 케이스가 있는 것으로 알려져 있어요. 이것을 방지하기 위해 Service LoadBalancer용 Finalizer 보호가 도입됐어요. finalizer를 사용하면 연관 로드 밸런서 리소스도 삭제될 때까지 Service 리소스는 절대 삭제되지 않아요.

구체적으로 Service에 type LoadBalancer가 있으면 서비스 컨트롤러는 service.kubernetes.io/load-balancer-cleanup 이라는 finalizer를 붙여요. finalizer는 로드 밸런서 리소스가 정리된 후에만 제거돼요. 이는 서비스 컨트롤러가 충돌하는 같은 코너 케이스에서도 매달린 로드 밸런서 리소스를 방지해요.

외부 로드 밸런서 제공자

이 기능의 데이터패스는 쿠버네티스 클러스터 외부의 로드 밸런서가 제공한다는 점을 기억하는 것이 중요해요.

Service type 이 LoadBalancer로 설정되면 쿠버네티스는 클러스터 안의 파드에 type ClusterIP와 동등한 기능을 제공하고, 관련 쿠버네티스 파드를 호스팅하는 노드의 항목으로 (쿠버네티스 외부의) 로드 밸런서를 프로그래밍해 확장해요. 쿠버네티스 제어 플레인은 외부 로드 밸런서 생성, 헬스 체크(필요한 경우), 패킷 필터링 규칙(필요한 경우)을 자동화해요. 클라우드 제공자가 로드 밸런서에 IP 주소를 할당하면 제어 플레인이 그 외부 IP 주소를 조회해 Service 객체에 채워 넣어요.

더 알아보기 (Learn more)