고급 트래픽 관리로 프록시리스 gRPC 서비스 설정

이 문서에서는 다음과 같은 라우팅 기능으로 Traffic Director를 구성하는 전체 과정을 설명합니다.

  • 경로 일치
  • 트래픽 분할

이러한 기능의 개념은 고급 트래픽 관리를 참조하세요.

이러한 기능을 설명하기 위해 gRPC 월렛 예시를 배포합니다. 아래 다이어그램과 같이 wallet-service, stats-service, account-service용 백엔드 서비스를 만듭니다.

gRPC 월렛 트래픽 라우팅 구성 예시(확대하려면 클릭)
gRPC 월렛 트래픽 라우팅 구성 예시(확대하려면 클릭)

이 예시에서는 구성한 규칙에 따라 각 서비스의 여러 버전을 배포하여 요청 라우팅을 보여줍니다. 여러 서비스 버전의 빌드와 배포를 시뮬레이션하도록 서버 플래그를 사용하여 한 번만 빌드하는 바이너리의 동작을 변경합니다.

  • --port 플래그는 백엔드 VM의 서비스가 리슨하는 포트를 지정합니다.
  • --hostname_suffix 플래그는 요청에 응답하는 VM의 호스트 이름에 추가되는 값을 지정합니다. 결과 값은 응답에 hostname 메타데이터로 추가됩니다. 이렇게 하면 클라이언트 요청에 응답한 백엔드 서비스의 인스턴스를 식별할 수 있습니다.
  • --premium_only 플래그를 true 값으로 지정하면 서비스가 stats 서비스의 프리미엄 버전으로 지정됩니다.
  • --v1_behavior 플래그를 true 값으로 지정하면 월렛 바이너리가 v1 버전으로 동작합니다.
서비스 인스턴스 그룹 인스턴스 서버 플래그
account account 2 --port=50053
--hostname_suffix="account"
stats stats 2 --port=50052
--hostname_suffix="stats"
--account_server="xds:///account.grpcwallet.io"
stats-premium stats-premium 2 --port=50052
--hostname_suffix="stats_premium"
--account_server="xds:///account.grpcwallet.io"
--premium_only=true
wallet-v1 wallet-v1 2 --port=50051
--hostname_suffix="wallet_v1"
--v1_behavior=true
--account_server="xds:///account.grpcwallet.io"
--stats_server="xds:///stats.grpcwallet.io"
wallet-v2 wallet-v2 2 --port=50051
--hostname_suffix "wallet_v2"
--account_server="xds:///account.grpcwallet.io"
--stats_server="xds:///stats.grpcwallet.io"

그런 후 다음 라우팅 규칙에 따라 Traffic Director가 요청을 테스트 클라이언트에서 이러한 서비스로 라우팅하도록 구성합니다.

호스트 일치 규칙 라우팅 작업
wallet.grpcwallet.io 기본 wallet-v1
전체 경로: /grpc.examples.wallet.Wallet/FetchBalance wallet-v1: 40%
wallet-v2: 60%
경로 프리픽스: /grpc.examples.wallet.Wallet/ wallet-v2
stats.grpcwallet.io 기본 stats
경로 프리픽스: "/"
헤더: {"membership": "premium"}
stats-premium
account.grpcwallet.io 기본 account

gRPC 상태 확인 및 방화벽 규칙 만들기

이 섹션에서는 gRPC 상태 확인과 gRPC 상태 확인 요청이 네트워크에 도달하도록 허용하는 방화벽 규칙을 만듭니다. 나중에 gRPC 상태 확인은 백엔드 서비스와 연결되어 백엔드 서비스의 백엔드 상태를 확인합니다.

gcloud

  1. 상태 확인을 만듭니다.

    gcloud compute health-checks create grpc grpcwallet-health-check \
      --use-serving-port
    
  2. 상태 확인의 방화벽 규칙을 만듭니다.

    gcloud compute firewall-rules create grpcwallet-allow-health-checks \
       --network default --action allow --direction INGRESS \
       --source-ranges 35.191.0.0/16,130.211.0.0/22 \
       --target-tags allow-health-checks \
       --rules tcp:50051-50053
    

인스턴스 템플릿 만들기

이 섹션에서는 포트 50053에 노출된 account gRPC 서비스를 배포하는 인스턴스 템플릿을 만듭니다.

gcloud

  1. 인스턴스 템플릿을 만듭니다.

    gcloud compute instance-templates create grpcwallet-account-template \
      --scopes=https://www.googleapis.com/auth/cloud-platform \
      --tags=allow-health-checks \
      --image-family=debian-10 \
      --image-project=debian-cloud \
      --metadata-from-file=startup-script=<(echo '#! /bin/bash
    set -ex
    cd /root
    export HOME=/root
    sudo apt-get update -y
    curl -L https://github.com/GoogleCloudPlatform/traffic-director-grpc-examples/archive/master.tar.gz | tar -xz
    cd traffic-director-grpc-examples-master/go/account_server/
    sudo apt-get install -y golang git
    go build .
    sudo systemd-run ./account_server --port 50053 --hostname_suffix account')
    

관리형 인스턴스 그룹 만들기

관리형 인스턴스 그룹은 필요에 따라 자동 확장을 사용하여 새 백엔드 VM을 만듭니다. 이 섹션에서는 이전 섹션에서 만든 인스턴스 템플릿을 사용하여 관리형 인스턴스 그룹을 만듭니다.

gcloud

  1. 인스턴스 그룹을 만듭니다.

    gcloud compute instance-groups managed create grpcwallet-account-mig-us-central1 \
      --zone us-central1-a \
      --size=2 \
      --template=grpcwallet-account-template
    

이름이 지정된 포트 구성

이 섹션에서는 gRPC 서비스에 사용될 이름이 지정된 포트를 구성합니다. 이름이 지정된 포트는 gRPC 서비스가 요청을 리슨하는 포트입니다. 이 예시에서 이름이 지정된 포트는 포트 50053입니다.

gcloud

  1. 이름이 지정된 포트를 만듭니다.

    gcloud compute instance-groups set-named-ports grpcwallet-account-mig-us-central1 \
      --named-ports=grpcwallet-account-port:50053 \
      --zone us-central1-a
    

백엔드 서비스 만들기

이 섹션에서는 부하 분산 스키마 INTERNAL_SELF_MANAGED와 프로토콜 GRPC를 사용하여 전역 백엔드 서비스를 만든 후 상태 확인과 인스턴스 그룹을 이 백엔드 서비스에 연결합니다. 이 예시에서는 관리형 인스턴스 그룹 만들기에서 만든 관리형 인스턴스 그룹을 사용합니다. 이 관리형 인스턴스 그룹은 account gRPC 서비스를 실행합니다. --port-name 플래그의 포트는 이름이 지정된 포트 구성에서 만든 이름이 지정된 포트입니다.

gcloud

  1. 백엔드 서비스를 만들고 상태 확인을 새 백엔드 서비스에 연결합니다.

    gcloud compute backend-services create grpcwallet-account-service \
        --global \
        --load-balancing-scheme=INTERNAL_SELF_MANAGED \
        --protocol=GRPC \
        --port-name=grpcwallet-account-port \
        --health-checks grpcwallet-health-check
    
  2. 관리형 인스턴스 그룹을 백엔드로 추가합니다.

    gcloud compute backend-services add-backend grpcwallet-account-service \
      --instance-group grpcwallet-account-mig-us-central1 \
      --instance-group-zone us-central1-a \
      --global
    

gRPC 월렛 예시에서 사용할 나머지 백엔드 서비스를 만드는 단계는 위 단계와 비슷합니다. 셸 스크립트를 실행하여 나머지 서비스를 만듭니다. 스크립트는 다음 백엔드 서비스를 배포합니다.

  • stats
  • stats-premium
  • wallet-v1
  • wallet-v2

추가 백엔드 서비스를 만드는 셸 스크립트를 실행합니다.

curl -O https://raw.githubusercontent.com/GoogleCloudPlatform/traffic-director-grpc-examples/master/scripts/create_service.sh
chmod +x ./create_service.sh

./create_service.sh go stats 50052 stats '--account_server="xds:///account.grpcwallet.io"'

./create_service.sh go stats 50052 stats-premium '--account_server="xds:///account.grpcwallet.io" --premium_only=true'

./create_service.sh java wallet 50051 wallet-v1 '--account_server="xds:///account.grpcwallet.io" --stats_server="xds:///stats.grpcwallet.io" --v1_behavior=true'

./create_service.sh java wallet 50051 wallet-v2 '--account_server="xds:///account.grpcwallet.io" --stats_server="xds:///stats.grpcwallet.io"'

라우팅 규칙 만들기

이 섹션에서는 예시를 통해 서비스의 가상 호스트 이름과 관련 라우팅 규칙을 지정하는 URL 맵을 만듭니다. 자세한 내용은 라우팅 규칙 맵을 참조하세요.

URL 맵에서 hostRules는 예시의 서비스 가상 호스트 이름을 지정합니다. 클라이언트가 특정 서비스에 연결하도록 채널 URI에서 사용하는 이름입니다. 예를 들어 account 서비스에 요청을 보내려면 클라이언트는 채널 URI에서 xds:///account.grpcwallet.io를 사용합니다. hostRules에서 hosts 항목을 account.grpcwallet.io 값으로 구성해야 합니다.

hosts 항목과 연결된 pathMatcher는 가상 호스트의 모든 라우팅 규칙이 포함된 pathMatcher의 이름을 지정합니다. pathMatcher 구성은 일치하는 규칙과 해당 작업 규칙으로 구성됩니다. 이 예시에서는 다음과 같이 구성됩니다.

  • 요청이 account.grpcwallet.io로 전송되면 이 요청을 grpcwallet-account-service 백엔드 서비스로 전송합니다.
  • 요청이 stats.grpcwallet.io로 전송된 경우:
    • 요청에 값이 premiummembership 헤더가 포함되어 있으면 요청을 grpcwallet-stats-premium-service 백엔드 서비스로 전송합니다.
    • 또는 기본 백엔드 서비스 grpcwallet-stats-service로 요청을 전송합니다.
  • 요청이 wallet.grpcwallet.io로 전송된 경우:

    • ServiceName/MethodName이 /grpc.examples.wallet.Wallet/FetchBalance와 일치하면 해당 요청의 40%를 grpcwallet-wallet-v2-service 백엔드 서비스로 전송하고 나머지 요청을 grpcwallet-wallet-v1-service 백엔드 서비스로 전송합니다.
    • 그렇지 않고 ServiceName/grpc.examples.wallet.Wallet/과 일치하면 호출된 메서드와 관계없이 요청을 grpcwallet-wallet-v1-service 백엔드 서비스로 전송합니다.

gcloud

다음을 실행하여 URL 맵을 만듭니다.

export PROJECT_ID=$(gcloud config list --format 'value(core.project)')

gcloud compute url-maps import grpcwallet-url-map << EOF
defaultService: projects/$PROJECT_ID/global/backendServices/grpcwallet-account-service
name: grpcwallet-url-map
hostRules:
- hosts:
  - account.grpcwallet.io
  pathMatcher: grpcwallet-account-path-matcher
- hosts:
  - stats.grpcwallet.io
  pathMatcher: grpcwallet-stats-path-matcher
- hosts:
  - wallet.grpcwallet.io
  pathMatcher: grpcwallet-wallet-path-matcher
pathMatchers:
- defaultService: projects/$PROJECT_ID/global/backendServices/grpcwallet-account-service
  name: grpcwallet-account-path-matcher
- defaultService: projects/$PROJECT_ID/global/backendServices/grpcwallet-stats-service
  name: grpcwallet-stats-path-matcher
  routeRules:
  - matchRules:
    - prefixMatch: /
      headerMatches:
      - headerName: membership
        exactMatch: premium
    priority: 0
    service: projects/$PROJECT_ID/global/backendServices/grpcwallet-stats-premium-service
- defaultService: projects/$PROJECT_ID/global/backendServices/grpcwallet-wallet-v1-service
  name: grpcwallet-wallet-path-matcher
  routeRules:
  - matchRules:
    - fullPathMatch: /grpc.examples.wallet.Wallet/FetchBalance
    priority: 0
    routeAction:
      weightedBackendServices:
      - backendService: projects/$PROJECT_ID/global/backendServices/grpcwallet-wallet-v2-service
        weight: 40
      - backendService: projects/$PROJECT_ID/global/backendServices/grpcwallet-wallet-v1-service
        weight: 60
  - matchRules:
    - prefixMatch: /grpc.examples.wallet.Wallet/
    priority: 1
    routeAction:
      weightedBackendServices:
      - backendService: projects/$PROJECT_ID/global/backendServices/grpcwallet-wallet-v2-service
        weight: 100
EOF

대상 프록시 및 전달 규칙 만들기

이 섹션에서는 대상 gRPC 프록시와 전달 규칙을 만듭니다.

대상 gRPC 프록시는 이전 단계에서 만든 URL 맵을 참조합니다. --validate-for-proxyless 플래그를 지정하면 프록시리스 gRPC 배포와 호환되지 않는 기능이 우발적으로 사용 설정되지 않도록 구성 확인을 사용 설정할 수 있습니다.

gcloud

  1. 대상 gRPC 프록시를 만듭니다.

    gcloud compute target-grpc-proxies create grpcwallet-proxy \
      --url-map grpcwallet-url-map \
      --validate-for-proxyless
    

전달 규칙은 생성된 대상 gRPC 프록시를 참조합니다. 부하 분산 스키마가 INTERNAL_SELF_MANAGED로 설정되어 이 전달 규칙이 Traffic Director에서 사용됨을 나타냅니다. 전역 전달 규칙이어야 합니다. IP 주소는 0.0.0.0으로 설정됩니다. 프록시리스 gRPC 클라이언트가 DNS를 조회하는 대신 LDS 요청을 Traffic Director로 전송하여 대상 URI의 hostname:port를 확인하기 때문입니다. 자세한 내용은 이름 확인 스키마를 참조하세요.

대상 URI에 포트가 지정되어 있지 않으면 기본값은 80입니다. 예를 들어 대상 URI xds:///foo.myservice:8080은 포트 8080으로 구성된 전달 규칙과 일치합니다. 이 예시에서 전달 규칙은 포트 80으로 구성됩니다.

gcloud

  1. 전달 규칙을 만듭니다.

    gcloud compute forwarding-rules create grpcwallet-forwarding-rule \
       --global \
       --load-balancing-scheme=INTERNAL_SELF_MANAGED \
       --address=0.0.0.0 --address-region=us-central1 \
       --target-grpc-proxy=grpcwallet-proxy \
       --ports 80 \
       --network default
    

구성 확인

구성 프로세스가 완료되면 Console의 Traffic Director 페이지를 확인하여 구성한 백엔드 서비스를 사용할 수 있는지 확인합니다. 백엔드 서비스와 관련 백엔드가 정상으로 보고되었는지 확인합니다.

라우팅 구성 확인

이 섹션에서는 라우팅 구성이 올바르게 작동하는지 확인합니다. grpcurl 도구를 사용하여 구성을 테스트합니다.

gcloud

  1. 클라이언트를 실행할 클라이언트 VM을 만들어 서비스를 테스트합니다.

    gcloud compute instances create grpc-wallet-client \
      --zone us-central1-a \
      --scopes=https://www.googleapis.com/auth/cloud-platform \
      --image-family=debian-10 \
      --image-project=debian-cloud \
      --metadata-from-file=startup-script=<(echo '#! /bin/bash
    set -e
    export GRPC_XDS_BOOTSTRAP=/run/td-grpc-bootstrap.json
    # Expose bootstrap variable to SSH connections
    echo export GRPC_XDS_BOOTSTRAP=$GRPC_XDS_BOOTSTRAP | sudo tee /etc/profile.d/grpc-xds-bootstrap.sh
    # Create the bootstrap file
    curl -L https://storage.googleapis.com/traffic-director/td-grpc-bootstrap-0.9.0.tar.gz | tar -xz
    ./td-grpc-bootstrap-0.9.0/td-grpc-bootstrap | tee $GRPC_XDS_BOOTSTRAP')
    
  2. SSH를 사용하여 VM에 액세스합니다.

사이드카 프록시 없이 서비스에 액세스하려면 gRPC 클라이언트에서 xds 이름 확인 스키마를 사용해야 합니다. 이 스키마는 클라이언트에서 사용되는 gRPC 라이브러리에 xDS 서버를 사용하여 호스트 이름을 확인하도록 지시합니다. 이렇게 하려면 부트스트랩 구성이 필요합니다. 이전 섹션의 시작 스크립트는 GRPC_XDS_BOOTSTRAP 환경 변수를 설정하고 도우미 스크립트를 사용하여 부트스트랩 파일을 생성합니다. Compute Engine VM 인스턴스에 대한 이러한 세부정보를 알고 있는 메타데이터 서버에서 생성된 부트스트랩 파일에 있는 TRAFFICDIRECTOR_GCP_PROJECT_NUMBER, TRAFFICDIRECTOR_NETWORK_NAME, 영역의 값을 가져옵니다. -gcp-project-number 옵션과 -vpc-network-name 옵션을 사용하면 이러한 값을 도우미 스크립트에 수동으로 제공할 수 있습니다.

grpcurl 도구를 사용하여 구성 확인

먼저 grpcurl 도구를 설치합니다.

curl -L https://github.com/fullstorydev/grpcurl/releases/download/v1.6.1/grpcurl_1.6.1_linux_x86_64.tar.gz | tar -xz
chmod +x grpcurl

다음으로 다음 명령어를 실행하여 Account, Stats, Wallet 서비스가 실행 중인지 확인합니다.

$ ./grpcurl -plaintext xds:///account.grpcwallet.io list
grpc.examples.wallet.account.Account
grpc.health.v1.Health
grpc.reflection.v1alpha.ServerReflection

$ ./grpcurl -plaintext -d '{"token": "2bd806c9"}' xds:///account.grpcwallet.io grpc.examples.wallet.account.Account/GetUserInfo
{
  "name": "Alice",
  "membership": "PREMIUM"
}

$ ./grpcurl -plaintext -H 'authorization:2bd806c9' -H 'membership:premium' xds:///stats.grpcwallet.io grpc.examples.wallet.stats.Stats/FetchPrice
{
  "price": "10295"
}

$ ./grpcurl -plaintext -H 'authorization:2bd806c9' -H 'membership:premium' -d '{"include_balance_per_address": true}' xds:///wallet.grpcwallet.io grpc.examples.wallet.Wallet/FetchBalance
{
  "balance": "5089953"
}

grpc-wallet 클라이언트에서 확인

다음 언어별 안내를 따라 구성을 확인합니다. 이 명령어는 URL 맵의 일치 규칙에 따라 요청이 백엔드 서비스로 라우팅됨을 보여주기 위해 추가 메타데이터와 함께 RPC 여러 개를 전송합니다. 또한 이 명령어는 각 응답의 백엔드 호스트 이름을 출력하여 요청이 라우팅된 백엔드 서비스를 보여줍니다.

C++

  1. gRPC C++ 클라이언트에서 서비스를 확인하려면 다음을 실행합니다.

    sudo apt-get update
    sudo apt-get install -y build-essential git
    
    git clone https://github.com/GoogleCloudPlatform/traffic-director-grpc-examples.git
    cd traffic-director-grpc-examples/cpp
    ../tools/bazel build :client
    
    # This command calls FetchBalance from the Wallet service in a loop, to demonstrate that
    # FetchBalance gets responses from wallet-v1 (40%) and wallet-v2 (60%).
    ../bazel-bin/cpp/client balance --wallet_server="xds:///wallet.grpcwallet.io" --unary_watch=true
    
    # This command calls the streaming RPC WatchBalance from the Wallet
    # service. The RPC path matches the service prefix, so all requests are sent to wallet-v2.
    ../bazel-bin/cpp/client balance --wallet_server="xds:///wallet.grpcwallet.io" --watch=true
    
    # This command calls WatchPrice from the Stats service. It sends the
    # user's membership (premium or not) in metadata. Premium requests are
    # all sent to stats-premium, and get faster responses. Alice's requests
    # always go to premium, and Bob goes to regular.
    ../bazel-bin/cpp/client price --stats_server="xds:///stats.grpcwallet.io" --watch=true --user=Bob
    ../bazel-bin/cpp/client price --stats_server="xds:///stats.grpcwallet.io" --watch=true --user=Alice
    

Go

  1. gRPC Go 클라이언트에서 서비스를 확인하려면 다음을 실행합니다.

    sudo apt-get update
    sudo apt install -y golang git
    
    git clone https://github.com/GoogleCloudPlatform/traffic-director-grpc-examples.git
    cd traffic-director-grpc-examples/go/wallet_client
    go build .
    
    # This command calls FetchBalance from the Wallet service in a loop,
    # to demonstrate that FetchBalance gets responses from wallet-v1 (40%)
    # and wallet-v2 (60%).
    ./wallet_client balance --wallet_server="xds:///wallet.grpcwallet.io" --unary_watch
    
    # This command calls the streaming RPC WatchBalance from the Wallet
    # service. The RPC path matches the service prefix, so all requests
    # are sent to wallet-v2.
    ./wallet_client balance --wallet_server="xds:///wallet.grpcwallet.io" --watch
    
    # This command calls WatchPrice from the Stats service. It sends the
    # user's membership (premium or not) in metadata. Premium requests are
    # all sent to stats-premium, and get faster responses. Alice's requests
    # always go to premium and Bob goes to regular.
    ./wallet_client price --stats_server="xds:///stats.grpcwallet.io" --watch --user=Bob
    ./wallet_client price --stats_server="xds:///stats.grpcwallet.io" --watch --user=Alice
    

자바

  1. gRPC 자바 클라이언트에서 서비스를 확인하려면 다음을 실행합니다.

    sudo apt-get update
    sudo apt-get install -y openjdk-11-jdk-headless git
    
    git clone https://github.com/GoogleCloudPlatform/traffic-director-grpc-examples.git
    cd traffic-director-grpc-examples/java
    ./gradlew installDist
    
    # This command calls FetchBalance from the Wallet service in a loop,
    # to demonstrate that FetchBalance gets responses from wallet-v1 (40%)
    # and wallet-v2(60%).
    ./build/install/wallet/bin/client balance --wallet_server="xds:///wallet.grpcwallet.io" --unary_watch=true
    
    # This command calls the streaming RPC WatchBalance from the Wallet
    # service. The RPC path matches the service prefix, so all requests are
    # sent to wallet-v2.
    ./build/install/wallet/bin/client balance --wallet_server="xds:///wallet.grpcwallet.io" --watch=true
    
    # This command calls WatchPrice from the Stats service. It sends the
    # user's membership (premium or not) in metadata. Premium requests are
    # all sent to stats-premium, and get faster responses. Alice's requests
    # always go to premium and Bob goes to regular.
    ./build/install/wallet/bin/client price --stats_server="xds:///stats.grpcwallet.io" --watch=true --user=Bob
    ./build/install/wallet/bin/client price --stats_server="xds:///stats.grpcwallet.io" --watch=true --user=Alice
    

리소스 삭제

다음 스크립트를 실행하여 리소스를 삭제합니다.

bash <(curl -s https://raw.githubusercontent.com/GoogleCloudPlatform/traffic-director-grpc-examples/master/scripts/cleanup.sh)
gcloud compute instances delete grpc-wallet-client --zone us-central1-a -q

다음 단계

구성 과정에서 예상치 못한 동작이 발생하면 프록시리스 Traffic Director 배포 문제 해결프록시리스 gRPC 애플리케이션 사용 시의 Traffic Director 제한사항을 참조하세요.