MetalLB를 사용한 번들 부하 분산

이 문서에서는 MetalLB 부하 분산기와 함께 번들 부하 분산을 사용하도록 VMware용 GKE를 구성하는 방법을 설명합니다.

VMware용 GKE에서 MetalLB는 계층-2 모드로 실행됩니다.

MetalLB 구성 예시

다음은 MetalLB 부하 분산기를 실행하는 클러스터에 대한 구성 예시입니다.

MetalLB 부하 분산기 구성입니다.
MetalLB 부하 분산기 구성입니다.

위의 도식은 MetalLB 배포를 보여주는 다이어그램입니다. MetalLB는 클러스터 노드에서 직접 실행됩니다. 이 예시에서 관리자 클러스터와 사용자 클러스터는 별도의 두 VLAN에 위치하며 각 클러스터는 별도의 서브넷에 있습니다.

클러스터 서브넷
관리자 클러스터 172.16.20.0/24
사용자 클러스터 172.16.40.0/24

admin-cluster.yaml

관리자 클러스터 구성 파일의 다음 예시에서는 앞선 다이어그램에 표시된 구성을 보여줍니다.

  • MetalLB 부하 분산기

  • Kubernetes API 서버 및 관리자 클러스터 부가기능용 MetalLB의 VIP

network:
  hostConfig:
  ...

  ipMode:
    type: "static"
    ipBlockFilePath: "config-folder/admin-cluster-ipblock.yaml"
...

loadBalancer:
  kind: "MetalLB"
  ...

  vips:
    controlPlaneVIP: "172.16.20.100"
    addonsVIP: "172.16.20.101"

admin-cluster-ipblock.yaml

다음 IP 블록 파일 예시에서는 관리자 클러스터의 노드에 대한 IP 주소 지정을 보여줍니다. 여기에는 사용자 클러스터의 제어 영역 노드 주소와 클러스터 업그레이드 중에 사용할 IP 주소도 포함됩니다.

blocks:
- netmask: "255.255.255.0"
  gateway: "17.16.20.1"
  ips:
  - ip: 172.16.20.50
    hostname: admin-vm-1
  - ip: 172.16.20.51
    hostname: admin-vm-2
  - ip: 172.16.20.52
    hostname: admin-vm-3
  - ip: 172.16.20.53
    hostname: admin-vm-4
  - ip: 172.16.20.54
    hostname: admin-vm-5

user-cluster.yaml

다음 사용자 클러스터 구성 파일 예시에서는 다음 구성을 보여줍니다.

  • MetalLB 컨트롤러가 LoadBalancer 유형의 서비스에서 선택하고 할당할 주소 풀입니다. 인그레스 VIP는 이러한 풀 중 하나에 있습니다.

  • 사용자 클러스터의 Kubernetes API 서버에 지정된 VIP와 인그레스 프록시에 구성한 인그레스 VIP입니다. 사용자 클러스터의 제어 영역이 관리자 클러스터의 노드에서 실행되므로 Kubernetes API 서버 VIP는 관리자 클러스터 서브넷에 있습니다.

  • MetalLB를 사용하도록 설정된 노드 풀 MetalLB는 해당 노드 풀에 속하는 사용자 클러스터의 노드에 배포됩니다.

network:
  hostConfig:
  ...

  ipMode:
    type: "static"
    ipBlockFilePath: "config-folder/user-cluster-ipblock.yaml"
...

loadBalancer:
  kind: MetalLB
  metalLB:
    addressPools:
    - name: "address-pool-1"
      addresses:
      - "172.16.40.100/32"
      - "172.16.40.101-172.16.40.112
      avoidBuggyIPs: true
  ...

  vips:
    controlPlaneVIP: "172.16.20.102"
    ingressVIP: "172.16.40.102"
...

nodePools:
- name: "node-pool-1"
  cpus: 4
  memoryMB: 8192
  replicas: 3
  enableLoadBalancer: true

앞선 예시의 구성에서는 서비스에 사용할 수 있는 주소 집합을 지정합니다. 애플리케이션 개발자가 사용자 클러스터에 LoadBalancer 유형의 서비스를 만들면 MetalLB 컨트롤러가 이 풀에서 IP 주소를 선택합니다.

user-cluster-ipblock.yaml

다음 IP 블록 파일 예시에서는 사용자 클러스터의 노드에 대한 IP 주소 지정을 보여줍니다. 여기에는 클러스터 업그레이드 중에 사용할 IP 주소가 포함됩니다.

blocks:
- netmask: "255.255.255.0"
  gateway: "17.16.40.1"
  ips:
  - ip: 172.16.40.21
    hostname: user-vm-1
  - ip: 172.16.40.22
    hostname: user-vm-2
  - ip: 172.16.40.23
    hostname: user-vm-3
  - ip: 172.16.40.24
    hostname: user-vm-4
  - ip: 172.16.40.25
    hostname: user-vm-5

MetalLB 설정

방화벽 포트 열기

MetalLB는 Go 구성원 목록 라이브러리를 사용하여 리더 선택을 수행합니다. memberlist 라이브러리는 TCP 포트 7946 및 UDP 포트 7946을 사용하여 정보를 교환합니다. 모든 부하 분산기 노드에서 들어오는 트래픽과 나가는 트래픽에 해당 포트에 액세스할 수 있는지 확인합니다.

새 관리자 클러스터에 MetalLB 사용 설정

관리자 클러스터 구성 파일에서 loadBalancer.kind"MetalLB"로 설정하세요.

loadBalancer:
  kind: "MetalLB"

관리자 클러스터 구성 파일의 나머지 부분을 작성하고 관리자 클러스터 만들기의 설명대로 관리자 클러스터를 만듭니다.

주소 풀 지정

MetalLB 컨트롤러는 서비스의 IP 주소를 관리합니다. 따라서 애플리케이션 개발자가 사용자 클러스터에서 LoadBalancer 유형의 서비스를 만들 때 서비스의 IP 주소를 수동으로 지정할 필요가 없습니다. 대신 MetalLB 컨트롤러에서 클러스터를 만들 때 지정한 주소 풀에서 IP 주소를 선택합니다.

특정 시점에 사용자 클러스터에서 활성화될 가능성이 높은 LoadBalancer 유형의 여러 가지 서비스를 생각해 봅니다. 그런 다음 사용자 클러스터 구성 파일의 loadBalancer.metalLB.addressPools 섹션에서 해당 서비스를 수용하도록 IP 주소를 충분하게 지정합니다.

사용자 클러스터의 인그레스 VIP는 주소 풀에서 지정한 주소 중 하나여야 합니다. 이는 인그레스 프록시가 LoadBalancer 유형의 서비스에 의해 노출되기 때문입니다.

애플리케이션 개발자가 LoadBalancer 유형의 서비스를 만들 필요가 없으면 인그레스 VIP 이외의 주소를 지정할 필요가 없습니다.

주소는 CIDR 형식이나 범위 형식이어야 합니다. 개별 주소를 지정하려면 /32 CIDR을 사용합니다. 예를 들면 다음과 같습니다.

addresses:
  - "192.0.2.0/26"
  - "192.0.2.64-192.0.2.72"
  - "192.0.2.75/32

클러스터를 만든 후 풀의 주소를 조정해야 하면 gkectl update cluster를 사용합니다. 자세한 내용은 MetalLB 업데이트를 참조하세요.

새 사용자 클러스터에 MetalLB 사용 설정

사용자 클러스터 구성 파일에서 다음을 수행합니다.

  • loadBalancer.kind"MetalLB"로 설정합니다.
  • 서비스에 주소 풀을 하나 이상 지정합니다. 인그레스 VIP는 이러한 풀 중 하나에 있어야 합니다.
  • 클러스터에 있는 노드 풀 최소 하나 이상에 enableLoadBalancertrue로 설정합니다.

사용자 클러스터 구성 파일의 나머지 부분을 작성하고 사용자 클러스터 만들기의 설명대로 사용자 클러스터를 만듭니다.

서비스 주소 수동 할당

MetalLB 컨트롤러에서 특정 풀의 IP 주소를 서비스에 자동으로 할당하지 않게 하려면 풀의 manualAssign 필드를 true로 설정합니다. 그러면 개발자는 LoadBalancer 유형의 서비스를 만들고 풀에서 주소 중 하나를 수동으로 지정할 수 있습니다. 예를 들면 다음과 같습니다.

loadBalancer:
  metalLB:
    addressPools:
    - name: "my-address-pool-2"
      addresses:
      - "192.0.2.73-192.0.2.80"
      manualAssign: true

버그가 있는 IP 주소 방지

주소 풀의 avoidBuggyIPs 필드를 true로 설정하면 MetalLB 컨트롤러가 .0 또는 .255로 끝나는 풀의 주소를 사용하지 않습니다. 이렇게 하면 버그가 있는 소비자 기기가 특수한 IP 주소로 전송된 트래픽을 실수로 차단하는 문제를 방지할 수 있습니다. 예를 들면 다음과 같습니다.

loadBalancer:
  metalLB:
    addressPools:
    - name: "my-address-pool-1"
      addresses:
      - "192.0.2.0/24"
      avoidBuggyIPs: true

LoadBalancer 유형의 서비스 만들기

매니페스트는 배포용과 서비스용으로 두 가지입니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  selector:
    matchLabels:
      greeting: hello
  replicas: 3
  template:
    metadata:
      labels:
        greeting: hello
    spec:
      containers:
      - name: hello
        image: gcr.io/google-samples/hello-app:2.0
---
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: LoadBalancer
  selector:
    greeting: hello
  ports:
  - name: metal-lb-example-port
    protocol: TCP
    port: 60000
    targetPort: 8080

서비스 매니페스트는 외부 IP 주소를 지정하지 않습니다. MetalLB 컨트롤러는 사용자 클러스터 구성 파일에 지정한 주소 풀에서 외부 IP 주소를 선택합니다.

매니페스트를 my-dep-svc.yaml이라는 파일에 저장합니다. 그런 다음 배포 객체와 서비스 객체를 만듭니다.

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG apply -f my-dep-svc.yaml

서비스를 확인합니다.

kubectl --kubeconfig USER_CLUSTER_KUBECONIFG get service my-service --output wide

출력에는 서비스에 자동으로 할당된 외부 IP 주소가 표시됩니다. 예를 들면 다음과 같습니다.

NAME         TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)           AGE   SELECTOR
my-service   LoadBalancer   10.96.2.166   192.0.2.2   60000:31914/TCP   28s

할당된 외부 IP 주소를 사용자 클러스터 구성 파일에서 지정한 주소 풀에서 가져왔는지 확인합니다. 예를 들어 192.0.2.2는 다음 주소 풀에 있습니다.

metalLB:
  addressPools:
  - name: "address-pool-1"
    addresses:
     - "192.0.2.0/24"
     - "198.51.100.1-198.51.100.3"

서비스를 호출합니다.

curl EXTERNAL_IP_ADDRESS:60000

출력에 Hello, world! 메시지가 표시됩니다.

Hello, world!
Version: 2.0.0

MetalLB 업데이트

클러스터를 만든 후 주소 풀의 MetalLB 및 노드 풀의 enableLoadBalancer 필드를 업데이트할 수 있습니다. 사용자 클러스터 구성 파일에서 원하는 사항을 변경하고 gkectl update cluster를 호출합니다.

gkectl update cluster --kubeconfig ADMIN_CLUSTER_KUBECONIFG --config USER_CLUSTER_CONFIG

MetalLB 포드 및 ConfigMap

MetalLB 컨트롤러는 배포로 실행되고 MetalLB 스피커는 enableLoadBalancertrue로 설정한 풀의 노드에서 DaemonSet으로 실행됩니다. MetalLB 컨트롤러에서 서비스에 할당된 IP 주소를 관리합니다. MetalLB 스피커는 리더를 선택하고 서비스 VIP를 발표합니다.

모든 MetalLB 포드를 확인합니다.

kubectl --kubeconfig USER_CLUSTER_KUBECONIFG get pods --namespace kube-system --selector app=metallb

문제를 해결하기 위해 MetalLB 포드의 로그를 사용할 수 있습니다.

MetalLB 구성은 MetalLB에 의해 알려진 형식으로 ConfigMap에 저장됩니다. ConfigMap을 직접 변경하지 마세요. 대신 앞의 설명대로 gkectl update cluster를 사용합니다. 문제를 해결하기 위해 ConfigMap을 보려면 다음 명령을 실행합니다.

kubectl --kubeconfig USER_CLUSTER_KUBECONIFG get configmap metallb-config --namespace kube-system

MetalLB 사용의 이점

  • MetalLB는 클러스터 노드에서 직접 실행되므로 추가 VM이 필요하지 않습니다.

  • MetalLB 컨트롤러는 서비스의 IP 주소 관리를 수행하므로 각 서비스의 IP 주소를 직접 선택할 필요가 없습니다.

  • 여러 서비스에 대한 MetalLB의 활성 인스턴스가 서로 다른 노드에서 실행될 수 있습니다.

  • 여러 서비스 간에 IP 주소를 공유할 수 있습니다.

F5 BIG-IP 및 Seesaw와 비교 가능한 MetalLB

  • VIP는 클러스터 노드와 동일한 서브넷에 있어야 합니다. 이는 Seesaw의 요구사항이기도 하지만 F5 BIG-IP의 요구사항은 아닙니다.

  • 트래픽 측정항목이 없습니다.

  • 자동 장애 조치가 없습니다. 기존 연결이 장애 조치 중에 재설정됩니다.

  • 특정 서비스의 포드에 대한 외부 트래픽은 MetalLB 스피커를 실행하는 단일 노드를 통과합니다. 즉, 클라이언트 IP 주소는 일반적으로 포드에서 실행되는 컨테이너에 표시되지 않습니다.