Google Kubernetes Engine 및 프록시리스 gRPC 서비스 설정
이 가이드에서는 Google Kubernetes Engine, gRPC 애플리케이션, Cloud Service Mesh에 필요한 부하 분산 구성요소를 구성하는 방법을 설명합니다.
이 가이드의 안내를 따르기 전에 프록시리스 gRPC 서비스로 Cloud Service Mesh 설정 준비를 검토하세요.
개요
GKE 및 프록시리스 gRPC 서비스로 Cloud Service Mesh를 설정하는 방법은 다음과 같습니다.
- GKE 클러스터 준비
- gRPC 서버 애플리케이션을 Kubernetes 서비스로 배포 서비스에 대해 네트워크 엔드포인트 그룹(NEG)을 자동으로 만들도록 GKE 배포 사양에 주석을 지정합니다.
- NEG 및 기타 Google Cloud Load Balancing 구성요소를 사용하여 Cloud Service Mesh 구성
- 프록시리스 gRPC 클라이언트 애플리케이션을 사용하여 gRPC 서버 애플리케이션에 트래픽을 전송하여 배포가 제대로 작동하는지 확인합니다.
Cloud Service Mesh용 GKE 클러스터 구성
이 섹션에서는 Cloud Service Mesh에서 사용할 수 있도록 GKE 클러스터를 사용 설정하는 방법을 설명합니다.
GKE 클러스터 요구사항
GKE 클러스터는 다음과 같은 요구사항을 충족해야 합니다.
- 네트워크 엔드포인트 그룹에 대해 지원을 사용 설정해야 합니다. 자세한 내용과 예시는 독립형 네트워크 엔드포인트 그룹을 참조하세요. 독립형 NEG 기능은 Cloud Service Mesh의 정식 버전으로 제공됩니다.
- 클러스터 노드 인스턴스의 서비스 계정에 Cloud Service Mesh API에 액세스할 수 있는 권한이 있어야 합니다. 필요한 권한에 대한 자세한 내용은 Cloud Service Mesh API에 액세스할 수 있도록 서비스 계정 사용 설정을 참조하세요.
- 컨테이너는 OAuth 인증으로 보호되는 Cloud Service Mesh API에 액세스할 수 있어야 합니다. 자세한 내용은 호스트 구성을 참조하세요.
GKE 클러스터 만들기
다음 예시에서는 us-central1-a zone
에서 grpc-td-cluster
라는 GKE 클러스터를 만드는 방법을 보여줍니다.
콘솔
Google Cloud 콘솔을 사용하여 클러스터를 만들려면 다음 단계를 수행하세요.
Google Cloud 콘솔에서 Kubernetes Engine 메뉴로 이동합니다.
클러스터 만들기를 클릭합니다.
표준 클러스터 템플릿을 선택하거나 워크로드에 적합한 템플릿을 선택합니다.
필요한 경우 템플릿을 맞춤설정합니다. 다음 필드는 필수입니다.
- 이름:
grpc-td-cluster
를 입력합니다. - 위치 유형:
Zonal
- 영역:
us-central1-a
- 노드 풀:
- 이름:
왼쪽 메뉴에서 default-pool을 클릭합니다.
이름을
grpc-td-cluster
로 변경합니다.크기에 만들 노드 수를 입력합니다. 노드 및 해당 리소스(예: 방화벽 경로)에 사용 가능한 리소스 할당량이 있어야 합니다.
왼쪽 메뉴에서 노드를 클릭합니다.
머신 구성의 머신 계열에서 컴퓨팅 최적화를 클릭합니다.
머신 유형을 선택합니다. 머신 유형 가격 책정 정보는 Compute Engine 가격 책정 페이지를 참조하세요.
네트워킹에서 네트워크 태그
allow-health-checks
를 추가합니다.왼쪽 메뉴에서 노드 보안을 클릭합니다.
액세스 범위에서 모든 Cloud API에 대한 전체 액세스 허용을 선택합니다.
만들기를 클릭합니다.
Google Cloud 콘솔에서 클러스터를 만든 후 클러스터와 상호작용하려면 kubectl
을 구성해야 합니다. 자세한 내용은 kubeconfig
항목 생성을 참조하세요.
gcloud
클러스터를 만듭니다.
gcloud container clusters create grpc-td-cluster \ --zone us-central1-a \ --scopes=https://www.googleapis.com/auth/cloud-platform \ --tags=allow-health-checks \ --enable-ip-alias
필수 GKE 클러스터 권한 가져오기
다음 명령어를 실행하여 방금 만든 클러스터로 전환합니다. 그러면 kubectl
이 올바른 클러스터를 가리킵니다.
gcloud
gcloud container clusters get-credentials grpc-td-cluster \ --zone us-central1-a
GKE 서비스 구성
이 섹션에서는 Cloud Service Mesh에서 사용할 수 있도록 GKE 배포 사양을 준비하는 방법을 설명합니다. 이는 NEG 주석이 있는 GKE helloworld
예시 서비스 구성으로 이루어집니다.
helloworld
예시 서비스는 gRPC 클라이언트 요청에 대한 응답으로 메시지를 반환하는 gRPC 서버 애플리케이션입니다. helloworld
서비스에는 특별한 것이 없습니다. 프록시리스 gRPC 서비스가 아니며 모든 gRPC 클라이언트의 요청에 응답할 수 있습니다.
'프록시리스' 부분은 gRPC 클라이언트 애플리케이션이 Cloud Service Mesh에 연결할 때에만 작동하므로 IP 주소나 DNS 기반 이름 변환을 사용할 필요 없이 helloworld
서비스를 알아보고 트래픽을 helloworld
와 연결된 포드에 전송할 수 있습니다.
NEG로 GKE 서비스 구성
Cloud Service Mesh에서 사용할 GKE 서비스를 구성하는 첫 번째 단계는 NEG를 통해 서비스를 노출하는 것입니다. NEG를 통해 노출하려면 각 사양에 노출할 포트와 일치하는 다음 주석이 있어야 합니다.
... metadata: annotations: cloud.google.com/neg: '{"exposed_ports":{"8080":{"name": "example-grpc-server"}}}'
이 주석은 서비스를 처음 배포할 때 독립형 NEG를 만듭니다. 이 NEG에는 포드의 IP 주소와 포트인 엔드포인트가 포함됩니다. 자세한 내용과 예시는 독립형 네트워크 엔드포인트 그룹을 참조하세요.
다음 예시에서는 포트 8080
으로 제공되는 helloworld
Kubernetes 서비스를 배포합니다. 이 포트는 클러스터에서 서비스가 표시되는 포트입니다. 포드의 gRPC 서비스는 targetPort
50051
에서 리슨합니다. 이 포트는 요청이 전송되는 포드의 포트입니다. 일반적으로 port
및 targetPort
는 편의를 위해 동일한 값으로 설정되지만, 이 예시에서는 NEG 주석에 사용할 올바른 값을 나타내기 위해 다른 값을 사용합니다.
cat << EOF > grpc-td-helloworld.yaml apiVersion: v1 kind: Service metadata: name: helloworld annotations: cloud.google.com/neg: '{"exposed_ports":{"8080":{"name": "example-grpc-server"}}}' spec: ports: - port: 8080 name: helloworld protocol: TCP targetPort: 50051 selector: run: app1 type: ClusterIP --- apiVersion: apps/v1 kind: Deployment metadata: labels: run: app1 name: app1 spec: selector: matchLabels: run: app1 replicas: 2 template: metadata: labels: run: app1 spec: containers: - image: grpc/java-example-hostname:1.50.2 name: app1 ports: - protocol: TCP containerPort: 50051 EOF
kubectl apply -f grpc-td-helloworld.yaml
새 helloworld
서비스가 만들어졌는지 확인합니다.
kubectl get svc
kubectl get svc
의 출력은 다음과 비슷합니다.
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE helloworld ClusterIP 10.71.9.71 <none> 8080/TCP 41m [..skip..]
애플리케이션 포드가 실행 중인지 확인합니다.
kubectl get pods
kubectl get pods
의 출력은 다음과 비슷합니다.
NAME READY STATUS RESTARTS AGE app1-6db459dcb9-zvfg2 1/1 Running 0 6m app1-6db459dcb9-hlvhj 1/1 Running 0 6m [..skip..]
NEG 이름이 올바른지 확인합니다.
콘솔
네트워크 엔드포인트 그룹의 목록을 보려면 Google Cloud 콘솔의 네트워크 엔드포인트 그룹 페이지로 이동하세요. example-grpc-server
라는 NEG가 표시됩니다.
네트워크 엔드포인트 그룹 페이지로 이동
gcloud
# List the NEGs gcloud compute network-endpoint-groups list \ --filter "name=example-grpc-server" --format "value(name)" # Optionally examine the NEG gcloud compute network-endpoint-groups describe example-grpc-server \ --zone us-central1-a # Optionally examine the endpoint(s) contained gcloud compute network-endpoint-groups list-network-endpoints example-grpc-server \ --zone us-central1-a
부하 분산 구성요소로 Cloud Service Mesh 구성
이 섹션에서는 서비스에 Google Cloud Load Balancing 구성요소를 구성하는 방법을 설명합니다. 이러한 구성요소에는 프록시리스 gRPC 클라이언트가 GKE 서비스와 통신할 수 있게 해주는 구성 정보가 포함됩니다.
다음 Cloud Service Mesh 구성 예시에서는 다음을 가정합니다.
- NEG 및 기타 모든 리소스는
us-central1-a
영역의 자동 모드 기본 네트워크에서 생성됩니다. - Google Cloud CLI를 사용하는 경우 클러스터의 NEG 이름은
example-grpc-server
입니다.
상태 확인, 방화벽 규칙 및 백엔드 서비스 만들기
이 섹션에서는 상태 확인 및 상태 확인용 방화벽 규칙을 만듭니다. 상태 확인은 gRPC 상태 확인 프로토콜을 사용해야 합니다. 방화벽 규칙을 사용하면 상태 확인 프로브가 배포에 있는 VM에 연결할 수 있습니다. --use-serving-port
지시문은 상태 확인이 각 엔드포인트에 대해 구성된 수신 포트를 가져오기 위해 사용됩니다.
방화벽 규칙은 네트워크의 인스턴스에 대한 수신 상태 확인 연결을 허용합니다.
이 섹션에서는 INTERNAL_SELF_MANAGED
및 프로토콜 GRPC
의 부하 분산 스키마를 사용하여 전역 백엔드 서비스를 만든 후 상태 확인을 백엔드 서비스와 연결합니다.
자세한 내용은 상태 확인 만들기를 참조하세요.
gcloud
상태 확인을 만듭니다.
gcloud compute health-checks create grpc grpc-gke-helloworld-hc \ --use-serving-port
방화벽 규칙 만들기
gcloud compute firewall-rules create grpc-gke-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
백엔드 서비스를 만듭니다.
gcloud compute backend-services create grpc-gke-helloworld-service \ --global \ --load-balancing-scheme=INTERNAL_SELF_MANAGED \ --protocol=GRPC \ --health-checks grpc-gke-helloworld-hc
백엔드 서비스에 백엔드 NEG를 추가합니다.
gcloud compute backend-services add-backend grpc-gke-helloworld-service \ --global \ --network-endpoint-group example-grpc-server \ --network-endpoint-group-zone us-central1-a \ --balancing-mode RATE \ --max-rate-per-endpoint 5
라우팅 규칙 맵 만들기
이 섹션에서는 호스트 이름 및 경로를 기반으로 서비스의 트래픽을 라우팅하는 URL 맵, 경로 일치자, 호스트 규칙을 만듭니다. 다음 예시에서는 helloworld-gke
를 서비스 이름으로 사용합니다. gRPC 클라이언트는 helloworld
서비스에 연결할 때 대상 URI에 이 서비스 이름을 사용합니다.
대상 gRPC 프록시 및 전달 규칙도 만듭니다.
자세한 내용은 라우팅 규칙 맵을 참조하세요.
다음 예시에서는 서비스 이름 helloworld-gke
및 8000
포트를 사용합니다.
즉, gRPC 클라이언트는 xds:///helloworld-gke:8000
을 사용하여 이 서비스에 연결해야 하며 URL 맵에 호스트 규칙 helloworld-gke:8000
이 구성되어야 합니다. helloworld-gke:8000
은 targetPort
50051
에서 리슨하는 NEG 엔드포인트로 직접 확인되므로 이전 섹션의 Kubernetes 서비스 사양에 표시된 서비스 포트 8080
은 Cloud Service Mesh에서 사용되지 않습니다.
일반적으로 URL 맵 호스트 규칙의 포트와 Kubernetes 서비스 사양 port
및 targetPort
모두 편의상 같은 값으로 설정되지만 이 예시에서는 Cloud Service Mesh가 서비스 사양의 port
를 사용하지 않음을 보여주기 위해 서로 다른 값을 사용합니다.
gcloud
URL 맵을 만듭니다.
gcloud compute url-maps create grpc-gke-url-map \ --default-service grpc-gke-helloworld-service
경로 일치자를 만듭니다.
gcloud compute url-maps add-path-matcher grpc-gke-url-map \ --default-service grpc-gke-helloworld-service \ --path-matcher-name grpc-gke-path-matcher \ --new-hosts helloworld-gke:8000
대상 gRPC 프록시를 만듭니다.
gcloud compute target-grpc-proxies create grpc-gke-proxy \ --url-map grpc-gke-url-map \ --validate-for-proxyless
전달 규칙을 만듭니다.
gcloud compute forwarding-rules create grpc-gke-forwarding-rule \ --global \ --load-balancing-scheme=INTERNAL_SELF_MANAGED \ --address=0.0.0.0 \ --target-grpc-proxy=grpc-gke-proxy \ --ports 8000 \ --network default
이제 Cloud Service Mesh가 URL 맵에 지정된 서비스의 NEG에서 엔드포인트 간에 트래픽을 부하 분산하도록 구성됩니다.
구성 확인
구성 프로세스가 완료되면 프록시리스 gRPC 클라이언트를 사용하여 helloworld
gRPC 서버에 연결할 수 있는지 확인합니다. 이 클라이언트는 Cloud Service Mesh에 연결되어 helloworld
서비스(grpc-gke-helloworld-service
백엔드 서비스를 사용하여 Cloud Service Mesh로 구성)에 대한 정보를 가져오고 이 정보를 사용하여 트래픽을 서비스의 백엔드로 전송합니다.
또한 Google Cloud 콘솔의 Cloud Service Mesh 섹션에서 구성된 서비스 helloworld-gke
에 대한 정보를 확인하고 백엔드가 정상으로 보고되는지 확인할 수 있습니다.
프록시리스 gRPC 클라이언트로 검증
다음 예시에서는 서로 다른 언어로 된 gRPC 클라이언트를 사용하거나 grpcurl
도구를 사용하여 Cloud Service Mesh가 메시에서 트래픽을 올바르게 라우팅하는지 확인합니다. 클라이언트 포드를 만든 후 셸을 열고 셸에서 인증 명령어를 실행합니다.
환경 변수 및 부트스트랩 파일 설정
클라이언트 애플리케이션에는 부트스트랩 구성 파일이 필요합니다. 파일 전송을 위해 부트스트랩 파일 및 볼륨을 생성하는 initContainer
를 추가하여 Kubernetes 애플리케이션 배포 사양을 수정합니다. 기존 컨테이너를 업데이트하여 파일을 찾습니다.
다음 initContainer
를 애플리케이션 배포 사양에 추가합니다.
initContainers: - args: - --output - "/tmp/bootstrap/td-grpc-bootstrap.json" image: gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.16.0 imagePullPolicy: IfNotPresent name: grpc-td-init resources: limits: cpu: 100m memory: 100Mi requests: cpu: 10m memory: 100Mi volumeMounts: - name: grpc-td-conf mountPath: /tmp/bootstrap/ volumes: - name: grpc-td-conf emptyDir: medium: Memory
다음을 포함하도록 애플리케이션 컨테이너의 env
섹션을 업데이트합니다.
env: - name: GRPC_XDS_BOOTSTRAP value: "/tmp/grpc-xds/td-grpc-bootstrap.json" volumeMounts: - name: grpc-td-conf mountPath: /tmp/grpc-xds/
다음은 클라이언트 Kubernetes 사양의 전체 예시입니다.
cat << EOF | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: labels: run: client name: sleeper spec: selector: matchLabels: run: client template: metadata: labels: run: client spec: containers: - image: openjdk:8-jdk imagePullPolicy: IfNotPresent name: sleeper command: - sleep - 365d env: - name: GRPC_XDS_BOOTSTRAP value: "/tmp/grpc-xds/td-grpc-bootstrap.json" resources: limits: cpu: "2" memory: 2000Mi requests: cpu: 300m memory: 1500Mi volumeMounts: - name: grpc-td-conf mountPath: /tmp/grpc-xds/ initContainers: - args: - --output - "/tmp/bootstrap/td-grpc-bootstrap.json" image: gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.16.0 imagePullPolicy: IfNotPresent name: grpc-td-init resources: limits: cpu: 100m memory: 100Mi requests: cpu: 10m memory: 100Mi volumeMounts: - name: grpc-td-conf mountPath: /tmp/bootstrap/ volumes: - name: grpc-td-conf emptyDir: medium: Memory EOF
배포가 준비되면 클라이언트 포드에 대한 셸을 엽니다.
kubectl exec -it $(kubectl get pods -o custom-columns=:.metadata.name \ --selector=run=client) -- /bin/bash
구성을 확인하려면 포드 셸에서 적절한 예시를 실행합니다.
자바
gRPC 자바 클라이언트에서 서비스를 확인하려면 다음 안내를 따르세요.
최신 패치와 함께 최신 버전의 gRPC 자바를 다운로드하고,
xds-hello-world
클라이언트 애플리케이션을 빌드합니다.curl -L https://github.com/grpc/grpc-java/archive/v1.37.0.tar.gz | tar -xz cd grpc-java-1.37.0/examples/example-xds ../gradlew --no-daemon installDist
"world"
를 이름으로,"xds:///helloworld-gke:8000"
을 서비스 URI 및 포트로 사용하여 클라이언트를 실행합니다../build/install/example-xds/bin/xds-hello-world-client "world" \ xds:///helloworld-gke:8000
Go
gRPC Go 클라이언트에서 서비스를 확인하려면 다음 안내를 따르세요.
최신 패치와 함께 최신 버전의 gRPC Go를 다운로드하고,
xds-hello-world
클라이언트 애플리케이션을 빌드합니다.apt-get update -y apt-get install -y golang git curl -L https://github.com/grpc/grpc-go/archive/v1.37.0.tar.gz | tar -xz cd grpc-go-1.37.0/examples/features/xds/client go get google.golang.org/grpc@v1.37.0 go build .
"world"
를 이름으로,"xds:///helloworld-gke:8000"
을 서비스 URI 및 포트로 사용하여 클라이언트를 실행합니다../client "world" xds:///helloworld-gke:8000
C++
gRPC C++ 클라이언트에서 서비스를 확인하려면 다음 안내를 따르세요.
최신 패치와 함께 최신 버전의 gRPC C++를 다운로드하고,
helloworld
클라이언트 예시를 빌드합니다.apt-get update -y apt-get install -y build-essential cmake git git clone --recurse-submodules -b v1.37.1 https://github.com/grpc/grpc cd grpc mkdir -p cmake/build pushd cmake/build cmake ../.. make make install popd mkdir -p third_party/abseil-cpp/cmake/build pushd third_party/abseil-cpp/cmake/build cmake ../.. make make install popd cd examples/cpp/helloworld mkdir -p cmake/build cd cmake/build/ cmake ../.. make
'xds:///helloworld-gke:8000'을 서비스 URI 및 포트로 클라이언트를 실행합니다.
./greeter_client --target=xds:///helloworld-gke:8000
grpcurl
grpcurl
도구는 프록시리스 gRPC 클라이언트 역할을 할 수도 있습니다. 이 경우 grpcurl
은 환경 변수와 부트스트랩 정보를 사용하여 Cloud Service Mesh에 연결합니다. 그런 다음 grpc-gke-helloworld-service
백엔드 서비스를 통해 Cloud Service Mesh로 구성된 helloworld
서비스를 알아봅니다.
grpcurl
도구를 사용하여 구성을 확인하려면 다음 안내를 따르세요.
grpcurl
도구를 다운로드하고 설치합니다.curl -L https://github.com/fullstorydev/grpcurl/releases/download/v1.8.1/grpcurl_1.8.1_linux_x86_64.tar.gz | tar -xz
'xds:///helloworld-gke:8000'을 서비스 URI로,
helloworld.Greeter/SayHello
을 호출할 서비스 이름과 메서드로 지정하고grpcurl
도구를 실행합니다.SayHello
메서드에 대한 매개변수는-d
옵션을 사용하여 전달합니다../grpcurl --plaintext \ -d '{"name": "world"}' \ xds:///helloworld-gke:8000 helloworld.Greeter/SayHello
Python
gRPC Python 클라이언트에서 서비스를 확인하려면 다음을 실행합니다. 최신 패치가 적용된 최신 버전의 gRPC를 사용합니다.
apt-get update -y apt-get install python3-pip -y pip3 install virtualenv curl -L https://github.com/grpc/grpc/archive/v1.37.1.tar.gz | tar -xz cd grpc-1.37.1/examples/python/xds virtualenv venv -p python3 source venv/bin/activate pip install -r requirements.txt python client.py xds:///helloworld-gke:8000
Ruby
gRPC Ruby 클라이언트에서 서비스를 확인하려면 다음을 실행합니다. 최신 패치가 적용된 최신 버전의 gRPC를 사용합니다.
apt-get update -y apt-get install -y ruby-full gem install grpc curl -L https://github.com/grpc/grpc/archive/v1.37.1.tar.gz | tar -xz cd grpc-1.37.1/examples/ruby ruby greeter_client.rb john xds:///helloworld-gke:8000
PHP
gRPC PHP 클라이언트에서 서비스를 확인하려면 다음을 실행합니다. 최신 패치가 적용된 최신 버전의 gRPC를 사용합니다.
apt-get update -y apt-get install -y php7.3 php7.3-dev php-pear phpunit python-all zlib1g-dev git pecl install grpc curl -sS https://getcomposer.org/installer | php mv composer.phar /usr/local/bin/composer curl -L https://github.com/grpc/grpc/archive/v1.37.1.tar.gz | tar -xz cd grpc-1.37.1 export CC=/usr/bin/gcc ./tools/bazel build @com_google_protobuf//:protoc ./tools/bazel build src/compiler:grpc_php_plugin cd examples/php composer install ../../bazel-bin/external/com_google_protobuf/protoc --proto_path=../protos \ --php_out=. --grpc_out=. \ --plugin=protoc-gen-grpc=../../bazel-bin/src/compiler/grpc_php_plugin \ ../protos/helloworld.proto php -d extension=grpc.so greeter_client.php john xds:///helloworld-gke:8000
Node.js
gRPC Node.js 클라이언트를 사용하여 서비스를 확인하려면 다음을 실행합니다. 최신 패치가 적용된 최신 버전의 gRPC를 사용합니다.
apt-get update -y apt-get install -y nodejs npm curl -L https://github.com/grpc/grpc/archive/v1.34.0.tar.gz | tar -xz cd grpc-1.34.0/examples/node/xds npm install node ./greeter_client.js --target=xds:///helloworld-gke:8000
INSTANCE_HOST_NAME
이 VM 인스턴스의 호스트 이름인 다음과 비슷한 출력이 표시됩니다.
Greetings: Hello world, from INSTANCE_HOST_NAME
이렇게 하면 프록시리스 gRPC 클라이언트가 성공적으로 Cloud Service Mesh에 연결되고 xds 이름 리졸버를 사용하여 helloworld-gke
서비스의 백엔드를 알아봤는지 확인할 수 있습니다. 클라이언트는 IP 주소 정보를 확인하거나 DNS 확인을 수행할 필요 없이 서비스의 백엔드 중 하나에 요청을 보냈습니다.
다음 단계
- Cloud Service Mesh 서비스 보안 알아보기
- 고급 트래픽 관리 알아보기
- 관측 가능성 설정 방법 알아보기
- 프록시리스 Cloud Service Mesh 배포 문제 해결 방법 알아보기