다중 네트워크 LoadBalancer 서비스 배포

이 문서에서는 GKE에서외부 패스 스루 네트워크 부하 분산기 및내부 패스 스루 네트워크 부하 분산기 리소스를 만들어 다중 네트워크 포드를 내부 또는 외부 클라이언트에 노출하는 방법을 보여줍니다. Google Cloud 다중 네트워크 LoadBalancer 서비스의 필수 구성, 기능, 제한사항을 설명합니다.

워크로드를 여러 VPC 네트워크에 연결하는 경우 LoadBalancer 유형의 Kubernetes 서비스를 사용하여 트래픽을 특정 보조 네트워크의 포드로 라우팅합니다. 서비스를 만들면 GKE는 이 트래픽을 관리하기 위해 패스 스루 네트워크 부하 분산기를 만듭니다.

GKE의 다중 네트워킹에 대한 자세한 내용은 포드의 다중 네트워크 지원 정보를참조하세요.

다중 네트워크 LoadBalancer 서비스 작동 방식

다중 네트워크 워크로드를 노출하려면 type: LoadBalancerService를 만듭니다. 서비스에는 보조 인터페이스의 네트워크를 기반으로 포드를 타겟팅하는 특수 선택기가 포함되어야 합니다. 내부 또는 외부 부하 분산기를 만들지 여부를 지정하는 주석을 추가합니다.

선택기의 networking.gke.io/network 라벨은 네트워크별로 엔드포인트를 필터링합니다. 이 라벨은 부하 분산기가 지정된 네트워크에 연결된 포드 인터페이스로만 트래픽을 전송하도록 합니다.

제한사항

다중 네트워크 부하 분산기에는 다음과 같은 제한사항이 있습니다.

  • externalTrafficPolicy: Cluster를 사용하는 서비스는 지원되지 않습니다.
  • hostNetwork 포드를 타겟팅하는 서비스는 지원되지 않습니다.
  • IPv6 및 이중 스택 네트워킹은 지원되지 않습니다.
  • 기존 서비스의 네트워크는 변경할 수 없습니다.
  • 레이어 3 네트워크만 지원됩니다.
  • 대상 풀 또는 인스턴스 그룹 백엔드를 기반으로 하는 부하 분산기는 지원되지 않습니다.
  • ClusterIP 및 NodePort 서비스는 보조 (기본이 아닌) 네트워크에서 지원되지 않습니다.

시작하기 전에

시작하기 전에 다음 작업을 완료하세요.

  1. 포드의 다중 네트워크 지원 설정 의 단계에 따라 VPC 네트워크를 준비하고 추가 네트워크가 있는 GKE 클러스터를 만듭니다.
  2. 클러스터에 레이어 4 내부 부하 분산기의 하위 설정이 사용 설정되어 있는지 확인합니다. 이 기능을 사용 설정하려면 클러스터를 만들거나 업데이트할 때 --enable-l4-ilb-subsetting 플래그를 사용합니다.
  3. 클러스터가 GKE 버전 1.37 이상을 실행하는지 확인합니다.

다중 네트워크 포드 배포

포드를 추가 네트워크에 연결하려면 networking.gke.io/interfaces 주석이 있는 배포를 만듭니다. 이 주석은 포드의 네트워크와 인터페이스를 지정합니다.

  1. 다음 매니페스트를 web-app-deployment.yaml로 저장합니다.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: web-app
      labels:
        app: web-app
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: web-app
      template:
        metadata:
          labels:
            app: web-app
          annotations:
            networking.gke.io/default-interface: 'eth1'
            networking.gke.io/interfaces: '[
              {"interfaceName":"eth0","network":"default"},
              {"interfaceName": "eth1","network": "dmz"}
            ]'
    spec:
      containers:
      - name: whereami
        image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1
        ports:
        - containerPort: 8080
    

    이 매니페스트는 포드가 3개 있는 web-app이라는 배포를 만듭니다. 포드에는 default 네트워크에 연결된 eth0dmz 네트워크에 연결된 eth1이라는 두 개의 인터페이스가 있습니다. networking.gke.io/default-interface 주석은 eth1을 포드의 기본 인터페이스로 설정합니다.

  2. 매니페스트를 클러스터에 적용합니다.

    kubectl apply -f web-app-deployment.yaml
    

서비스에 기본이 아닌 인터페이스를 사용하는 경우 포드 내에서 라우팅을 구성해야 합니다. 라우팅을 구성하려면 NET_ADMIN 기능이 있는 initContainer를 포드 사양에 추가합니다.

다음 예시에서는 eth1 인터페이스의 기본 경로를 추가하는 initContainer를 보여줍니다.

initContainers:
      - name: init-routes-busybox
        image: busybox
        command: ['sh', '-c', 'ip route add default dev eth1 table 200 && ip rule add from 172.16.1.0/24 table 200']
        securityContext:
          capabilities:
            add: ["NET_ADMIN"]

initContainer 명령어에서 172.16.1.0/24를 포드 네트워크의 보조 IP 주소 범위로 바꿉니다.

내부 LoadBalancer 서비스 배포

dmz 네트워크에서 web-app 배포를 노출하려면 내부 LoadBalancer 서비스를 만듭니다.

  1. 다음 매니페스트를 internal-lb-service.yaml로 저장합니다.

    apiVersion: v1
    kind: Service
    metadata:
      name: web-app-internal-lb
      namespace: default
      annotations:
        networking.gke.io/load-balancer-type: "Internal"
    spec:
      externalTrafficPolicy: Local
      ports:
      -   port: 80
        protocol: TCP
        targetPort: 8080
      selector:
        networking.gke.io/network: dmz
        app: web-app
      type: LoadBalancer
    

    이 매니페스트는 다음 속성을 사용해서 서비스를 기술합니다.

    • networking.gke.io/load-balancer-type: "Internal": 내부 패스 스루 네트워크 부하 분산기를 지정합니다.
    • selector: dmz 네트워크에 연결된 app: web-app 라벨이 있는 포드를 선택합니다.
  2. 매니페스트를 클러스터에 적용합니다.

    kubectl apply -f internal-lb-service.yaml
    

외부 LoadBalancer 서비스 배포

web-app 배포를 외부 클라이언트에 노출하려면 외부 LoadBalancer 서비스를 만듭니다.

  1. 다음 매니페스트를 external-lb-service.yaml로 저장합니다.

    apiVersion: v1
    kind: Service
    metadata:
      name: web-app-external-lb
      namespace: default
      annotations:
        cloud.google.com/l4-rbs: "enabled"
    spec:
      externalTrafficPolicy: Local
      ports:
      -   port: 80
        protocol: TCP
        targetPort: 8080
      selector:
        networking.gke.io/network: dmz
        app: web-app
      type: LoadBalancer
    

    이 매니페스트는 다음 속성을 사용해서 서비스를 기술합니다.

    • cloud.google.com/l4-rbs: "enabled": 백엔드 서비스 기반 외부 패스 스루 네트워크 부하 분산기를 지정합니다.
    • selector: dmz 네트워크에 연결된 app: web-app 라벨이 있는 포드를 선택합니다.
  2. 매니페스트를 클러스터에 적용합니다.

    kubectl apply -f external-lb-service.yaml
    

서비스 확인

서비스를 배포한 후 부하 분산기가 올바르게 생성되고 구성되었는지 확인합니다.

  1. 서비스 상태를 확인합니다.

    kubectl get services
    

    출력은 다음과 비슷합니다.

    NAME                  TYPE           CLUSTER-IP    EXTERNAL-IP     PORT(S)        AGE
    web-app-external-lb   LoadBalancer   10.8.47.77    35.239.57.231   80:31550/TCP   5m
    web-app-internal-lb   LoadBalancer   10.8.43.251   172.16.0.43     80:32628/TCP   6m
    kubernetes            ClusterIP      10.8.32.1     <none>          443/TCP        43h
    

    내부 부하 분산기의 EXTERNAL-IP 주소는 dmz 네트워크에 속합니다.

  2. 프로젝트의 전달 규칙을 나열합니다.

    gcloud compute forwarding-rules list
    

    출력은 다음과 비슷합니다.

    NAME                                                   REGION        IP_ADDRESS     IP_PROTOCOL  TARGET
    af901673cc0f24907a6aa8c3ce4afc21                       us-central1   35.239.57.231  TCP          us-central1/backendServices/k8s2-xhvzqabw-default-web-app-external-lb-u4xbs4ot
    k8s2-tcp-xhvzqabw-default-web-app-internal-lb-vp1x1d6a us-central1   172.16.0.43    TCP          us-central1/backendServices/k8s2-xhvzqabw-default-web-app-internal-lb-vp1x1d6a
    
  3. 내부 부하 분산기의 전달 규칙을 설명하여 올바른 네트워크에 연결되어 있는지 확인합니다.

    gcloud compute forwarding-rules describe k8s2-tcp-xhvzqabw-default-web-app-internal-lb-vp1x1d6a --region=$REGION
    

    REGION을 클러스터의 리전으로 바꿉니다.

    출력은 다음과 비슷합니다. networksubnetwork 필드가 dmz 네트워크의 세부정보와 일치하는지 확인합니다.

    IPAddress: 172.16.0.43
    IPProtocol: TCP
    ...
    loadBalancingScheme: INTERNAL
    name: k8s2-tcp-xhvzqabw-default-web-app-internal-lb-vp1x1d6a
    network: https://www.googleapis.com/compute/v1/projects/projectId/global/networks/dmz-vpc
    ...
    subnetwork: https://www.googleapis.com/compute/v1/projects/projectId/regions/us-central1/subnetworks/dmz-subnet
    

부하 분산기 테스트

  1. 외부 부하 분산기를 테스트하려면 외부 IP 주소로 요청을 보냅니다.

    curl EXTERNAL_LB_IP:80
    

    EXTERNAL_LB_IPweb-app-external-lb 서비스의 외부 IP 주소로 바꿉니다.

  2. 내부 부하 분산기를 테스트하려면 부하 분산기와 동일한 VPC의 호스트에서 요청을 보냅니다.

    curl INTERNAL_LB_IP:80
    

    INTERNAL_LB_IPweb-app-internal-lb 서비스의 IP 주소로 바꿉니다.

문제 해결

이 섹션에서는 다중 네트워크 부하 분산기 문제를 해결하는 방법을 설명합니다.

부하 분산기 생성 실패

부하 분산기 생성이 실패하면 서비스 이벤트에서 오류 메시지를 확인합니다.

kubectl describe service SERVICE_NAME

SERVICE_NAME을 서비스 이름으로 바꿉니다.

network some-other-network does not exist와 같은 오류 메시지는 서비스 선택기에 지정된 네트워크가 클러스터에 정의되어 있지 않음을 나타냅니다. 네트워크가 있는지 확인합니다.

kubectl get networks

네트워크가 있는 경우 Network 객체가 유효한 GKENetworkParamSet 리소스를 올바르게 참조하는지 확인합니다. 구성 오류를 확인하려면 Network 리소스 상태를 검사합니다.

kubectl get networks NETWORK_NAME -o yaml

NETWORK_NAME을 네트워크 이름으로 바꿉니다.

유효한 구성에서는 ParamsReadyReady 조건이 모두 True입니다. ParamsReadyTrue가 아닌 경우 Network 사양의 parametersRef가 기존 GKENetworkParamSet 리소스의 이름, 종류, 그룹과 올바르게 일치하는지 확인합니다.

Network 리소스가 올바르지만 아직 준비되지 않은 경우 참조된 GKENetworkParamSet의 상태에서 서브넷 누락과 같은 오류를 확인합니다.

kubectl get gkenetworkparamsets GNP_NAME -o yaml

GNP_NAMEGKENetworkParamSet의 이름으로 바꿉니다.

부하 분산기에 백엔드가 없음

부하 분산기가 프로비저닝되었지만 정상 백엔드가 없는 경우 다음 단계를 따르세요.

  1. 서비스에서 사용하는 네트워크에 네트워크 인터페이스가 있는 노드 풀이 있는지 확인합니다.
  2. 서비스에서 선택한 포드가 실행 중인지 확인합니다.
  3. 서비스의 엔드포인트를 확인합니다.

    kubectl describe endpointslice -l kubernetes.io/service-name=SERVICE_NAME
    

    multinet-endpointslice-controller.gke.io 컨트롤러는 다중 네트워크 엔드포인트를 만듭니다. EndpointSlice에 나열된 포드 IP 주소는 서비스에서 사용하는 네트워크에 속합니다. EndpointSlice에 엔드포인트가 없는 경우 서비스 선택기 라벨이 실행 중인 포드와 일치하고 네트워크 선택기가 포드의 네트워크와 일치하는지 확인합니다.

다음 단계