VPC 네트워크에서 내부 부하 분산기 만들기

이 페이지에서는 VPC 네트워크 간의 Google Kubernetes Engine(GKE)에서 내부 패스 스루 네트워크 부하 분산기를 만드는 방법을 설명합니다.

이 페이지를 읽기 전 다음 내용을 숙지해야 합니다.

시작하기 전에

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

  • Google Kubernetes Engine API를 사용 설정합니다.
  • Google Kubernetes Engine API 사용 설정
  • 이 태스크에 Google Cloud CLI를 사용하려면 gcloud CLI를 설치한 후 초기화합니다. 이전에 gcloud CLI를 설치했으면 gcloud components update 명령어를 실행하여 최신 버전을 가져옵니다. 이전 gcloud CLI 버전에서는 이 문서의 명령어를 실행하지 못할 수 있습니다.

Private Service Connect로 내부 부하 분산기 만들기

서비스 프로듀서는 Private Service Connect를 사용해서 서비스 연결을 사용하여 서비스를 다른 VPC 네트워크에 있는 서비스 소비자에게 제공할 수 있습니다. ServiceAttachment 커스텀 리소스를 사용하여 서비스 연결을 만들고, 관리, 삭제할 수 있습니다. GKE Private Service Connect 컨트롤러는 ServiceAttachment 리소스를 모니터링하고 Compute Engine에서 해당 ServiceAttachment 리소스를 자동으로 만들거나 업데이트하거나 삭제합니다.

요구사항 및 제한사항

  • Private Service Connect 제한사항이 적용됩니다.
  • GKE 버전 1.21.4-gke.300 이상에서 서비스 연결을 만들 수 있습니다.
  • 클러스터에 HttpLoadBalancing 부가기능이 사용 설정되어 있어야 합니다. 새 GKE 클러스터에는 기본적으로 HttpLoadBalancing 부가기능이 사용 설정되어 있습니다.
  • 여러 서비스 연결 구성에서는 동일한 서브넷을 사용할 수 없습니다.
  • 내부 패스 스루 네트워크 부하 분산기를 사용하는 GKE 서비스를 만들어야 합니다.
  • GKE 서비스는 단일 프로토콜만 사용해야 합니다. 혼합 프로토콜 GKE 서비스는 지원되지 않습니다.
  • 1.22.4-gke.100 이전 버전의 GKE에 다른 프로젝트(공유 VPC)의 서브넷을 지정할 수 없습니다. 공유 VPC의 경우 공유 VPC 요구사항이 모두 충족되는지 확인합니다.
  • 서비스 연결을 만든 후에는 내부 부하 분산기를 업데이트할 수 없습니다. 부하 분산기 구성을 변경하려면 서비스 연결을 삭제하고 다시 만들어야 합니다.

서비스 및 NAT 서브넷의 IP 버전 호환성

ServiceAttachment 리소스를 만들면 GKE Private Service Connect 컨트롤러가 프로듀서 전달 규칙과 연결된 단일 Compute Engine 서비스 연결을 만듭니다. 프로듀서 전달 규칙은 IPv4 주소 또는 IPv6 주소를 사용합니다. 다음 표에서는 컨트롤러가 참조된 Kubernetes 서비스의 IP 제품군 구성(spec.ipFamilies 필드)과 spec.natSubnets 필드에 지정된 모든 서브넷의 스택 유형을 기반으로 전달 규칙을 선택하는 방법을 보여줍니다.

Kubernetes 서비스(전달 규칙) natSubnets 필드의 서브넷 스택 유형 Compute Engine 서비스 연결 전달 규칙 참고
단일 스택 IPv4 IPV4_ONLY, IPV4_IPV6 또는 둘 다 IPv4 주소 지원됨
IPV6_ONLY 서브넷 포함 없음(오류) 구성 오류입니다. 모든 NAT 서브넷은 IPv4 주소를 지원해야 합니다.
이중 스택(IPv4 및 IPv6 주소) IPV4_ONLY, IPV4_IPV6 또는 둘 다(IPV6_ONLY 서브넷 없음) IPv4 주소 지원됨 IPv4 전달 규칙을 사용합니다. IPv4 서비스 연결은 IPv4 및 IPv6 소비자 엔드포인트 모두에서 연결을 수락할 수 있습니다.
IPV6_ONLY 또는 IPV6_ONLY 및 IPV4_IPV6의 조합(IPV4_ONLY 서브넷 없음) IPv6 주소 지원됨 IPV6_ONLY 서브넷이 있으므로 IPv6 전달 규칙을 사용합니다. IPv6 서비스 연결은 IPv6 소비자 엔드포인트의 연결만 허용합니다.
IPV4_ONLY 및 IPV6_ONLY 서브넷을 모두 포함합니다. 없음(오류) 구성 오류입니다. 모든 NAT 서브넷은 공통 IP 버전을 공유해야 합니다.
단일 스택 IPv6 IPV6_ONLY, IPV4_IPV6 또는 둘 다 IPv6 주소 지원됨
IPV4_ONLY 서브넷 포함 없음(오류) 구성 오류입니다. 모든 NAT 서브넷은 IPv6 주소를 지원해야 합니다.

소비자 엔드포인트가 IPv4 및 IPv6 서비스 연결에 연결되는 방법에 대한 자세한 내용은 IP 버전 변환을 참조하세요.

ServiceAttachment 만들기

  1. 서브넷을 만듭니다.

    각 ServiceAttachment에 대해 새 서브넷을 만들어야 합니다.

    gcloud compute networks subnets create SUBNET_NAME \
        --project PROJECT_ID \
        --network NETWORK_NAME \
        --region REGION \
        --range SUBNET_RANGE \
        --purpose PRIVATE_SERVICE_CONNECT
    

    다음을 바꿉니다.

    • SUBNET_NAME: 새 서브넷의 이름입니다. GKE 버전 1.22.4-gke.100 이상에서는 이 필드에 정규화된 리소스 URL을 사용하여 다른 프로젝트의 서브넷을 지정할 수 있습니다. gcloud compute networks subnets describe 명령어를 사용하여 정규화된 리소스 URL을 가져올 수 있습니다.
    • PROJECT_ID: Google Cloud프로젝트의 ID
    • NETWORK_NAME: 서브넷의 VPC 네트워크의 이름
    • REGION: 새 서브넷의 리전. 만드는 서비스와 동일한 리전을 사용해야 합니다.
    • SUBNET_RANGE: 서브넷에 사용할 IPv4 주소 범위.

    이중 스택 또는 IPv6 전용 Private Service Connect 서브넷을 만들려면 --stack-type=IPV4_IPV6 및 --ipv6-access-type=INTERNAL 플래그 또는 --stack-type=IPV6_ONLY 및 --ipv6-access-type=INTERNAL 플래그를 포함합니다(IPV6_ONLY 스택 유형을 사용할 때는 --range 플래그 생략). 서비스 및 NAT 서브넷의 IP 버전 호환성에 설명된 대로 서브넷 스택 유형이 서비스의 IP 계열과 호환되는지 확인합니다.

  2. 워크로드를 배포합니다.

    다음 매니페스트는 샘플 웹 애플리케이션 컨테이너 이미지를 실행하는 배포를 설명합니다. 매니페스트를 my-deployment.yaml로 저장합니다.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: psc-ilb
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: psc-ilb
      template:
        metadata:
          labels:
            app: psc-ilb
        spec:
          containers:
          - name: whereami
            image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1
            ports:
              - name: http
                containerPort: 8080
            readinessProbe:
              httpGet:
                path: /healthz
                port: 8080
                scheme: HTTP
              initialDelaySeconds: 5
              timeoutSeconds: 1
    
  3. 매니페스트를 클러스터에 적용합니다.

    kubectl apply -f my-deployment.yaml
    
  4. 서비스를 생성합니다. 다음 매니페스트는 TCP 포트 8080에 내부 패스 스루 네트워크 부하 분산기를 만드는 서비스를 설명합니다. 매니페스트를 my-service.yaml로 저장합니다.

     apiVersion: v1
     kind: Service
     metadata:
       name: SERVICE_NAME
       annotations:
         networking.gke.io/load-balancer-type: "Internal"
     spec:
       type: LoadBalancer
       selector:
         app: psc-ilb
       ports:
       - port: 80
         targetPort: 8080
         protocol: TCP
    

    다음을 바꿉니다.

    • SERVICE_NAME: 새 서비스의 이름입니다.
  5. 매니페스트를 클러스터에 적용합니다.

    kubectl apply -f my-service.yaml
    
  6. ServiceAttachment를 만듭니다.

    다음 매니페스트는 만든 서비스를 서비스 소비자에게 노출하는 ServiceAttachment를 설명합니다. 매니페스트를 my-psc.yaml로 저장합니다.

    apiVersion: networking.gke.io/v1
    kind: ServiceAttachment
    metadata:
     name: SERVICE_ATTACHMENT_NAME
     namespace: default
    spec:
     connectionPreference: ACCEPT_AUTOMATIC
     natSubnets:
     - SUBNET_NAME
     proxyProtocol: false
     reconcileConnections: false  # set to true to enable connection reconciliation
     resourceRef:
       kind: Service
       name: SERVICE_NAME
    

    다음을 바꿉니다.

    • SERVICE_ATTACHMENT_NAME: 새 서비스 연결의 이름입니다.
    • SUBNET_NAME: 새 서브넷의 이름입니다. GKE 버전 1.22.4-gke.100 이상에서는 이 필드에 정규화된 리소스 URL을 사용하여 다른 프로젝트의 서브넷을 지정할 수 있습니다. gcloud compute networks subnets describe 명령어를 사용하여 정규화된 리소스 URL을 가져올 수 있습니다. 공유 VPC 구성의 경우 projects/HOST_PROJECT_ID/regions/COMPUTE_REGION/subnetworks/SUBNET_NAME 형식을 사용합니다.

    매니페스트 필드에 대한 자세한 내용은 서비스 연결 필드를 참조하세요.

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

    kubectl apply -f my-psc.yaml
    
  8. Private Service Connect 컨트롤러가 서비스 연결을 만들었는지 확인합니다.

    gcloud compute service-attachments list
    

    출력에 자동 생성된 이름의 서비스 연결이 표시됩니다.

    NAME        REGION       PRODUCER_FORWARDING_RULE          CONNECTION_PREFERENCE
    k8s1-sa-... REGION_NAME  a3fea439c870148bdba5e59c9ea9451a  ACCEPT_AUTOMATIC
    

ServiceAttachment 보기

다음 명령어를 사용하여 ServiceAttachment의 세부정보를 확인할 수 있습니다.

kubectl describe serviceattachment SERVICE_ATTACHMENT_NAME

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

Name:        <sa-name>
Namespace:    default
Labels:       <none>
Annotations:  <none>
API Version:  networking.gke.io/v1beta1
Kind:         ServiceAttachment
Metadata:
  ...
Status:
  Forwarding Rule URL:      https://www.googleapis.com/compute/beta/projects/<project>/regions/<region>/forwardingRules/<fr-name>
  Last Modified Timestamp:  2021-07-08T01:32:39Z
  Service Attachment URL:   https://www.googleapis.com/compute/beta/projects/<projects>/regions/<region>/serviceAttachments/<gce-service-attachment-name>
Events:                     <none>

ServiceAttachment 사용

다른 프로젝트에서 서비스를 사용하려면 다음 단계를 수행합니다.

  1. ServiceAttachment의 URL을 가져옵니다.

    kubectl get serviceattachment SERVICE_ATTACHMENT_NAME -o=jsonpath="{.status.serviceAttachmentURL}"
    

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

      serviceAttachmentURL: https://www.googleapis.com/compute/alpha/projects/<project>/region/<region>/serviceAttachments/k8s1-...my-sa
    
  2. ServiceAttachment의 URL을 사용하여 Private Service Connect 엔드포인트를 만듭니다.

  3. 소비자 프로젝트의 VM에서 curl 명령어를 사용하여 제작자 프로젝트에 배포한 서비스에 연결할 수 있는지 확인합니다.

    curl PSC_IP_ADDRESS
    

    PSC_IP_ADDRESS를 소비자 프로젝트에 있는 전달 규칙의 IP 주소로 바꿉니다.

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

    {
      "cluster_name":"cluster",
      "host_header":"10.128.15.200",
      "node_name":"gke-psc-default-pool-be9b6e0e-dvxg.c.gke_project.internal",
      "pod_name":"foo-7bf648dcfd-l5jf8",
      "pod_name_emoji":"👚",
      "project_id":"gke_project",
      "timestamp":"2021-06-29T21:32:03",
      "zone":"ZONE_NAME"
    }
    

ServiceAttachment 업데이트

다음 단계에 따라 ServiceAttachment를 업데이트할 수 있습니다.

  1. my-psc.yaml에서 ServiceAttachment 매니페스트를 수정합니다.

    apiVersion: networking.gke.io/v1
    kind: ServiceAttachment
    metadata:
      name: my-sa
      namespace: default
    spec:
      connectionPreference: ACCEPT_AUTOMATIC
      natSubnets:
      - my-nat-subnet
      proxyProtocol: false
      resourceRef:
        kind: Service
        name: ilb-service
    
  2. 매니페스트를 클러스터에 적용합니다.

    kubectl apply -f my-psc.yaml
    

ServiceAttachment 삭제

서비스 연결에 연결된 내부 패스 스루 네트워크 부하 분산기를 삭제할 수 없습니다. 서비스 연결 및 GKE 서비스를 개별적으로 삭제해야 합니다.

  1. 서비스 연결을 삭제합니다.

    kubectl delete serviceattachment SERVICE_ATTACHMENT_NAME --wait=false
    

    이 명령어는 서비스 연결을 삭제하도록 표시하지만 리소스가 계속 존재합니다. 또한 --wait 플래그를 생략하여 삭제가 완료될 때까지 기다릴 수 있습니다.

  2. 서비스를 삭제합니다.

    kubectl delete svc SERVICE_NAME
    
  3. 서브넷을 삭제:합니다.

    gcloud compute networks subnets delete SUBNET_NAME
    

필드 ServiceAttachment개

ServiceAttachment에는 다음 필드가 포함됩니다.

  • connectionPreference: 고객의 서비스 연결 방법을 결정하는 연결 환경설정입니다. ACCEPT_AUTOMATIC을 사용하여 자동 프로젝트 승인을 사용하거나 ACCEPT_MANUAL을 사용하여 명시적인 프로젝트 승인을 사용할 수 있습니다. 자세한 내용은 Private Service Connect를 사용하여 서비스 게시를 참조하세요.
  • natSubnets: 서비스 연결에 사용할 서브네트워크 리소스 이름의 목록입니다.
  • proxyProtocol: true로 설정된 경우 소비자 소스 IP 및 Private Service Connect 연결 ID를 요청에서 사용할 수 있습니다. 이 필드는 선택사항이며 제공되지 않은 경우 false가 기본값입니다.
  • reconcileConnections(프리뷰): true로 설정하면 서비스 소비자 허용 또는 거부 목록에 대한 변경사항이 승인되지 않은 기존 연결을 자동으로 종료합니다. false로 설정하면 변경사항이 새 연결에만 영향을 미칩니다. 이 필드는 선택사항이며 기본값은 false입니다. 이 필드는 GKE 버전 1.36.0-gke.2459000 이상에서 지원됩니다.
  • consumerAllowList: ServiceAttachment에 연결하기 위해 허용된 소비자 프로젝트의 목록입니다. 이 필드는 connectionPreference가 ACCEPT_MANUAL일 때만 사용할 수 있습니다. 이 필드에 대한 자세한 내용은 Private Service Connect를 사용하여 서비스 게시를 참조하세요.
    • project: 소비자 프로젝트의 프로젝트 ID 또는 번호입니다.
    • connectionLimit: 소비자 프로젝트의 연결 한도입니다. 이 필드는 선택사항입니다.
    • forceSendFields: 전송하여 API 요청에 포함할 필드 이름입니다. 이 필드는 선택사항입니다.
    • nullFields: 널 값으로 API 요청에 포함할 필드 이름입니다. 이 필드는 선택사항입니다.
  • consumerRejectList: ServiceAttachment에 연결이 허용되지 않은 소비자 프로젝트 ID 또는 숫자 목록입니다. 이 필드는 connectionPreference가 ACCEPT_MANUAL일 때만 사용할 수 있습니다. 이 필드에 대한 자세한 내용은 Private Service Connect를 사용하여 서비스 게시를 참조하세요.
  • resourceRef: Kubernetes 리소스에 대한 참조입니다.

    • kind: Kubernetes 리소스의 유형입니다. Service를 사용해야 합니다.
    • name: 내부 패스 스루 네트워크 부하 분산기와 동일한 네임스페이스에 있어야 하는 Kubernetes 리소스의 이름입니다.

문제 해결

다음 명령어를 사용하여 오류 메시지를 확인할 수 있습니다.

kubectl get events -n NAMESPACE

NAMESPACE를 내부 패스 스루 네트워크 부하 분산기의 네임스페이스로 바꿉니다.

내부 패스 스루 네트워크 부하 분산기 삭제 오류

서비스 연결에서 사용 중인 내부 패스 스루 네트워크 부하 분산기를 삭제하려고 하면 다음과 유사한 오류 메시지가 표시됩니다. 내부 패스 스루 네트워크 부하 분산기를 삭제하려면 먼저 ServiceAttachment를 삭제해야 합니다.

Error syncing load balancer: failed to ensure load balancer: googleapi:
Error 400: The forwarding_rule resource '<fwd-rule-URL>' is already being used
by '<svc-attachment-URL>', resourceInUseByAnotherResource.

전역 액세스 사용 설정 오류

Private Service Connect 서비스 연결을 사용하는 내부 패스 스루 네트워크 부하 분산기에 전역 액세스를 사용 설정하면 오류가 발생할 수 있습니다.

증상:

GKE 서비스 매니페스트를 업데이트하고 networking.gke.io/internal-load-balancer-allow-global-access: "true" 주석을 설정하여 전역 액세스를 사용 설정하면 매니페스트를 적용할 때 업데이트가 실패합니다. kubectl get events 명령어를 실행하면 다음 오류 메시지가 표시됩니다.

Error syncing load balancer: failed to ensure load balancer: googleapi: Error 400: The forwarding_rule resource '...' is already being used by '...', resourceInUseByAnotherResource

이유:

이 오류는 GKE 컨트롤 플레인에서 전역 액세스를 사용 설정하기 위해 부하 분산기의 전달 규칙을 다시 생성하려고 할 때 발생합니다. 하지만 전달 규칙이 ServiceAttachment에서 사용 중이므로 규칙을 삭제하고 다시 만들 수 없어 오류가 발생합니다.

해결 방법:

다운타임을 최소화하면서 부하 분산기에서 전역 액세스를 사용 설정하려면 GKE 서비스 구성을 업데이트하고 전달 규칙을 수동으로 업데이트해야 합니다.

  1. GKE 서비스 매니페스트 업데이트: networking.gke.io/internal-load-balancer-allow-global-access: "true" 주석을 포함하도록 GKE 서비스 매니페스트를 업데이트합니다.

  2. 전달 규칙에서 전역 액세스를 수동으로 사용 설정: 전역 액세스 사용 설정의 단계에 따라Google Cloud 콘솔, Google Cloud CLI 또는 Compute Engine API를 사용하여 부하 분산기의 전달 규칙을 업데이트합니다.

동기화되지 않은 ReconcileConnections 필드

Compute Engine ServiceAttachment 리소스에서 ReconcileConnections 필드를 수동으로 사용 설정했지만 Kubernetes 매니페스트에서 필드를 생략한 경우 필드는 기본적으로 false로 설정됩니다. 그러면 GKE 컨트롤러가 필드 값을 덮어쓰지 않습니다.

증상:

Kubernetes ServiceAttachment 리소스에 networking.gke.io/unsynced-field: ReconcileConnections 주석이 있습니다. kubectl get events 명령어를 실행하면 다음과 유사한 경고 이벤트가 표시됩니다.

Field "ReconcileConnections" is not specified in the ServiceAttachment CR but has a value in GCE. The controller will not overwrite this field until it is explicitly set in the CR.

해결 방법:

이 경고를 해결하고 값을 동기화하려면 다음 작업 중 하나를 수행합니다.

  • GKE ServiceAttachment 리소스 업데이트: reconcileConnections: true(또는 사용 중지하려는 경우 false)를 포함하도록 GKE ServiceAttachment 매니페스트를 업데이트합니다.
  • Compute Engine ServiceAttachment 리소스 업데이트: reconcileConnections 필드를 false로 수동 설정합니다.

다음 단계