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


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

시작하기 전에

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

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

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

서비스 제작자는 Private Service Connect를 사용해서 서비스 연결을 사용하여 서비스를 다른 VPC 네트워크에 있는 서비스 소비자에게 제공할 수 있습니다. ServiceAttachment 커스텀 리소스를 사용하여 서비스 연결을 만들고, 관리, 삭제할 수 있습니다.

요구사항 및 제한사항

  • Private Service Connect 제한사항이 적용됩니다.
  • GKE 버전 1.21.4-gke.300 이상에서 서비스 연결을 만들 수 있습니다.
  • 여러 서비스 연결 구성에서는 동일한 서브넷을 사용할 수 없습니다.
  • 내부 패스 스루 네트워크 부하 분산기를 사용하는 GKE 서비스를 만들어야 합니다.
  • 1.22.4-gke.100 이전 버전의 GKE에 다른 프로젝트(공유 VPC)의 서브넷을 지정할 수 없습니다. 공유 VPC의 경우 공유 VPC 요구사항이 모두 충족되는지 확인합니다.

ServiceAttachment 만들기

  1. 서브넷을 만듭니다.

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

    gcloud beta 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: 서브넷에 사용할 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.2.19
            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
     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 beta 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

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

 kubectl describe serviceattachment foo-sa
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가 기본값입니다.
  • consumerAllowList: ServiceAttachment에 연결하기 위해 허용된 소비자 프로젝트의 목록입니다. 이 필드는 connectionPreferenceACCEPT_MANUAL일 때만 사용할 수 있습니다. 이 필드에 대한 자세한 내용은 Private Service Connect를 사용하여 서비스 게시를 참조하세요.
    • project: 소비자 프로젝트의 프로젝트 ID 또는 번호입니다.
    • connectionLimit: 소비자 프로젝트의 연결 한도입니다. 이 필드는 선택사항입니다.
    • forceSendFields: 전송하여 API 요청에 포함할 필드 이름입니다. 이 필드는 선택사항입니다.
    • nullFields: 널 값으로 API 요청에 포함할 필드 이름입니다. 이 필드는 선택사항입니다.
  • consumerRejectList: ServiceAttachment에 연결이 허용되지 않은 소비자 프로젝트 ID 또는 숫자 목록입니다. 이 필드는 connectionPreferenceACCEPT_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.

다음 단계