독립형 영역별 NEG를 통한 컨테이너 기반 부하 분산


이 페이지에서는 Google Kubernetes Engine(GKE) VPC 기반 클러스터영역 GCE_VM_IP_PORT 네트워크 엔드포인트 그룹(NEG)에서 지원되는 Kubernetes 서비스를 만드는 방법을 보여줍니다.

컨테이너 기반 부하 분산의 이점, 요구사항, 제한사항에 대한 자세한 내용은 컨테이너 기반 부하 분산을 참조하세요.

개요

NEG는 엔드포인트의 그룹을 나타냅니다. GKE는 GCE_VM_IP_PORT 유형의 독립형 NEG를 지원합니다. GCE_VM_IP_PORT NEG는 VM의 기본 내부 IP 주소 또는 별칭 IP 범위 중 하나의 IP 주소를 사용하는 엔드포인트를 지원합니다.

독립형 NEG를 사용하는 GKE VPC 기반 클러스터의 경우 각 엔드포인트는 포드 IP 주소와 대상 포트입니다. 포드 IP 주소는 포드의 노드 별칭 IP 범위에서 제공되며, 이는 포드에 대한 클러스터의 서브넷 보조 IP 주소 범위에서 가져옵니다.

GKE는 GCE_VM_IP_PORT NEG의 멤버십 관리를 위해 NEG 컨트롤러를 제공합니다. 생성되는 NEG를 GKE API 외부에서 구성하는 부하 분산기의 백엔드 서비스에 백엔드로 추가할 수 있습니다.

다음 다이어그램은 Kubernetes API 객체가 어떻게 Compute Engine 객체에 해당하는지를 설명합니다.

Kubernetes 서비스는 Compute Engine 네트워크 엔드포인트 그룹에 해당하고 Kubernetes 포드는 Compute Engine 네트워크 엔드포인트에 해당합니다. 제어 영역의 NEG 컨트롤러 구성요소가 이를 관리합니다.

NEG를 사용한 인그레스

NEG가 GKE 인그레스와 함께 사용되면 인그레스 컨트롤러는 부하 분산기의 모든 측면의 생성을 용이하게 해줍니다. 여기에는 가상 IP 주소, 전달 규칙, 상태 확인, 방화벽 규칙 등이 포함됩니다.

인그레스에는 NEG 관리를 간소화하는 기능이 많이 있으므로 컨테이너 기반 부하 분산을 사용하기 위한 권장되는 방법입니다. 인그레스에서 관리하는 NEG가 사용 사례에 해당되지 않는 경우 독립형 NEG를 옵션으로 사용할 수 있습니다.

독립형 NEG

NEG가 인그레스 이외의 다른 방법으로 프로비저닝된 부하 분산기와 함께 배포되는 경우 독립형 NEG로 간주됩니다. 독립형 NEG는 NEG 컨트롤러를 통해 배포 및 관리되지만 전달 규칙, 상태 확인, 기타 부하 분산 객체는 수동으로 배포됩니다.

독립형 NEG는 인그레스가 사용 설정된 컨테이너 기반 부하 분산과 충돌하지 않습니다.

다음 이미지는 각 시나리오에서 부하 분산 객체가 배포되는 방식의 차이점을 보여줍니다.

독립형 NEG 및 인그레스 관리형 NEG를 사용하면 GKE 제어 영역의 NEG 컨트롤러가 NEG 및 네트워크 엔드포인트 객체를 관리합니다. 독립형 NEG에서 다른 모든 구성 요소는 이전 단락에서 설명한 대로 사용자에 의해 관리됩니다.

NEG 유출 방지

독립형 NEG에서는 부하 분산기를 구성하는 리소스와 NEG의 수명 주기를 사용자가 관리해야 합니다. NEG가 유출되는 방법은 다음과 같습니다.

  • GKE 서비스를 삭제해도 백엔드 서비스에서 NEG를 계속 참조하는 경우 연결된 NEG는 가비지로 수집되지 않습니다. NEG 삭제를 허용하려면 백엔드 서비스에서 NEG를 참조 해제합니다.
  • 클러스터가 삭제되더라도 독립형 NEG는 삭제되지 않습니다.

독립형 NEG 사용 사례

독립형 NEG에는 여러 가지 중요한 용도가 있습니다. 독립형 NEG는 매우 유연합니다. 이는 인그레스(NEG와 함께 사용되거나 NEG 없이 사용됨)와 대비되는 특성입니다. 인그레스는 사용의 용이함을 위해 독단적인 방식으로 선택된 특정 부하 분산 객체 집합을 정의합니다.

독립형 NEG의 사용 사례는 다음과 같습니다.

컨테이너 및 VM의 이기종 서비스

NEG에는 VM과 컨테이너 IP 주소가 모두 포함될 수 있습니다. 이는 단일 가상 IP 주소가 Kubernetes 및 비 Kubernetes 워크로드 두 가지 모두로 구성된 백엔드를 가리킬 수 있음을 의미합니다. 기존 워크로드를 GKE 클러스터로 마이그레이션하는 데도 사용할 수 있습니다.

독립형 NEG는 VM IP를 가리킬 수 있으므로 같은 서비스 VIP의 VM과 컨테이너로 구성된 백엔드를 가리키도록 부하 분산기를 수동으로 구성할 수 있습니다.

맞춤설정된 인그레스 컨트롤러

맞춤설정된 인그레스 컨트롤러를 사용하여(또는 인그레스 컨트롤러 없이) 독립형 NEG를 대상으로 하는 부하 분산기를 구성할 수 있습니다.

GKE에서 Traffic Director 사용

Traffic Director를 GKE와 함께 사용할 수 있습니다. Traffic Director는 독립형 NEG를 사용하여 관리형 서비스 메시에 컨테이너 기반 부하 분산을 제공합니다.

GKE에서 외부 프록시 네트워크 부하 분산기 사용

독립형 NEG를 사용하여 Kubernetes/GKE에서 기본적으로 지원하지 않는 외부 프록시 네트워크 부하 분산기로 컨테이너에 직접 부하를 분산할 수 있습니다.

포드 준비

준비 게이트는 포드가 준비 상태로 전환할 수 있도록 PodStatus에 추가 피드백 또는 신호를 삽입할 수 있도록 하는 Kubernetes의 확장 기능입니다. NEG 컨트롤러는 커스텀 준비 게이트를 관리하여 Compute Engine 부하 분산기에서 포드까지 전체 네트워크 경로를 보장합니다. GKE의 포드 준비 게이트는 컨테이너 기반 부하 분산에 설명되어 있습니다.

NEG를 사용한 인그레스는 부하 분산기를 대신하여 Compute Engine 상태 확인을 배포하고 관리합니다. 그러나 독립형 NEG는 별도로 배포 및 관리되는 것으로 예상되므로 Compute Engine 상태 확인에 대해 아무런 가정도 하지 않습니다. Compute Engine 상태 확인은 수신 준비가 되지 않은 백엔드로 트래픽이 전송되지 않도록 항상 부하 분산기와 함께 구성되어야 합니다. NEG와 연결된 상태 확인 상태가 없는 경우(일반적으로 상태 확인이 구성되지 않은 이유로) NEG 컨트롤러는 NEG에서 해당 엔드포인트가 프로그래밍될 때 포드의 준비 게이트 값을 True로 표시합니다.

요구사항

클러스터는 VPC 기반이어야 합니다. 자세한 내용은 VPC 기반 클러스터 만들기를 참조하세요.

클러스터에 HttpLoadBalancing 부가기능이 사용 설정되어 있어야 합니다. GKE 클러스터에는 기본적으로 HttpLoadBalancing 부가기능이 사용 설정되어 있습니다.

시작하기 전에

시작하기 전에 다음 태스크를 수행했는지 확인합니다.

  • Google Kubernetes Engine API를 사용 설정합니다.
  • Google Kubernetes Engine API 사용 설정
  • 이 태스크에 Google Cloud CLI를 사용하려면 gcloud CLI를 설치한 후 초기화합니다. 이전에 gcloud CLI를 설치한 경우 gcloud components update를 실행하여 최신 버전을 가져옵니다.

독립형 NEG 사용

다음 안내에서는 GKE로 외부 HTTP 부하 분산기와 함께 독립형 NEG를 사용하는 방법을 보여줍니다.

다음 객체를 만들어야 합니다.

  • 포드를 만들고 관리하는 배포
  • NEG를 만드는 서비스
  • Compute Engine API로 생성되는 부하 분산기 이는 인그레스에서 NEG를 사용(이 경우 인그레스가 자동으로 부하 분산기를 만들고 구성함)하는 것과는 다릅니다. 독립형 NEG에서는 사용자가 직접 NEG와 백엔드 서비스를 연결하여 포드를 부하 분산기에 연결해야 합니다. 부하 분산기는 다음 다이어그램에 표시된 몇 가지 구성요소들로 구성됩니다.

부하 분산기의 구성요소는 전달 규칙, 대상 HTTP 프록시, URL 맵, 상태 확인, 백엔드 서비스입니다. 이는 포드 IP 주소가 포함된 NEG로 트래픽을 전달합니다.

VPC 기반 클러스터 만들기

Autopilot 클러스터는 기본적으로 VPC 기반이므로 워크로드 배포로 건너뛸 수 있습니다.

표준 클러스터의 경우 us-central1-a 영역에 VPC 기반 클러스터를 만듭니다.

gcloud container clusters create neg-demo-cluster \
    --create-subnetwork="" \
    --network=default \
    --zone=us-central1-a

배포 만들기

다음 예시 매니페스트는 컨테이너화된 HTTP 서버의 3개 인스턴스를 실행하는 배포를 지정합니다. HTTP 서버는 애플리케이션 서버의 호스트 이름, 서버가 실행 중인 포드의 이름으로 요청에 응답합니다.

포드 준비 피드백을 사용하는 워크로드를 사용하는 것이 좋습니다.

포드 준비 상태 피드백 사용

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: neg-demo-app # Label for the Deployment
  name: neg-demo-app # Name of Deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      run: neg-demo-app
  template: # Pod template
    metadata:
      labels:
        run: neg-demo-app # Labels Pods from this Deployment
    spec: # Pod specification; each Pod created by this Deployment has this specification
      containers:
      - image: registry.k8s.io/serve_hostname:v1.4 # Application to run in Deployment's Pods
        name: hostname
  

하드코딩된 지연 사용

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: neg-demo-app # Label for the Deployment
  name: neg-demo-app # Name of Deployment
spec:
  minReadySeconds: 60 # Number of seconds to wait after a Pod is created and its status is Ready
  replicas: 3
  selector:
    matchLabels:
      run: neg-demo-app
  template: # Pod template
    metadata:
      labels:
        run: neg-demo-app # Labels Pods from this Deployment
    spec: # Pod specification; each Pod created by this Deployment has this specification
      containers:
      - image: registry.k8s.io/serve_hostname:v1.4 # Application to run in Deployment's Pods
        name: hostname
  

이 매니페스트를 neg-demo-app.yaml로 저장한 후 다음 명령어를 실행하여 배포를 만듭니다.

kubectl apply -f neg-demo-app.yaml

서비스 만들기

다음 매니페스트는 다음과 같은 서비스를 지정합니다.

  • run: neg-demo-app 라벨이 있는 모든 포드는 이 서비스의 구성원입니다.
  • 서비스에는 하나의 ServicePort 필드가 있습니다(포트 80).
  • cloud.google.com/neg 주석은 포트 80이 NEG와 연결되도록 지정합니다. 선택사항인 name 필드는 NEG의 이름을 NEG_NAME으로 지정합니다. name 필드가 생략되면 고유 이름이 자동으로 생성됩니다. 자세한 내용은 NEG 이름 지정을 참조하세요.
  • 각 구성원 포드에는 TCP 포트 9376에서 리슨하는 컨테이너가 있어야 합니다.
apiVersion: v1
kind: Service
metadata:
  name: neg-demo-svc
  annotations:
    cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "NEG_NAME"}}}'
spec:
  type: ClusterIP
  selector:
    run: neg-demo-app # Selects Pods labelled run: neg-demo-app
  ports:
  - port: 80
    protocol: TCP
    targetPort: 9376

NEG_NAME을 NEG 이름으로 바꿉니다. NEG 이름은 리전 내에서 고유해야 합니다.

이 매니페스트를 neg-demo-svc.yaml로 저장한 후 다음 명령어를 실행하여 서비스를 만듭니다.

kubectl apply -f neg-demo-svc.yaml

NEG는 서비스 생성 후 몇 분 내에 생성됩니다.

서비스 유형

이 예시는 ClusterIP 서비스를 사용하지만 5개의 서비스 유형 모두 독립형 NEG를 지원합니다. 기본 유형인 ClusterIP를 사용하는 것이 좋습니다.

NEG 이름 지정

GKE 버전 1.18.18-gke.1200 이상에서는 NEG에 커스텀 이름을 지정할 수 있습니다. 또는 GKE가 이름을 자동으로 생성할 수 있습니다. 이전 버전의 GKE는 자동 생성된 NEG 이름만 지원합니다.

GKE는 클러스터에 사용되는 각 영역에 하나의 NEG를 만듭니다. NEG에는 모두 동일한 이름이 사용됩니다.

이름 지정

NEG의 이름 및 영역을 미리 알고 있으므로 커스텀 NEG 이름을 지정하여 부하 분산기 구성을 간소화합니다. 커스텀 NEG 이름은 다음 요구사항을 충족해야 합니다.

  • 영역 클러스터의 경우 클러스터의 영역에 고유해야 하고 리전 클러스터의 경우 리전에 고유해야 합니다.
  • GKE NEG 컨트롤러에서 생성되지 않은 기존 NEG의 이름과 일치하지 않아야 합니다.
  • 밑줄을 포함해서는 안 됩니다.

서비스의 cloud.google.com/neg 주석에 있는 name 필드를 사용하여 NEG 이름을 지정합니다.

cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "NEG_NAME"}}}'

NEG_NAME을 NEG 이름으로 바꿉니다. NEG 이름은 리전 내에서 고유해야 합니다.

자동으로 생성된 이름 사용

자동으로 생성된 NEG 이름은 고유합니다. 자동으로 생성된 이름을 사용하려면 name 필드를 생략합니다.

cloud.google.com/neg: '{"exposed_ports": {"80":{}}}'

자동 생성된 이름은 형식이 다음과 같습니다.

k8s1-CLUSTER_UID-NAMESPACE-SERVICE-PORT-RANDOM_HASH

여러 NEG에 포트 매핑

서비스는 두 개 이상의 포트에서 리슨할 수 있습니다. 기본적으로 NEG에는 단일 IP 주소와 포트만 있습니다. 즉, 포트가 여러 개인 서비스를 지정하면 각 포트에 대해 NEG가 생성됩니다.

cloud.google.com/neg 주석의 형식은 다음과 같습니다.

cloud.google.com/neg: '{
   "exposed_ports":{
      "SERVICE_PORT_1":{},
      "SERVICE_PORT_2":{},
      "SERVICE_PORT_3":{},
      ...
   }
 }'

이 예시에서 각 SERVICE_PORT_N 인스턴스는 서비스의 기존 서비스 포트를 참조하는 고유한 포트 번호입니다. NEG 컨트롤러는 나열된 각 서비스 포트에 대해 클러스터가 점유하는 각 영역에 NEG를 하나씩 만듭니다.

NEG 상태 검색

다음 명령어를 사용하여 클러스터의 서비스 상태를 검색합니다.

kubectl get service neg-demo-svc -o yaml

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

cloud.google.com/neg-status: '{
   "network-endpoint-groups":{
      "SERVICE_PORT_1": "NEG_NAME_1",
      "SERVICE_PORT_2": "NEG_NAME_2",
      ...
   },
   "zones":["ZONE_1", "ZONE_2", ...]
}

이 출력에서 network-endpoint-groups 매핑의 각 요소는 서비스 포트(예: SERVICE_PORT_1)와 해당 관리형 NEG의 이름(예: NEG_NAME_1)입니다. zones 목록에는 NEG가 있는 모든 영역(예: ZONE_1)이 포함됩니다.

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

apiVersion: v1
kind: Service
metadata:
  annotations:
    cloud.google.com/neg: '{"exposed_ports": {"80":{}}}'
    cloud.google.com/neg-status: '{"network_endpoint_groups":{"80":"k8s1-cca197ad-default-neg-demo-app-80-4db81e02"},"zones":["ZONE_1", "ZONE_2"]}'
  labels:
    run: neg-demo-app
  name: neg-demo-app
  namespace: default
  selfLink: /api/v1/namespaces/default/services/neg-demo-app
  ...
spec:
  clusterIP: 10.0.14.252
  ports:
  - port: 80
    protocol: TCP
    targetPort: 9376
  selector:
    run: neg-demo-app
  sessionAffinity: None
status:
  loadBalancer: {}

이 예시에서 주석은 서비스 포트 80이 k8s1-cca197ad-default-neg-demo-app-80-4db81e02라는 NEG에 노출되었음을 보여줍니다.

NEG 생성 확인

NEG는 서비스 생성 후 몇 분 내에 생성됩니다. 서비스 매니페스트에 지정된 라벨과 일치하는 포드가 있으면 생성 시 NEG에 포드의 IP가 포함됩니다.

NEG가 생성되고 올바르게 구성되었는지 확인하는 두 가지 방법이 있습니다. GKE 1.18.6-gke.6400 이상에서 커스텀 리소스 ServiceNetworkEndpointGroup은 서비스 컨트롤러에서 생성된 NEG에 대한 상태 정보를 저장합니다. 이전 버전에서는 NEG를 직접 검사해야 합니다.

ServiceNetworkEndpointGroup 리소스

모든 ServiceNetworkEndpointGroup 리소스를 가져와 클러스터의 NEG를 나열합니다.

kubectl get svcneg

ServiceNetworkEndpointGroup 리소스의 상태를 확인하여 NEG의 상태를 확인합니다.

kubectl get svcneg NEG_NAME -o yaml

NEG_NAME을 검사하려는 개별 NEG의 이름으로 바꿉니다.

이 명령어의 출력에는 오류 메시지가 포함될 수 있는 상태 섹션이 포함됩니다. 일부 오류는 서비스 이벤트로 보고됩니다. 서비스 객체를 쿼리하면 자세한 내용을 확인할 수 있습니다.

kubectl describe service SERVICE_NAME

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

NEG 컨트롤러가 NEG를 성공적으로 동기화하는지 확인하려면 ServiceNetworkEndpointGroup 리소스의 상태 필드의 조건이 type:Synced인지 확인합니다. 가장 최근의 동기화 시간은 status.lastSyncTime 필드에 있습니다.

ServiceNetworkEndpointGroup 리소스는 GKE 버전 1.18 이상에만 존재합니다.

NEG 직접 검사

Google Cloud 프로젝트의 NEG를 나열하고 생성한 서비스와 일치하는 NEG를 확인하여 NEG가 존재하는지 확인합니다. NEG 이름의 형식은 다음과 같습니다.

k8s1-CLUSTER_UID-NAMESPACE-SERVICE-PORT-RANDOM_HASH

다음 명령어를 사용하여 NEG를 나열합니다.

gcloud compute network-endpoint-groups list

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

NAME                                          LOCATION       ENDPOINT_TYPE   SIZE
k8s1-70aa83a6-default-my-service-80-c9710a6f  ZONE_NAME      GCE_VM_IP_PORT  3

이 출력은 NEG의 SIZE가 3임을 보여줍니다. 즉, 배포의 3개 포드에 해당하는 3개의 엔드포인트가 있음을 의미합니다.

다음 명령어를 사용하여 개별 엔드포인트를 식별합니다.

gcloud compute network-endpoint-groups list-network-endpoints NEG_NAME

NEG_NAME을 개별 엔드포인트를 표시할 NEG 이름으로 바꿉니다.

출력에는 각각 포드의 IP 주소와 포트가 있는 3개의 엔드포인트가 표시됩니다.

INSTANCE                                           IP_ADDRESS  PORT
gke-cluster-3-default-pool-4cc71a15-qlpf  10.12.1.43  9376
gke-cluster-3-default-pool-4cc71a15-qlpf  10.12.1.44  9376
gke-cluster-3-default-pool-4cc71a15-w9nk  10.12.2.26  9376

독립형 NEG에 외부 애플리케이션 부하 분산기 연결

Compute Engine API를 사용하여 NEG를 외부 애플리케이션 부하 분산기의 백엔드로 사용할 수 있습니다.

  1. 방화벽 규칙을 만듭니다. 부하 분산기는 상태 확인을 수행하기 위해 클러스터 엔드포인트에 액세스해야 합니다. 이 명령어는 액세스를 허용하는 방화벽 규칙을 만듭니다.

    gcloud compute firewall-rules create fw-allow-health-check-and-proxy \
       --network=NETWORK_NAME \
       --action=allow \
       --direction=ingress \
       --target-tags=GKE_NODE_NETWORK_TAGS \
       --source-ranges=130.211.0.0/22,35.191.0.0/16 \
       --rules=tcp:9376
    

    다음을 바꿉니다.

    • NETWORK_NAME: 클러스터가 실행되는 네트워크입니다.
    • GKE_NODE_NETWORK_TAGS: GKE 노드의 네트워킹 태그입니다.

    노드에 대해 커스텀 네트워크 태그를 만들지 않은 경우 GKE는 자동으로 태그를 생성합니다. 다음 명령어를 실행하여 이렇게 생성된 태그를 조회할 수 있습니다.

    gcloud compute instances describe INSTANCE_NAME
    

    INSTANCE_NAME을 GKE 노드를 실행하는 호스트 Compute Engine VM 인스턴스의 이름으로 바꿉니다. 예를 들어 이전 섹션의 출력에는 GKE 노드에 대한 INSTANCE 열의 인스턴스 이름이 표시됩니다. 또한 Standard 클러스터의 경우 gcloud compute instances list를 실행하여 프로젝트의 모든 인스턴스를 나열할 수 있습니다.

  2. 부하 분산기의 전역 가상 IP 주소를 만듭니다.

    gcloud compute addresses create hostname-server-vip \
        --ip-version=IPV4 \
        --global
    
  3. 상태 확인을 만듭니다. 이는 부하 분산기에서 NEG 내에 있는 개별 엔드포인트의 활성 여부를 감지하는 데 사용됩니다.

    gcloud compute health-checks create http http-basic-check \
        --use-serving-port
    
  4. 전역 외부 애플리케이션 부하 분산기임을 지정하는 백엔드 서비스를 만듭니다.

    gcloud compute backend-services create my-bes \
        --protocol HTTP \
        --health-checks http-basic-check \
        --global
    
  5. 부하 분산기의 URL 맵대상 프록시를 만듭니다. 이 가이드에 사용된 serve_hostname 앱에는 단일 엔드포인트가 있고 URL이 없으므로 이 예시는 매우 간단합니다.

    gcloud compute url-maps create web-map \
        --default-service my-bes
    
    gcloud compute target-http-proxies create http-lb-proxy \
        --url-map web-map
    
  6. 전달 규칙을 만듭니다. 부하 분산기가 생성됩니다.

    gcloud compute forwarding-rules create http-forwarding-rule \
        --address=HOSTNAME_SERVER_VIP \
        --global \
        --target-http-proxy=http-lb-proxy \
        --ports=80
    

    HOSTNAME_SERVER_VIP를 부하 분산기에 사용할 IP 주소로 바꿉니다. --address를 생략하면 GKE가 자동으로 임시 IP 주소를 할당합니다. 또한 새로운 고정 외부 IP 주소를 예약할 수도 있습니다.

체크포인트

지금까지 생성한 리소스는 다음과 같습니다.

  • 외부 가상 IP 주소
  • 전달 규칙
  • 방화벽 규칙
  • 대상 HTTP 프록시
  • URL 맵 Compute Engine 상태 확인
  • 백엔드 서비스
  • Compute Engine 상태 확인

이러한 리소스 간의 관계는 다음 다이어그램에 나와 있습니다.

이미지

이러한 리소스는 부하 분산기입니다. 다음 단계에서는 부하 분산기에 백엔드를 추가합니다.

여기에 설명된 독립형 NEG의 이점 중 하나는 부하 분산기와 백엔드의 수명 주기가 완전히 독립적일 수 있다는 것입니다. 부하 분산기는 애플리케이션, 서비스 또는 GKE 클러스터가 삭제된 후에도 계속 실행될 수 있습니다. 프런트엔드 부하 분산기 객체를 변경하지 않고 부하 분산기에서 새 NEG 또는 여러 NEG를 추가 및 삭제할 수 있습니다.

부하 분산기에 백엔드 추가

gcloud compute backend-services add-backend를 사용하여 NEG를 my-bes 백엔드 서비스의 백엔드로 추가하여 부하 분산기에 연결합니다.

gcloud compute backend-services add-backend my-bes \
    --global \
    --network-endpoint-group=NEG_NAME \
    --network-endpoint-group-zone=NEG_ZONE \
    --balancing-mode RATE --max-rate-per-endpoint 5

다음을 바꿉니다.

  • NEG_NAME: 네트워크 엔드포인트 그룹의 이름입니다. 이름은 NEG를 만들 때 지정한 이름 또는 자동 생성된 이름입니다. NEG에 대해 이름을 지정하지 않은 경우 다음 안내를 참조하여 자동 생성된 이름을 찾습니다.
  • NEG_ZONE: 네트워크 엔드포인트 그룹이 있는 영역입니다. 이 값을 찾으려면 다음 안내를 참조하세요.

다음 명령어를 사용하여 NEG의 이름과 위치를 가져옵니다.

gcloud compute network-endpoint-groups list

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

NAME                                          LOCATION       ENDPOINT_TYPE   SIZE
k8s1-70aa83a6-default-my-service-80-c9710a6f  ZONE_NAME      GCE_VM_IP_PORT  3

이 예시 출력에서 NEG 이름은 k8s1-70aa83a6-default-my-service-80-c9710a6f입니다.

여러 NEG를 동일한 백엔드 서비스에 추가할 수 있습니다. my-bes와 같은 전역 백엔드 서비스는 여러 리전에 NEG 백엔드가 있을 수 있지만 리전 백엔드 서비스는 단일 리전에 백엔드가 있어야 합니다.

부하 분산기가 작동하는지 확인

설정한 부하 분산기가 작동하는지 확인하는 방법에는 두 가지가 있습니다.

  • 상태 확인이 올바르게 구성되었고 정상 상태를 보고하는지 확인합니다.
  • 애플리케이션에 액세스하여 응답을 확인합니다.

상태 확인을 확인

백엔드 서비스가 상태 확인 및 네트워크 엔드포인트 그룹과 연결되어 있고 개별 엔드포인트가 정상인지 확인합니다.

이 명령어를 사용하여 백엔드 서비스가 상태 확인 및 네트워크 엔드포인트 그룹과 연결되어 있는지 확인합니다.

gcloud compute backend-services describe my-bes --global

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

backends:
- balancingMode: RATE
  capacityScaler: 1.0
  group: ... /networkEndpointGroups/k8s1-70aa83a6-default-my-service-80-c9710a6f
...
healthChecks:
- ... /healthChecks/http-basic-check
...
name: my-bes
...

다음으로 개별 엔드포인트의 상태를 확인합니다.

gcloud compute backend-services get-health my-bes --global

출력의 status: 섹션은 다음과 비슷합니다.

status:
  healthStatus:
  - healthState: HEALTHY
    instance: ... gke-cluster-3-default-pool-4cc71a15-qlpf
    ipAddress: 10.12.1.43
    port: 50000
  - healthState: HEALTHY
    instance: ... gke-cluster-3-default-pool-4cc71a15-qlpf
    ipAddress: 10.12.1.44
    port: 50000
  - healthState: HEALTHY
    instance: ... gke-cluster-3-default-pool-4cc71a15-w9nk
    ipAddress: 10.12.2.26
    port: 50000

애플리케이션에 액세스

부하 분산기의 IP 주소를 통해 애플리케이션에 액세스하여 모든 부분이 작동하는지 확인합니다.

먼저 부하 분산기의 가상 IP 주소를 가져옵니다.

gcloud compute addresses describe hostname-server-vip --global | grep "address:"

출력에 IP 주소가 포함됩니다. 그런 다음 해당 IP 주소로 요청을 보냅니다(이 예시에서는 34.98.102.37).

curl 34.98.102.37

serve_hostname 앱의 응답은 neg-demo-app이어야 합니다.

독립형 NEG에 내부 애플리케이션 부하 분산기 연결

NEG를 사용하여 독립형 GKE 포드에서 실행되는 서비스의 내부 애플리케이션 부하 분산기를 구성할 수 있습니다.

프록시 전용 서브넷 구성

프록시 전용 서브넷은 부하 분산기 리전의 모든 리전 내부 애플리케이션 부하 분산기에 사용됩니다.

콘솔

Google Cloud 콘솔을 사용하는 경우에는 기다렸다가 나중에 프록시 전용 서브넷을 만들 수 있습니다.

gcloud

gcloud compute networks subnets create 명령어를 사용하여 프록시 전용 서브넷을 만듭니다.

gcloud compute networks subnets create proxy-only-subnet \
    --purpose=REGIONAL_MANAGED_PROXY \
    --role=ACTIVE \
    --region=COMPUTE_REGION \
    --network=lb-network \
    --range=10.129.0.0/23

COMPUTE_REGION을 서브넷의 Compute Engine으로 바꿉니다.

API

subnetworks.insert 메서드로 프록시 전용 서브넷을 만듭니다.

POST https://compute.googleapis.com/compute/projects/PROJECT_ID/regions/COMPUTE_REGION/subnetworks
{
  "name": "proxy-only-subnet",
  "ipCidrRange": "10.129.0.0/23",
  "network": "projects/PROJECT_ID/global/networks/lb-network",
  "region": "projects/PROJECT_ID/regions/COMPUTE_REGION",
  "purpose": "REGIONAL_MANAGED_PROXY",
  "role": "ACTIVE"
}

다음을 바꿉니다.

  • PROJECT_ID: 프로젝트 ID입니다.
  • COMPUTE_REGION: 서브넷의 Compute Engine입니다.

방화벽 규칙 구성

이 예시에서는 다음과 같은 방화벽 규칙을 사용합니다.

  • fw-allow-ssh: 부하 분산되는 인스턴스에 적용되는 인그레스 규칙으로, TCP 포트 22에서 임의의 주소로부터 수신되는 SSH 연결을 허용합니다. 이 규칙에 더 제한적인 소스 IP 범위를 선택할 수 있습니다. 예를 들어 SSH 세션을 시작할 시스템의 IP 범위만 지정할 수 있습니다. 이 예시에서는 allow-ssh 대상 태그를 사용하여 방화벽 규칙이 적용되는 VM을 식별합니다.

  • fw-allow-health-check: 부하 분산된 인스턴스에 적용되는 인그레스 규칙으로, Google Cloud 상태 확인 시스템(130.211.0.0/2235.191.0.0/16)의 모든 TCP 트래픽을 허용합니다. 이 예시에서는 load-balanced-backend 대상 태그를 사용하여 적용해야 할 인스턴스를 식별합니다.

  • fw-allow-proxies: 부하 분산되는 인스턴스에 적용되는 인그레스 규칙입니다. 내부 HTTP(S) 부하 분산기의 관리형 프록시로부터의 포트 9376의 TCP 트래픽을 허용합니다. 이 예시에서는 load-balanced-backend 대상 태그를 사용하여 방화벽 규칙이 적용되는 인스턴스를 식별합니다.

이러한 방화벽 규칙이 없으면 기본 거부 인그레스 규칙은 백엔드 인스턴스로 들어오는 트래픽을 차단합니다.

콘솔

  1. Google Cloud 콘솔에서 방화벽 정책 페이지로 이동합니다.

    방화벽 정책으로 이동

  2. 방화벽 규칙 만들기 를 클릭하여 수신 SSH 연결을 허용하는 규칙을 만듭니다.

    • 이름: fw-allow-ssh
    • 네트워크: lb-network
    • 트래픽 방향: 인그레스
    • 일치 시 작업: 허용
    • 대상: 지정된 대상 태그
    • 대상 태그: allow-ssh
    • 소스 필터: IPv4 ranges
    • 소스 IPv4 범위: 0.0.0.0/0
    • 프로토콜 및 포트:
      • 지정된 프로토콜 및 포트를 선택합니다.
      • tcp 체크박스를 선택하고 포트 22를 지정합니다.
  3. 만들기를 클릭합니다.

  4. 방화벽 규칙 만들기 를 다시 클릭하여 Google Cloud 상태 점검을 허용하는 규칙을 만듭니다.

    • 이름: fw-allow-health-check
    • 네트워크: lb-network
    • 트래픽 방향: 인그레스
    • 일치 시 작업: 허용
    • 대상: 지정된 대상 태그
    • 대상 태그: load-balanced-backend
    • 소스 필터: IPv4 ranges
    • 소스 IPv4 범위: 130.211.0.0/2235.191.0.0/16
    • 프로토콜 및 포트:
      • 지정된 프로토콜 및 포트를 선택합니다.
      • tcp 체크박스를 선택하고 포트 80를 지정합니다. 권장사항에 따라서 상태 확인에 사용되는 것과 일치하는 프로토콜 및 포트로 이러한 규칙을 제한합니다. 프로토콜 및 포트에 tcp:80을 사용하면 Google Cloud는 포트 80에서 HTTP를 사용하여 VM에 연결할 수 있지만 포트 443에서 HTTPS를 사용하여 연결할 수는 없습니다.
  5. 만들기를 클릭합니다.

  6. 방화벽 규칙 만들기 를 다시 클릭하여 부하 분산기의 프록시 서버를 백엔드에 연결하도록 허용하는 규칙을 만듭니다.

    • 이름: fw-allow-proxies
    • 네트워크: lb-network
    • 트래픽 방향: 인그레스
    • 일치 시 작업: 허용
    • 대상: 지정된 대상 태그
    • 대상 태그: load-balanced-backend
    • 소스 필터: IPv4 ranges
    • 소스 IPv4 범위: 10.129.0.0/23
    • 프로토콜 및 포트:
      • 지정된 프로토콜 및 포트를 선택합니다.
      • tcp 체크박스를 선택하고 포트 9376를 지정합니다.
  7. 만들기를 클릭합니다.

gcloud

  1. allow-ssh 네트워크 태그를 사용해 VM으로 가는 SSH 연결을 허용하는 fw-allow-ssh 방화벽 규칙을 만듭니다. source-ranges를 생략하면 Google Cloud는 모든 소스를 의미하는 것으로 규칙을 해석합니다.

    gcloud compute firewall-rules create fw-allow-ssh \
        --network=lb-network \
        --action=allow \
        --direction=ingress \
        --target-tags=allow-ssh \
        --rules=tcp:22
    
  2. fw-allow-health-check 규칙을 만들어 Google Cloud 상태 점검을 허용합니다. 이 예시에서는 상태 확인 프로버의 모든 TCP 트래픽을 허용합니다. 그러나 필요에 따라 더 좁은 포트 집합을 구성할 수 있습니다.

    gcloud compute firewall-rules create fw-allow-health-check \
        --network=lb-network \
        --action=allow \
        --direction=ingress \
        --source-ranges=130.211.0.0/22,35.191.0.0/16 \
        --target-tags=load-balanced-backend \
        --rules=tcp
    
  3. 내부 HTTP(S) 부하 분산기의 프록시를 백엔드에 연결하도록 허용하는 fw-allow-proxies 규칙을 만듭니다.

    gcloud compute firewall-rules create fw-allow-proxies \
        --network=lb-network \
        --action=allow \
        --direction=ingress \
        --source-ranges=10.129.0.0/23 \
        --target-tags=load-balanced-backend \
        --rules=tcp:9376
    

API

firewalls.insert 메서드에 POST 요청을 전송하여 fw-allow-ssh 방화벽 규칙을 만듭니다.

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls
{
  "name": "fw-allow-ssh",
  "network": "projects/PROJECT_ID/global/networks/lb-network",
  "sourceRanges": [
    "0.0.0.0/0"
  ],
  "targetTags": [
    "allow-ssh"
  ],
  "allowed": [
   {
     "IPProtocol": "tcp",
     "ports": [
       "22"
     ]
   }
  ],
 "direction": "INGRESS"
}

PROJECT_ID를 프로젝트 ID로 바꿉니다.

firewalls.insert 메서드에 POST 요청을 전송하여 fw-allow-health-check 방화벽 규칙을 만듭니다.

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls
{
  "name": "fw-allow-health-check",
  "network": "projects/PROJECT_ID/global/networks/lb-network",
  "sourceRanges": [
    "130.211.0.0/22",
    "35.191.0.0/16"
  ],
  "targetTags": [
    "load-balanced-backend"
  ],
  "allowed": [
    {
      "IPProtocol": "tcp"
    }
  ],
  "direction": "INGRESS"
}

프록시 서브넷 firewalls.insert 메서드 내에서 TCP 트래픽을 허용하도록 fw-allow-proxies 방화벽 규칙을 만듭니다.

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls
{
  "name": "fw-allow-proxies",
  "network": "projects/PROJECT_ID/global/networks/lb-network",
  "sourceRanges": [
    "10.129.0.0/23"
  ],
  "targetTags": [
    "load-balanced-backend"
  ],
  "allowed": [
    {
      "IPProtocol": "tcp",
      "ports": [
        "9376"
      ]
    }
  ],
  "direction": "INGRESS"
}

PROJECT_ID를 프로젝트 ID로 바꿉니다.

부하 분산기 구성

전달 규칙의 IP 주소에는 백엔드 서브넷을 사용합니다. 프록시 전용 서브넷을 사용하려고 하면 전달 규칙 생성에 실패합니다.

콘솔

부하 분산기 유형 선택

  1. Google Cloud 콘솔에서 부하 분산기 만들기 페이지로 이동합니다. 부하 분산기 만들기로 이동
  2. HTTP(S) 부하 분산 아래에서 구성 시작을 클릭합니다.
  3. VM 사이에서만 분산을 선택합니다. 이 설정은 부하 분산기가 내부용이라는 의미입니다.
  4. 계속을 클릭합니다.

부하 분산기 준비

  1. 부하 분산기 이름l7-ilb-gke-map를 입력합니다.
  2. 리전에 대해 서브넷을 만든 리전을 선택합니다.
  3. 네트워크lb-network를 선택합니다.

프록시 전용 서브넷 예약

프록시 전용 서브넷 예약:

  1. 서브넷 예약을 클릭합니다.
  2. 이름proxy-only-subnet을 입력합니다.
  3. IP 주소 범위10.129.0.0/23을 입력합니다.
  4. 추가를 클릭합니다.

백엔드 서비스 구성

  1. 백엔드 구성을 클릭합니다.
  2. 백엔드 서비스 만들기 또는 선택 메뉴에서 백엔드 서비스 만들기를 선택합니다.
  3. 백엔드 서비스의 이름l7-ilb-gke-backend-service로 설정합니다.
  4. 백엔드 유형네트워크 엔드포인트 그룹을 선택합니다.
  5. 백엔드 섹션새 백엔드 카드에서 다음 안내를 따릅니다.
    1. 네트워크 엔드포인트 그룹을 GKE에서 만든 NEG로 설정합니다. NEG 이름을 가져오려면 NEG 생성 확인을 참조하세요.
    2. 최대 RPS에 대해 엔드포인트당 최대 5 RPS 속도를 지정합니다. 필요한 경우 Google Cloud가 이 최댓값을 초과합니다.
    3. 완료를 클릭합니다.
  6. 상태 확인 드롭다운 목록에서 상태 확인 만들기를 선택한 후 다음 매개변수를 지정합니다.
    1. 이름: l7-ilb-gke-basic-check
    2. 프로토콜: HTTP
    3. 포트 사양: 포트 제공
    4. 저장 후 계속을 클릭합니다.
  7. 만들기를 클릭합니다.

URL 맵 구성

  1. 라우팅 규칙을 클릭합니다. l7-ilb-gke-backend-service가 일치하지 않는 모든 호스트 및 일치하지 않는 모든 경로에 대한 유일한 백엔드 서비스인지 확인합니다.

프런트엔드 구성

프런트엔드 구성을 클릭하고 다음 단계를 수행합니다.

HTTP의 경우:

  1. 프런트엔드 구성을 클릭합니다.
  2. 프런트엔드 IP 및 포트 추가를 클릭합니다.
  3. 이름l7-ilb-gke-forwarding-rule로 설정합니다.
  4. 프로토콜HTTP로 설정합니다.
  5. 서브네트워크backend-subnet으로 설정합니다.
  6. 내부 IP에서 고정 내부 IP 주소 예약을 선택합니다.
  7. 표시되는 패널에 다음 세부정보를 입력합니다.
    1. 이름: l7-ilb-gke-ip
    2. 고정 IP 주소 섹션에서 직접 선택을 선택합니다.
    3. 커스텀 IP 주소 섹션에 10.1.2.199를 입력합니다.
    4. 예약을 클릭합니다.
  8. 포트80으로 설정합니다.
  9. 완료를 클릭합니다.

HTTPS의 경우:

클라이언트와 부하 분산기 사이에 HTTPS를 사용하는 경우 프록시를 구성할 하나 이상의 SSL 인증서 리소스가 필요합니다. SSL 인증서 리소스를 만드는 방법은 SSL 인증서를 참조하세요. 내부 HTTP(S) 부하 분산기에서는 Google 관리 인증서가 지원되지 않습니다.

  1. 프런트엔드 구성을 클릭합니다.
  2. 프런트엔드 IP 및 포트 추가를 클릭합니다.
  3. 이름 필드에 l7-ilb-gke-forwarding-rule을 입력합니다.
  4. 프로토콜 필드에서 HTTPS (includes HTTP/2)를 선택합니다.
  5. 서브넷backend-subnet으로 설정합니다.
  6. 내부 IP에서 고정 내부 IP 주소 예약을 선택합니다.
  7. 표시되는 패널에 다음 세부정보를 입력합니다.
    1. 이름: l7-ilb-gke-ip
    2. 고정 IP 주소 섹션에서 직접 선택을 선택합니다.
    3. 커스텀 IP 주소 섹션에 10.1.2.199를 입력합니다.
    4. 예약을 클릭합니다.
  8. HTTPS 트래픽을 허용하도록 포트443으로 설정되어 있는지 확인합니다.
  9. 인증서 드롭다운 목록을 클릭합니다.
    1. 이미 기본 SSL 인증서로 사용할 자체 관리형 SSL 인증서 리소스가 있다면 드롭다운 메뉴에서 선택합니다.
    2. 그 이외의 경우 새 인증서 만들기를 선택합니다.
      1. l7-ilb-cert이름을 입력합니다.
      2. 해당 필드에 다음 PEM 형식의 파일을 업로드합니다.
        • 공개 키 인증서
        • 인증서 체인
        • 비공개 키
      3. 만들기를 클릭합니다.
  10. 기본 SSL 인증서 리소스 외에 인증서 리소스를 추가하려면 다음 안내를 따르세요.
    1. 인증서 추가를 클릭합니다.
    2. 인증서 목록에서 인증서를 선택하거나 새 인증서 만들기를 클릭하고 안내를 따릅니다.
  11. 완료를 클릭합니다.

구성 완료

만들기를 클릭합니다.

gcloud

  1. gcloud compute health-checks create http 명령어로 HTTP 상태 확인을 정의합니다.

    gcloud compute health-checks create http l7-ilb-gke-basic-check \
        --region=COMPUTE_REGION \
        --use-serving-port
    
  2. gcloud compute backend-services create 명령어로 백엔드 서비스를 정의합니다.

    gcloud compute backend-services create l7-ilb-gke-backend-service \
        --load-balancing-scheme=INTERNAL_MANAGED \
        --protocol=HTTP \
        --health-checks=l7-ilb-gke-basic-check \
        --health-checks-region=COMPUTE_REGION \
        --region=COMPUTE_REGION
    
  3. DEPLOYMENT_NAME 변수를 설정합니다.

    export DEPLOYMENT_NAME=NEG_NAME
    

    NEG_NAME을 NEG 이름으로 바꿉니다.

  4. gcloud compute backend-services add-backend 명령어로 백엔드 서비스에 NEG 백엔드를 추가합니다.

    gcloud compute backend-services add-backend l7-ilb-gke-backend-service \
        --network-endpoint-group=$DEPLOYMENT_NAME \
        --network-endpoint-group-zone=COMPUTE_ZONE-b \
        --region=COMPUTE_REGION \
        --balancing-mode=RATE \
        --max-rate-per-endpoint=5
    
  5. gcloud compute url-maps create 명령어로 URL 맵을 만듭니다.

    gcloud compute url-maps create l7-ilb-gke-map \
        --default-service=l7-ilb-gke-backend-service \
        --region=COMPUTE_REGION
    
  6. 대상 프록시를 만듭니다.

    HTTP의 경우:

    gcloud compute target-http-proxies create 명령어를 사용합니다.

    gcloud compute target-http-proxies create l7-ilb-gke-proxy \
        --url-map=l7-ilb-gke-map \
        --url-map-region=COMPUTE_REGION \
        --region=COMPUTE_REGION
    

    HTTPS의 경우:

    SSL 인증서 리소스를 만드는 방법은 SSL 인증서를 참조하세요. 내부 HTTP(S) 부하 분산기에서는 Google 관리 인증서가 지원되지 않습니다.

    파일 경로를 변수 이름에 할당합니다.

    export LB_CERT=PATH_TO_PEM_FORMATTED_FILE
    
    export LB_PRIVATE_KEY=PATH_TO_PEM_FORMATTED_FILE
    

    gcloud compute ssl-certificates create 명령어를 사용하여 리전별 SSL 인증서를 만듭니다.

    gcloud computessl-certificates create

    gcloud compute ssl-certificates create l7-ilb-cert \
        --certificate=$LB_CERT \
        --private-key=$LB_PRIVATE_KEY \
        --region=COMPUTE_REGION
    

    리전별 SSL 인증서를 사용하여 gcloud compute target-https-proxies create 명령어로 대상 프록시를 만듭니다.

    gcloud compute target-https-proxies create l7-ilb-gke-proxy \
        --url-map=l7-ilb-gke-map \
        --region=COMPUTE_REGION \
        --ssl-certificates=l7-ilb-cert
    
  7. 전달 규칙을 만듭니다.

    커스텀 네트워크의 경우 전달 규칙에서 서브넷을 참조해야 합니다. 이때 참조할 서브넷은 프록시 서브넷이 아니라 VM 서브넷입니다.

    HTTP의 경우:

    gcloud compute forwarding-rules create 명령어를 올바른 플래그와 함께 사용합니다.

    gcloud compute forwarding-rules create l7-ilb-gke-forwarding-rule \
        --load-balancing-scheme=INTERNAL_MANAGED \
        --network=lb-network \
        --subnet=backend-subnet \
        --address=10.1.2.199 \
        --ports=80 \
        --region=COMPUTE_REGION \
        --target-http-proxy=l7-ilb-gke-proxy \
        --target-http-proxy-region=COMPUTE_REGION
    

    HTTPS의 경우:

    gcloud compute forwarding-rules create 명령어를 올바른 플래그와 함께 사용합니다.

    gcloud compute forwarding-rules create l7-ilb-gke-forwarding-rule \
        --load-balancing-scheme=INTERNAL_MANAGED \
        --network=lb-network \
        --subnet=backend-subnet \
        --address=10.1.2.199 \
        --ports=443 \
        --region=COMPUTE_REGION \
        --target-https-proxy=l7-ilb-gke-proxy \
        --target-https-proxy-region=COMPUTE_REGION
    

API

regionHealthChecks.insert 메서드에 POST 요청을 전송하여 상태 확인을 만듭니다.

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/COMPUTE_REGION/healthChecks
{
   "name": "l7-ilb-gke-basic-check",
   "type": "HTTP",
   "httpHealthCheck": {
     "portSpecification": "USE_SERVING_PORT"
   }
}

PROJECT_ID를 프로젝트 ID로 바꿉니다.

regionBackendServices.insert 메서드에 POST 요청을 전송하여 리전 백엔드 서비스를 만듭니다.

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/COMPUTE_REGION/backendServices
{
  "name": "l7-ilb-gke-backend-service",
  "backends": [
    {
      "group": "https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/COMPUTE_ZONE/networkEndpointGroups/NEG_NAME",
      "balancingMode": "RATE",
      "maxRatePerEndpoint": 5
    }
  ],
  "healthChecks": [
    "projects/PROJECT_ID/regions/COMPUTE_REGION/healthChecks/l7-ilb-gke-basic-check"
  ],
  "loadBalancingScheme": "INTERNAL_MANAGED"
}

다음을 바꿉니다.

  • PROJECT_ID: 프로젝트 ID입니다.
  • NEG_NAME: NEG 이름입니다.

regionUrlMaps.insert 메서드에 대한 POST 요청을 전송하여 URL 맵을 만듭니다.

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/COMPUTE_REGION/urlMaps
{
  "name": "l7-ilb-gke-map",
  "defaultService": "projects/PROJECT_ID/regions/COMPUTE_REGION/backendServices/l7-ilb-gke-backend-service"
}

PROJECT_ID를 프로젝트 ID로 바꿉니다.

regionTargetHttpProxies.insert 메서드에 대한 POST 요청을 전송하여 대상 HTTP 프록시를 만듭니다.

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/COMPUTE_REGION/targetHttpProxy
{
  "name": "l7-ilb-gke-proxy",
  "urlMap": "projects/PROJECT_ID/global/urlMaps/l7-ilb-gke-map",
  "region": "COMPUTE_REGION"
}

PROJECT_ID를 프로젝트 ID로 바꿉니다.

forwardingRules.insert 메서드에 POST 요청을 전송하여 전달 규칙을 만듭니다.

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/COMPUTE_REGION/forwardingRules
{
  "name": "l7-ilb-gke-forwarding-rule",
  "IPAddress": "10.1.2.199",
  "IPProtocol": "TCP",
  "portRange": "80-80",
  "target": "projects/PROJECT_ID/regions/COMPUTE_REGION/targetHttpProxies/l7-ilb-gke-proxy",
  "loadBalancingScheme": "INTERNAL_MANAGED",
  "subnetwork": "projects/PROJECT_ID/regions/COMPUTE_REGION/subnetworks/backend-subnet",
  "network": "projects/PROJECT_ID/global/networks/lb-network",
  "networkTier": "PREMIUM",
}

PROJECT_ID를 프로젝트 ID로 바꿉니다.

테스트

영역에서 VM 인스턴스를 만들어 연결을 테스트합니다.

gcloud compute instances create l7-ilb-client \
    --image-family=debian-9 \
    --image-project=debian-cloud \
    --zone=COMPUTE_ZONE \
    --network=lb-network \
    --subnet=backend-subnet \
    --tags=l7-ilb-client,allow-ssh

클라이언트 인스턴스에 로그인하고 내부 애플리케이션 부하 분산기의 전달 규칙 IP 주소를 사용하여 백엔드의 HTTP(S) 서비스에 연결할 수 있는지와 NEG의 엔드포인트 간에 트래픽이 부하 분산되는지 확인합니다.

SSH를 사용하여 각 클라이언트 인스턴스에 연결합니다.

gcloud compute ssh l7-ilb-client \
    --zone=COMPUTE_ZONE-b

IP가 호스트 이름을 제공하는지 확인합니다.

curl 10.1.2.199

HTTPS 테스트의 경우 다음 명령어를 실행합니다.

curl -k -s 'https://test.example.com:443' --connect-to test.example.com:443:10.1.2.199:443

-k 플래그로 인해 curl이 인증서 유효성 검사를 건너뜁니다.

100개의 요청을 실행하고 부하 분산되었는지 확인합니다.

HTTP의 경우:

{
RESULTS=
for i in {1..100}
do
    RESULTS="$RESULTS:$(curl --silent 10.1.2.199)"
done
echo "***"
echo "*** Results of load-balancing to 10.1.2.199: "
echo "***"
echo "$RESULTS" | tr ':' '\n' | grep -Ev "^$" | sort | uniq -c
echo
}

HTTPS의 경우:

{
RESULTS=
for i in {1..100}
do
    RESULTS="$RESULTS:$(curl -k -s 'https://test.example.com:443' --connect-to test.example.com:443:10.1.2.199:443
)"
done
echo "***"
echo "*** Results of load-balancing to 10.1.2.199: "
echo "***"
echo "$RESULTS" | tr ':' '\n' | grep -Ev "^$" | sort | uniq -c
echo
}

이기종 서비스 구현하기(VM 및 컨테이너)

부하 분산기는 혼합 Kubernetes 및 비 Kubernetes 워크로드의 프런트엔드일 수 있습니다. VM에서 컨테이너로의 마이그레이션 또는 공유 부하 분산기의 혜택을 얻는 영구 아키텍처의 일부일 수 있습니다. 이를 위해서는 독립형 NEG를 포함한 다양한 종류의 백엔드를 대상으로 하는 부하 분산기를 만들면 됩니다.

동일한 백엔드 서비스의 VM 및 컨테이너

이 예시는 워크로드를 실행하는 기존 VM을 가리키는 NEG를 만드는 방법과 이 NEG를 기존 backendService의 다른 백엔드로 추가하는 방법을 보여줍니다. 이렇게 하면 단일 부하 분산기가 VM과 GKE 컨테이너 사이의 균형을 조정합니다.

이 예시에서는 외부 HTTP 부하 분산기를 사용하는 이전 예시를 확장합니다.

모든 엔드포인트는 동일한 backendService로 그룹화되므로 VM 및 컨테이너 엔드포인트는 동일한 서비스로 간주됩니다. 즉, 호스트 또는 경로 일치는 URL 맵 규칙에 따라 모든 백엔드를 동일하게 취급합니다.

설명된 아키텍처를 보여주는 다이어그램입니다. 앞에서 만든 부하 분산기는 2개의 NEG를 가리킵니다(앞에서 만든 컨테이너의 NEG, VM의 IP 주소를 포함하는 새로운 NEG).

NEG를 백엔드 서비스의 백엔드로 사용하면 해당 백엔드 서비스의 다른 모든 백엔드도 NEG여야 합니다. 동일한 백엔드 서비스에서 인스턴스 그룹과 NEG를 백엔드로 사용할 수 없습니다. 또한 컨테이너와 VM은 동일한 NEG 내에서 엔드포인트로 존재할 수 없으므로 항상 별도의 NEG로 구성해야 합니다.

  1. 다음 명령어를 사용하여 Compute Engine에 VM을 배포합니다.

    gcloud compute instances create vm1 \
        --zone=COMPUTE_ZONE \
        --network=NETWORK \
        --subnet=SUBNET \
        --image-project=cos-cloud \
        --image-family=cos-stable --tags=vm-neg-tag
    

    다음을 바꿉니다.

    • COMPUTE_ZONE: 영역 이름입니다.
    • NETWORK: 네트워크의 이름입니다.
    • SUBNET: 네트워크와 연결된 서브넷의 이름입니다.
  2. VM에 애플리케이션을 배포합니다.

    gcloud compute ssh vm1 \
        --zone=COMPUTE_ZONE \
        --command="docker run -d --rm --network=host registry.k8s.io/serve_hostname:v1.4 && sudo iptables -P INPUT ACCEPT"
    

    이 명령어는 앞의 예시에서 사용한 것과 동일한 예시 애플리케이션을 VM에 배포합니다. 간편함을 위해 애플리케이션은 Docker 컨테이너로 실행되지만 이는 필수 사항은 아닙니다. iptables 명령어는 실행 중인 컨테이너에 대한 방화벽 액세스를 허용하기 위해 필요합니다.

  3. 애플리케이션이 포트 9376에서 제공되고 vm1에서 실행 중임을 보고하는지 확인합니다.

    gcloud compute ssh vm1 \
        --zone=COMPUTE_ZONE \
        --command="curl -s localhost:9376"
    

    서버가 vm1로 응답합니다.

  4. VM 엔드포인트에서 사용할 NEG를 만듭니다. 컨테이너와 VM은 모두 NEG 엔드포인트일 수 있지만 단일 NEG가 VM 엔드포인트와 컨테이너 엔드포인트를 모두 가질 수는 없습니다.

    gcloud compute network-endpoint-groups create vm-neg \
        --subnet=SUBNET \
        --zone=COMPUTE_ZONE
    
  5. VM 엔드포인트를 NEG에 연결합니다.

    gcloud compute network-endpoint-groups update vm-neg \
        --zone=COMPUTE_ZONE \
        --add-endpoint="instance=vm1,ip=VM_PRIMARY_IP,port=9376"
    

    VM_PRIMARY_IP를 VM의 기본 IP 주소로 바꿉니다.

  6. NEG에 VM 엔드포인트가 있는지 확인합니다.

    gcloud compute network-endpoint-groups list-network-endpoints vm-neg \
        --zone COMPUTE_ZONE
    
  7. 컨테이너 백엔드를 추가할 때 사용한 것과 동일한 명령어를 사용하여 NEG를 백엔드 서비스에 연결합니다.

    gcloud compute backend-services add-backend my-bes
        --global \
        --network-endpoint-group vm-neg \
        --network-endpoint-group-zone COMPUTE_ZONE \
        --balancing-mode RATE --max-rate-per-endpoint 10
    
  8. 방화벽을 열어 VM의 상태 확인을 허용합니다.

    gcloud compute firewall-rules create fw-allow-health-check-to-vm1 \
        --network=NETWORK \
        --action=allow \
        --direction=ingress \
        --target-tags=vm-neg-tag \
        --source-ranges=130.211.0.0/22,35.191.0.0/16 \
        --rules=tcp:9376
    
  9. 테스트 트래픽을 전송하여 부하 분산기가 새 vm1 백엔드와 기존 컨테이너 백엔드로 모두 트래픽을 전달하는지 확인합니다.

    for i in `seq 1 100`; do curl ${VIP};echo; done
    

    컨테이너(neg-demo-app)와 VM(vm1) 엔드포인트의 응답이 모두 있어야 합니다.

다양한 백엔드 서비스를 위한 VM 및 컨테이너

이 예시에서는 워크로드를 실행하는 기존 VM을 가리키는 NEG를 만드는 방법과 이 NEG를 새 backendService에 백엔드로 추가하는 방법을 보여줍니다. 이는 컨테이너와 VM이 서로 다른 서비스이지만 동일한 IP 주소 또는 도메인 이름을 공유하는 경우와 같이 동일한 L7 부하 분산기를 공유해야 하는 경우에 유용합니다.

이 예시에서는 컨테이너 백엔드와 동일한 백엔드 서비스에 VM 백엔드가 있는 이전 예시를 확장합니다. 이 예시에서는 해당 VM을 재사용합니다.

컨테이너와 VM 엔드포인트는 별도의 백엔드 서비스로 그룹화되므로 다른 서비스로 간주됩니다. 즉, URL 맵은 백엔드와 일치하고 호스트 이름을 기준으로 VM 또는 컨테이너로 트래픽을 전달합니다.

다음 다이어그램은 단일 가상 IP 주소가 두 개의 호스트 이름에 해당하고, 다시 이 호스트 이름이 컨테이너 기반 백엔드 서비스와 VM 기반 백엔드 서비스에 해당하는 방법을 보여줍니다.

다음 다이어그램은 이전 섹션에서 설명된 아키텍처를 보여줍니다.

아키텍처에는 컨테이너로 구현된 서비스와 VM으로 구현된 서비스를 위한 2개의 NEG가 있습니다. 각 NEG에는 백엔드 서비스 객체가 있습니다. URL Map 객체는 요청된 URL을 기반으로 올바른 백엔드 서비스로 트래픽을 전달합니다.

  1. VM의 새 백엔드 서비스를 만듭니다.

    gcloud compute backend-services create my-vm-bes \
       --protocol HTTP \
       --health-checks http-basic-check \
       --global
    
  2. vm-neg VM의 NEG를 백엔드 서비스에 연결합니다.

    gcloud compute backend-services add-backend my-vm-bes \
        --global \
        --network-endpoint-group vm-neg \
        --network-endpoint-group-zone COMPUTE_ZONE \
        --balancing-mode RATE --max-rate-per-endpoint 10
    
  3. 호스트 규칙을 URL 맵에 추가하여 container.example.com 호스트에 대한 요청을 컨테이너 백엔드 서비스로 전달합니다.

    gcloud compute url-maps add-path-matcher web-map \
        --path-matcher-name=container-path --default-service=my-bes \
        --new-hosts=container.example.com --global
    
  4. URL 맵에 다른 호스트 규칙을 추가하여 vm.example.com 호스트에 대한 요청을 VM 백엔드 서비스로 전달합니다.

    gcloud compute url-maps add-path-matcher web-map \
        --path-matcher-name=vm-path --default-service=my-vm-bes \
        --new-hosts=vm.example.com --global
    
  5. 부하 분산기가 요청된 경로를 기반으로 VM 백엔드로 트래픽을 전송하는지 확인합니다.

    curl -H "HOST:vm.example.com" VIRTUAL_IP
    

    VIRTUAL_IP를 가상 IP 주소로 바꿉니다.

독립형 NEG의 제한사항

  • 주석 유효성 검사 오류는 Kubernetes 이벤트를 통해 사용자에게 노출됩니다.
  • NEG의 제한 사항은 독립형 NEG에도 적용됩니다.

가격 책정

부하 분산기의 가격 책정에 대한 자세한 내용은 가격 책정 페이지의 부하 분산 섹션을 참조하세요. NEG에는 추가 요금이 부과되지 않습니다.

문제 해결

이 섹션에서는 독립형 NEG에서 발생할 수 있는 일반적인 문제의 문제 해결 단계를 제공합니다.

구성된 독립형 NEG가 없음

증상: 생성된 NEG가 없습니다.

잠재적인 해결 방법:

  • 서비스와 관련된 이벤트를 확인하고 오류 메시지를 찾습니다.
  • 독립형 NEG 주석이 올바른 형식의 JSON이며 노출된 포트가 서비스 사양의 기존 포트와 일치하는지 확인합니다.
  • NEG 상태 주석을 확인하고 예상된 서비스 포트에 해당 NEG가 있는지 확인합니다.
  • gcloud compute network-endpoint-groups list 명령어로 NEG가 예상 영역에 생성되었는지 확인합니다.
  • GKE 버전 1.18 이상을 사용하는 경우 서비스의 svcneg 리소스가 있는지 확인합니다. 리소스가 있으면 Initialized 조건에 오류 정보가 있는지 확인합니다.
  • 커스텀 NEG 이름을 사용하는 경우 리전의 각 NEG 이름이 고유한지 확인합니다.

트래픽이 엔드포인트에 도달하지 않음

증상: 502 오류 또는 거부된 연결

잠재적인 해결 방법:

  • 서비스가 구성된 후 일반적으로 상태 확인에 응답하면 NEG에 연결한 후 새 엔드포인트에 연결할 수 있습니다.
  • 이 시간 이후에도 트래픽이 엔드포인트에 도달하지 못해 HTTP(S)에 대한 502 오류 코드가 발생하거나 TCP/SSL 부하 분산기에 대한 연결이 거부되는 경우 다음을 확인하세요.
    • 방화벽 규칙이 130.211.0.0/22 범위와 35.191.0.0/16 범위에서 엔드포인트로 들어오는 TCP 트래픽을 허용하는지 확인합니다.
    • Google Cloud CLI를 사용하거나 backendService에서 getHealth API를 호출하거나 showHealth 매개변수가 SHOW로 설정된 상태로 NEG에서 listEndpoints API를 호출하여 엔드포인트가 정상인지 확인합니다.

출시 중단

증상: 업데이트된 배포 출시가 중단되고 최신 복제본 수가 선택한 복제본 수와 일치하지 않습니다.

잠재적인 해결 방법:

배포 상태 확인이 실패합니다. 컨테이너 이미지가 손상되었거나 상태 확인이 잘못 구성되었을 수 있습니다. 포드의 순차적 교체는 새로 시작된 포드가 포드 준비 게이트를 통과할 때까지 대기합니다. 이는 포드가 부하 분산기 상태 확인에 응답하는 경우에만 발생합니다. 포드가 응답하지 않거나 상태 확인이 잘못 구성된 경우 준비 게이트 조건을 충족할 수 없으며 출시를 계속할 수 없습니다.

  • kubectl 1.13 이상을 사용하는 경우 다음 명령어를 사용하여 포드의 준비 게이트 상태를 확인할 수 있습니다.

    kubectl get my-Pod -o wide
    

    READINESS GATES 열을 확인합니다.

    kubectl 1.12 이하에는 이 열이 존재하지 않습니다. READY 상태로 표시된 포드에서는 준비 게이트가 실패했을 수 있습니다. 이를 확인하려면 다음 명령어를 사용합니다.

    kubectl get my-pod -o yaml
    

    준비 게이트와 해당 상태가 출력에 나열됩니다.

  • 배포 포드 사양의 컨테이너 이미지가 제대로 작동하고 있고 상태 확인에 응답할 수 있는지 확인합니다.

  • 상태 확인이 올바르게 구성되어 있는지 확인합니다.

NEG가 가비지로 수집되지 않음

증상: 삭제되었어야 하는 NEG가 여전히 존재합니다.

잠재적인 해결 방법:

  • 백엔드 서비스에서 NEG를 참조하는 경우 NEG는 가비지로 수집되지 않습니다. 자세한 내용은 누출된 NEG 방지을 참조하세요.
  • 1.18 이상을 사용하는 경우 서비스 NEG 절차를 사용하여 ServiceNetworkEndpointGroup 리소스의 이벤트를 확인할 수 있습니다.
  • 서비스에서 NEG가 아직 필요한지 확인합니다. NEG에 해당하는 서비스의 svcneg 리소스를 확인하고 서비스 주석이 있는지 확인합니다.

NEG가 서비스와 동기화되지 않음

증상: NEG에 예상되는 (포드 IP) 엔드포인트가 없거나 NEG가 동기화되지 않았거나 Failed to sync NEG_NAME (will not retry): neg name NEG_NAME is already in use, found a custom named neg with an empty description 오류가 발생했습니다.

잠재적인 해결 방법:

GKE 1.18 이상을 사용하는 경우 자세한 내용은 svcneg 리소스를 참조하세요.

  • status.lastSyncTime 값을 확인하여 NEG가 최근에 동기화되었는지 확인합니다.
  • 가장 최근의 동기화에 발생한 오류가 있는지 Synced 조건을 확인합니다.

GKE 1.19.9 이상을 사용하는 경우 이름 및 영역이 GKE NEG 컨트롤러가 만들어야 하는 NEG의 이름 및 영역과 일치하는 NEG가 있는지 확인합니다. 예를 들어 NEG 컨트롤러가 사용해야 하는 이름의 NEG가 gcloud CLI 또는 Google Cloud 콘솔을 사용하여 클러스터 영역(또는 클러스터 영역 중 하나)에 생성되었을 수 있습니다. 이 경우 NEG 컨트롤러가 엔드포인트를 동기화하려면 먼저 기존 NEG를 삭제해야 합니다. 독립형 NEG 만들기 및 멤버십은 NEG 컨트롤러에서 관리되도록 설계되었습니다.

다음 단계