리전별 Cloud Service Mesh

리전 격리를 사용하면 Cloud Service Mesh 컨트롤 플레인의 특정 리전에 연결된 클라이언트가 해당 리전 내의 리소스에만 액세스할 수 있습니다. 마찬가지로 특정 리전 내의 API 리소스는 해당 리전의 다른 리소스만 참조할 수 있습니다.

리전 Cloud Service Mesh에는 다음과 같은 제한사항이 있습니다.

  • Istio API가 지원되지 않습니다. 리전 Traffic Director를 사용하여 Istio API와 함께 Kubernetes를 사용할 수 없습니다. 이 미리보기에서는 Google Cloud API만 지원됩니다.
  • 전역 서비스 라우팅 API의 기존 고려사항 및 제한사항이 적용됩니다.
  • xdSTP 명명 규칙을 지원하는 최소 Envoy 버전은 v1.31.1입니다.
  • 메시용 게이트웨이 API는 지원되지 않습니다.
  • 최소 gRPC 버전은 v1.65입니다.
  • 다음 리전만 지원됩니다.

    africa-south1
    asia-east1
    asia-east2
    asia-northeast1
    asia-northeast2
    asia-northeast3
    asia-south1
    asia-south2
    asia-southeast1
    asia-southeast2
    australia-southeast1
    australia-southeast2
    europe-central2
    europe-north1
    europe-north2
    europe-southwest1
    europe-west10
    europe-west12
    europe-west1
    europe-west2
    europe-west3
    europe-west4
    europe-west6
    europe-west8
    europe-west9
    me-central1
    me-central2
    me-west1
    northamerica-northeast1
    northamerica-northeast2
    northamerica-south1
    southamerica-east1
    southamerica-west1
    us-central1
    us-east1
    us-east4
    us-east5
    us-south1
    us-west1
    us-west2
    us-west3
    us-west4
    

가격 책정

이 기능이 정식 버전으로 출시되면 리전별 Cloud Service Mesh가 지원되는 각 리전에는 리전별 SKU가 있습니다. 현재 가격은 글로벌과 동일합니다.

Cloud Service Mesh용 xDS 클라이언트 준비

Compute VM Envoy xDS

수동

수동 단계는 수동 Envoy 배포를 사용하여 VM 설정을 기반으로 합니다. 주요 차이점은 ENVOY_CONTROL_PLANE_REGION가 설정되고 부트스트랩에 삽입된다는 것입니다.

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

    gcloud compute instance-templates create td-vm-templategcloud compute instance-templates create td-vm-template \
      --scopes=https://www.googleapis.com/auth/cloud-platform \
      --tags=http-td-tag,http-server,https-server \
      --image-family=debian-11 \
      --image-project=debian-cloud \
      --metadata=startup-script='#! /usr/bin/env bash
    
    # Set variables
    export ENVOY_CONTROL_PLANE_REGION="us-central1"
    export ENVOY_USER="envoy"
    export ENVOY_USER_UID="1337"
    export ENVOY_USER_GID="1337"
    export ENVOY_USER_HOME="/opt/envoy"
    export ENVOY_CONFIG="${ENVOY_USER_HOME}/config.yaml"
    export ENVOY_PORT="15001"
    export ENVOY_ADMIN_PORT="15000"
    export ENVOY_TRACING_ENABLED="false"
    export ENVOY_XDS_SERVER_CERT="/etc/ssl/certs/ca-certificates.crt"
    export ENVOY_ACCESS_LOG="/dev/stdout"
    export ENVOY_NODE_ID="$(cat /proc/sys/kernel/random/uuid)~$(hostname -i)"
    export BOOTSTRAP_TEMPLATE="${ENVOY_USER_HOME}/bootstrap_template.yaml"
    export GCE_METADATA_SERVER="169.254.169.254/32"
    export INTERCEPTED_CIDRS="*"
    export GCP_PROJECT_NUMBER=PROJECT_NUMBER
    export VPC_NETWORK_NAME=mesh:sidecar-mesh
    export GCE_ZONE=$(curl -sS -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/zone | cut -d"/" -f4)
    
    # Create system user account for Envoy binary
    sudo groupadd ${ENVOY_USER} \
      --gid=${ENVOY_USER_GID} \
      --system
    sudo adduser ${ENVOY_USER} \
      --uid=${ENVOY_USER_UID} \
      --gid=${ENVOY_USER_GID} \
      --home=${ENVOY_USER_HOME} \
      --disabled-login \
      --system
    # Download and extract the Cloud Service Mesh tar.gz file
    cd ${ENVOY_USER_HOME}
    sudo curl -sL https://storage.googleapis.com/traffic-director/traffic-director-xdsv3.tar.gz -o traffic-director-xdsv3.tar.gz
    sudo tar -xvzf traffic-director-xdsv3.tar.gz traffic-director-xdsv3/bootstrap_template.yaml \
      -C bootstrap_template.yaml \
      --strip-components 1
    sudo tar -xvzf traffic-director-xdsv3.tar.gz traffic-director-xdsv3/iptables.sh \
      -C iptables.sh \
      --strip-components 1
    sudo rm traffic-director-xdsv3.tar.gz
    
    # Generate Envoy bootstrap configuration
    cat "${BOOTSTRAP_TEMPLATE}" \
      | sed -e "s|ENVOY_NODE_ID|${ENVOY_NODE_ID}|g" \
      | sed -e "s|ENVOY_ZONE|${GCE_ZONE}|g" \
      | sed -e "s|VPC_NETWORK_NAME|${VPC_NETWORK_NAME}|g" \
      | sed -e "s|CONFIG_PROJECT_NUMBER|${GCP_PROJECT_NUMBER}|g" \
      | sed -e "s|ENVOY_PORT|${ENVOY_PORT}|g" \
      | sed -e "s|ENVOY_ADMIN_PORT|${ENVOY_ADMIN_PORT}|g" \
      | sed -e "s|XDS_SERVER_CERT|${ENVOY_XDS_SERVER_CERT}|g" \
      | sed -e "s|TRACING_ENABLED|${ENVOY_TRACING_ENABLED}|g" \
      | sed -e "s|ACCESSLOG_PATH|${ENVOY_ACCESS_LOG}|g" \
      | sed -e "s|BACKEND_INBOUND_PORTS|${BACKEND_INBOUND_PORTS}|g" \
      | sed -e "s|trafficdirector.googleapis.com|trafficdirector.${ENVOY_CONTROL_PLANE_REGION}.rep.googleapis.com|g" \
      | sudo tee "${ENVOY_CONFIG}"
    
    # Install Envoy binary
    wget -O envoy_key https://apt.envoyproxy.io/signing.key
    cat envoy_key | sudo gpg --dearmor > $(pwd)/envoy-keyring.gpg
    echo "deb [arch=$(dpkg --print-architecture) signed-by=$(pwd)/envoy-keyring.gpg] https://apt.envoyproxy.io bullseye main" | sudo tee /etc/apt/sources.list.d/envoy.list
    sudo apt-get update
    sudo apt-get install envoy
    
    # Run Envoy as systemd service
    sudo systemd-run --uid=${ENVOY_USER_UID} --gid=${ENVOY_USER_GID} \
      --working-directory=${ENVOY_USER_HOME} --unit=envoy.service \
      bash -c "/usr/bin/envoy --config-path ${ENVOY_CONFIG} | tee"
    
    # Configure iptables for traffic interception and redirection
    sudo ${ENVOY_USER_HOME}/iptables.sh \
      -p "${ENVOY_PORT}" \
      -u "${ENVOY_USER_UID}" \
      -g "${ENVOY_USER_GID}" \
      -m "REDIRECT" \
      -i "${INTERCEPTED_CIDRS}" \
      -x "${GCE_METADATA_SERVER}"
    

Compute VM gRPC xDS

전역 Cloud Service Mesh와 마찬가지로 gRPC 클라이언트는 리전 Cloud Service Mesh에 연결하는 방법을 알리기 위해 부트스트랩을 구성해야 합니다.

gRPC 부트스트랩 생성기를 사용하여 이 부트스트랩을 생성할 수 있습니다. 리전별 Cloud Service Mesh를 사용하도록 설정하려면 --xds-server-region라는 새 플래그를 지정합니다.

이 예시에서 xds-server-regionus-central1로 설정하면 리전별 Cloud Service Mesh 엔드포인트가 자동으로 결정됩니다. trafficdirector.us-central1.rep.googleapis.com:443.

K8s 수동 Envoy 삽입

수동 단계는 수동 Envoy 삽입을 사용하여 Google Kubernetes Engine 포드 설정을 기반으로 합니다. 하지만 수동 포드 삽입에 관한 섹션만 수정하면 됩니다.

  1. 제어 영역을 전역에서 리전으로 변경합니다.

    wget -q -O - https://storage.googleapis.com/traffic-director/demo/trafficdirector_client_new_api_sample_xdsv3.yaml
    
    sed -i "s/PROJECT_NUMBER/PROJECT_NUMBER/g" trafficdirector_client_new_api_sample_xdsv3.yaml
    
    sed -i "s/MESH_NAME/MESH_NAME/g" trafficdirector_client_new_api_sample_xdsv3.yaml
    
    sed -i "s|trafficdirector.googleapis.com|trafficdirector.${REGION}.rep.googleapis.com|g" trafficdirector_client_new_api_sample_xdsv3.yaml
    
    sed -i "s|gcr.io/google-containers/busybox|busybox:stable|g" trafficdirector_client_new_api_sample_xdsv3.yaml
    
    1. 변경사항을 적용합니다.

      kubectl apply -f trafficdirector_client_new_api_sample_xdsv3.yaml
        ```
      

설정 가이드

이 섹션에서는 5가지 독립적인 구성 및 배포 모델을 다룹니다. 이는 모두 기존 전역 서비스 라우팅 API 설정 가이드의 리전화된 버전입니다.

리전 GRPCRoute 및 리전 Cloud Service Mesh로 프록시리스 gRPC 서비스 구성

이 섹션에서는 리전 Cloud Service Mesh 및 리전 GRPCRoute 리소스를 사용하여 프록시리스 gRPC 서비스 메시를 구성하는 방법을 설명합니다.

이 가이드의 모든 예시를 명령줄에 복사하여 붙여넣을 수 있도록 구성하는 Google Cloud 프로젝트 번호를 저장합니다.

export PROJECT="PROJECT_NUMBER"
export REGION="us-central1"
export ZONE="us-central1-a"

여기에서 PROJECT_NUMBER를 프로젝트 번호로 바꿉니다.

원하는 경우 다음을 바꿀 수 있습니다.

  • us-central1을 사용하려는 다른 리전으로 바꿉니다.
  • us-central1-a을 사용하려는 다른 영역으로 바꿉니다.
  • default을 다른 VPC_NAME으로 바꿉니다.

메시 구성

프록시리스 gRPC 애플리케이션이 xds://hostname에 연결되면 gRPC 클라이언트 라이브러리가 Cloud Service Mesh에 연결을 설정하여 호스트 이름에 대한 요청을 라우팅하는 데 필요한 라우팅 구성을 가져옵니다.

  1. 메시 사양을 만들고 mesh.yaml 파일에 저장합니다.

    cat <<EOF > mesh.yaml
    name: grpc-mesh
    EOF
    
  2. mesh.yaml 사양을 사용하여 메시를 만듭니다.

    gcloud network-services meshes import grpc-mesh \
        --source=mesh.yaml \
        --location=${REGION}
    

    리전 메시가 생성되면 Cloud Service Mesh가 구성을 제공할 준비가 됩니다. 하지만 아직 정의된 서비스가 없으므로 구성이 비어 있습니다.

gRPC 서비스 구성

데모를 위해 포트 50051에서 gRPC 프로토콜을 사용하여 hello world를 제공하는 자동 확장 VM(관리형 인스턴스 그룹(MIG) 사용)으로 리전 백엔드 서비스를 만듭니다.

  1. 포트 50051에 노출된 helloworld gRPC 서비스로 Compute Engine VM 인스턴스 템플릿을 만듭니다.

    gcloud compute instance-templates create grpc-td-vm-template \
      --scopes=https://www.googleapis.com/auth/cloud-platform \
      --tags=allow-health-checks \
      --image-family=debian-11 \
      --image-project=debian-cloud \
      --metadata-from-file=startup-script=<(echo '#! /bin/bash
    set -e
    cd /root
    sudo apt-get update -y
    sudo apt-get install -y openjdk-11-jdk-headless
    curl -L https://github.com/grpc/grpc-java/archive/v1.38.0.tar.gz | tar -xz
    cd grpc-java-1.38.0/examples/example-hostname
    ../gradlew --no-daemon installDist
    # Server listens on 50051
    sudo systemd-run ./build/install/hostname-server/bin/hostname-server')
    
  2. 템플릿을 기반으로 MIG를 만듭니다.

    gcloud compute instance-groups managed create grpc-td-mig-us-central1 \
      --zone=${ZONE} \
      --size=2 \
      --template=grpc-td-vm-template
    
  3. gRPC 서비스의 이름이 지정된 포트를 구성합니다. 이 포트는 gRPC 서비스가 요청을 리슨하도록 구성된 포트입니다.

    gcloud compute instance-groups set-named-ports grpc-td-mig-us-central1 \
      --named-ports=grpc-helloworld-port:50051 \
      --zone=${ZONE}
    

    이 예에서 포트는 50051입니다.

  4. gRPC 상태 점검을 만듭니다.

    gcloud compute health-checks create grpc grpc-helloworld-health-check \
      --use-serving-port --region=${REGION}
    

    서비스는 gRPC 상태 점검이 제대로 작동할 수 있도록 gRPC 상태 점검 프로토콜을 구현해야 합니다. 자세한 내용은 상태 확인 만들기를 참고하세요.

  5. 네트워크 인스턴스에 들어오는 상태 점검 연결을 허용하는 방화벽 규칙을 만듭니다.

    gcloud compute firewall-rules create grpc-vm-allow-health-checks \
      --network default --action allow --direction INGRESS \
      --source-ranges 35.191.0.0/16,209.85.152.0/22,209.85.204.0/22 \
      --target-tags allow-health-checks \
      --rules tcp:50051
    
  6. 부하 분산 스키마가 INTERNAL_SELF_MANAGED인 리전 백엔드 서비스를 만들고, 앞서 만든 상태 점검 및 관리형 인스턴스 그룹을 백엔드 서비스에 추가합니다. 지정된 포트 이름의 포트는 관리형 인스턴스 그룹의 VM에 연결하는 데 사용됩니다.

    gcloud compute backend-services create grpc-helloworld-service \
        --load-balancing-scheme=INTERNAL_SELF_MANAGED \
        --protocol=GRPC \
        --port-name=grpc-helloworld-port \
      --health-checks="https://www.googleapis.com/compute/v1/projects/${PROJECT}/regions/${REGION}/healthChecks/grpc-helloworld-health-check" \
        --region=${REGION}
    
  7. BackendService에 관리형 인스턴스 그룹을 추가합니다.

    gcloud compute backend-services add-backend grpc-helloworld-service \
      --instance-group=grpc-td-mig-us-central1 \
      --instance-group-zone=${ZONE} \
      --region=${REGION}
    

리전 GRPCRoute로 라우팅 설정

이제 리전 메시와 gRPC 서버 서비스가 구성됩니다. 이제 필요한 라우팅을 설정할 수 있습니다.

  1. 리전별 GRPCRoute 사양을 만들고 grpc_route.yaml 파일에 저장합니다.

    cat <<EOF > grpc_route.yaml
    name: helloworld-grpc-route
    hostnames:
    - helloworld-gce
    meshes:
    - projects/${PROJECT_NUMBER}/locations/${REGION}/meshes/grpc-mesh
    rules:
    - action:
        destinations:
        - serviceName: projects/${PROJECT_NUMBER}/locations/${REGION}/backendServices/grpc-helloworld-service
    EOF
    
  2. grpc_route.yaml 사양을 사용하여 리전별 GRPCRoute를 만듭니다.

    gcloud network-services grpc-routes import helloworld-grpc-route \
        --source=grpc_route.yaml \
        --location=${REGION}
    

    이제 Cloud Service Mesh는 관리형 인스턴스 그룹의 백엔드에서 gRPC 경로에 지정된 서비스의 트래픽을 부하 분산하도록 구성됩니다.

gRPC 클라이언트 서비스 만들기

구성을 확인하려면 프록시리스 gRPC 데이터 플레인으로 클라이언트 애플리케이션을 인스턴스화합니다. 이 애플리케이션은 부트스트랩 파일에서 메시의 이름을 지정해야 합니다.

구성되면 이 애플리케이션은 xds:///helloworld-gce 서비스 URI를 사용하여 helloworld-gce와 연결된 인스턴스 또는 엔드포인트에 요청을 보낼 수 있습니다.

다음 예시에서는 grpcurl 도구를 사용하여 gRPC 서비스를 테스트합니다.

  1. 클라이언트 VM을 만듭니다.

    gcloud compute instances create grpc-client \
      --zone=${ZONE}\
      --scopes=https://www.googleapis.com/auth/cloud-platform \
      --image-family=debian-11 \
      --image-project=debian-cloud \
      --metadata-from-file=startup-script=<(echo '#! /bin/bash
    set -ex
    export PROJECT=PROJECT_NUMBER
    export REGION=us-central1
    export GRPC_XDS_BOOTSTRAP=/run/td-grpc-bootstrap.json
    echo export GRPC_XDS_BOOTSTRAP=$GRPC_XDS_BOOTSTRAP | sudo tee /etc/profile.d/grpc-xds-bootstrap.sh
    curl -L https://storage.googleapis.com/traffic-director/td-grpc-bootstrap-0.18.0.tar.gz | tar -xz
    ./td-grpc-bootstrap-0.18.0/td-grpc-bootstrap --config-mesh=grpc-mesh --xds-server-uri=trafficdirector.${REGION}.rep.googleapis.com:443 --gcp-project-number=${PROJECT} | sudo tee $GRPC_XDS_BOOTSTRAP
    sudo sed -i "s|\"authorities\": {|\"authorities\": {\n    \"traffic-director.${REGION}.xds.googleapis.com\": {\"xds_servers\":[{\"server_uri\": \"trafficdirector.${REGION}.rep.googleapis.com:443\", \"channel_creds\": [ { \"type\": \"google_default\" } ], \"server_features\": [ \"xds_v3\", \"ignore_resource_deletion\" ]}], \"client_listener_resource_name_template\": \"xdstp://traffic-director.${REGION}.xds.googleapis.com/envoy.config.listener.v3.Listener/${PROJECT}/mesh:grpc-mesh/%s\"},|g" $GRPC_XDS_BOOTSTRAP
    sudo sed -i "s|\"client_default_listener_resource_name_template\": \"xdstp://traffic-director-global.xds.googleapis.com|\"client_default_listener_resource_name_template\": \"xdstp://traffic-director.${REGION}.xds.googleapis.com|g" $GRPC_XDS_BOOTSTRAP')
    

환경 변수 및 부트스트랩 파일 설정

클라이언트 애플리케이션에는 부트스트랩 구성 파일이 필요합니다. 이전 섹션의 시작 스크립트는 GRPC_XDS_BOOTSTRAP 환경 변수를 설정하고 도우미 스크립트를 사용하여 부트스트랩 파일을 생성합니다. Compute Engine VM 인스턴스에 대한 이러한 세부정보를 알고 있는 메타데이터 서버에서 생성된 부트스트랩 파일에 있는 TRAFFICDIRECTOR_GCP_PROJECT_NUMBER 및 영역의 값을 가져옵니다.

-gcp-project-number 옵션을 사용하여 이러한 값을 도우미 스크립트에 수동으로 제공할 수 있습니다. -config-mesh-experimental 옵션을 사용하여 메시 리소스와 일치하는 메시 이름을 제공해야 합니다.

  1. 구성을 확인하려면 클라이언트에 로그인합니다.

    gcloud compute ssh grpc-client --zone=${ZONE}
    
  2. grpcurl 도구를 다운로드하고 설치합니다.

    curl -L https://github.com/fullstorydev/grpcurl/releases/download/v1.9.3/grpcurl_1.9.3_linux_x86_64.tar.gz | tar -xz
    
  3. xds:///helloworld-gce를 서비스 URI로, helloworld.Greeter/SayHello를 호출할 서비스 이름과 메서드로 사용하여 grpcurl 도구를 실행합니다.

    ./grpcurl --plaintext \
      -d '{"name": "world"}' \
      xds:///helloworld-gce helloworld.Greeter/SayHello
    

    SayHello 메서드의 매개변수는 -d 옵션을 사용하여 전달됩니다.

    INSTANCE_NAME이 VM 인스턴스의 이름인 다음과 비슷한 출력이 표시됩니다.

    Greeting: Hello world, from INSTANCE_HOSTNAME
    

이렇게 하면 프록시리스 gRPC 클라이언트가 성공적으로 Cloud Service Mesh에 연결되고 xDS 이름 리졸버를 사용하여 helloworld-gce 서비스의 백엔드를 알아봤는지 확인할 수 있습니다. 클라이언트는 IP 주소 정보를 확인하거나 DNS 확인을 수행할 필요 없이 서비스의 백엔드 중 하나에 요청을 보냈습니다.

리전 HTTPRoute 및 리전 메시를 사용하여 HTTP 서비스로 Envoy 사이드카 프록시 구성

이 섹션에서는 리전 메시 및 리전 HTTPRoute 리소스를 사용하여 Envoy 프록시 기반 서비스 메시를 구성하는 방법을 설명합니다.

이 가이드의 모든 예시를 명령줄에 복사하여 붙여넣을 수 있도록 구성하는 Google Cloud 프로젝트 번호를 저장합니다.

export PROJECT_ID="PROJECT_ID"
export PROJECT="PROJECT_NUMBER"
export REGION="us-central1"
export ZONE="us-central1-a"

다음을 바꿉니다.

  • PROJECT_ID를 프로젝트 ID로 바꿉니다.
  • PROJECT_NUMBER를 프로젝트 번호로 바꿉니다.

원하는 경우 다음을 바꿀 수 있습니다.

  • us-central1을 사용하려는 다른 리전으로 바꿉니다.
  • us-central1-a을 사용하려는 다른 영역으로 바꿉니다.

메시 구성

사이드카 Envoy 프록시가 Cloud Service Mesh에서 서비스 라우팅 구성을 수신합니다. 사이드카는 구성된 특정 서비스 메시를 식별하기 위해 리전 메시 리소스의 이름을 표시합니다. Cloud Service Mesh에서 수신한 라우팅 구성은 라우트 리소스에 구성된 호스트 이름이나 헤더와 같은 요청 매개변수에 따라 사이드카 프록시를 통과하는 트래픽을 다양한 리전 백엔드 서비스로 전달하는 데 사용됩니다.

메시 이름은 사이드카 프록시가 이 메시와 연결된 구성을 요청하는 데 사용하는 키입니다.

  1. 리전별 메시 사양을 만들고 mesh.yaml 파일에 저장합니다.

    cat <<EOF > mesh.yaml
    name: sidecar-mesh
    EOF
    

    지정하지 않으면 가로채기 포트의 기본값은 15001입니다.

  2. mesh.yaml 사양을 사용하여 리전 메시를 만듭니다.

    gcloud network-services meshes import sidecar-mesh \
        --source=mesh.yaml \
        --location=${REGION}
    

    리전 메시가 생성되면 Cloud Service Mesh가 구성을 제공할 준비가 됩니다. 하지만 아직 정의된 서비스가 없으므로 구성이 비어 있습니다.

HTTP 서버 구성

데모를 위해 포트 80에서 gRPC 프로토콜을 사용하여 'hello world'를 제공하는 자동 확장 VM(관리형 인스턴스 그룹(MIG) 사용)으로 리전 백엔드 서비스를 만듭니다.

  1. 포트 80에 노출된 helloworld HTTP 서비스로 Compute Engine VM 인스턴스 템플릿을 만듭니다.

    gcloud compute instance-templates create td-httpd-vm-template \
      --scopes=https://www.googleapis.com/auth/cloud-platform \
      --tags=http-td-server \
      --image-family=debian-11 \
      --image-project=debian-cloud \
      --metadata=startup-script="#! /bin/bash
    
    sudo apt-get update -y
    sudo apt-get install apache2 -y
    sudo service apache2 restart
    echo '<!doctype html><html><body><h1>'\`/bin/hostname\`'</h1></body></html>' | sudo tee /var/www/html/index.html"
    
  2. 템플릿을 기반으로 MIG를 만듭니다.

    gcloud compute instance-groups managed create http-td-mig-us-central1 \
      --zone=${ZONE} \
      --size=2 \
      --template=td-httpd-vm-template
    
  3. 상태 점검을 만듭니다.

    gcloud compute health-checks create http http-helloworld-health-check --region=${REGION}
    
  4. 네트워크 인스턴스에 들어오는 상태 점검 연결을 허용하는 방화벽 규칙을 만듭니다.

    gcloud compute firewall-rules create http-vm-allow-health-checks \
      --network default --action allow --direction INGRESS \
      --source-ranges 35.191.0.0/16,209.85.152.0/22,209.85.204.0/22 \
      --target-tags http-td-server \
      --rules tcp:80
    
  5. 부하 분산 스키마가 INTERNAL_SELF_MANAGED인 리전 백엔드 서비스를 만듭니다.

    gcloud compute backend-services create http-helloworld-service \
        --load-balancing-scheme=INTERNAL_SELF_MANAGED \
        --protocol=HTTP \
    --health-checks="https://www.googleapis.com/compute/v1/projects/${PROJECT}/regions/${REGION}/healthChecks/http-helloworld-health-check" \
        --region=${REGION}
    
  6. 백엔드 서비스에 상태 점검과 관리형 또는 비관리형 인스턴스 그룹을 추가합니다.

    gcloud compute backend-services add-backend http-helloworld-service \
      --instance-group=http-td-mig-us-central1 \
      --instance-group-zone=${ZONE} \
      --region=${REGION}
    

    이 예시에서는 이전에 만든 샘플 HTTP 서비스를 실행하는 Compute Engine VM 템플릿과 함께 관리형 인스턴스 그룹을 사용합니다.

리전 HTTPRoute로 라우팅 설정

메시 리소스와 HTTP 서버가 구성됩니다. 이제 호스트 이름을 백엔드 서비스에 연결하는 HTTPRoute 리소스를 사용하여 연결할 수 있습니다.

  1. HTTPRoute 사양을 만들고 http_route.yaml로 저장합니다.

    cat <<EOF > http_route.yaml
    name: helloworld-http-route
    hostnames:
    - helloworld-gce
    meshes:
    - projects/${PROJECT_NUMBER}/locations/${REGION}/meshes/sidecar-mesh
    rules:
    - action:
        destinations:
        - serviceName: projects/${PROJECT_NUMBER}/locations/${REGION}/backendServices/http-helloworld-service
    EOF
    
  2. http_route.yaml 사양을 사용하여 HTTPRoute를 만듭니다.

    gcloud network-services http-routes import helloworld-http-route \
        --source=http_route.yaml \
        --location=${REGION}
    

    이제 Cloud Service Mesh는 관리형 인스턴스 그룹의 백엔드에서 HTTPRoute에 지정된 서비스의 트래픽을 부하 분산하도록 구성됩니다.

Envoy 사이드카로 HTTP 클라이언트 만들기

이 섹션에서는 Envoy 사이드카 프록시가 있는 클라이언트 VM을 인스턴스화하여 이전에 만든 Cloud Service Mesh 구성을 요청합니다. Google Cloud CLI 명령어의 mesh 매개변수는 이전에 생성된 메시 리소스를 참조합니다.

gcloud compute instance-templates create td-vm-template \
  --scopes=https://www.googleapis.com/auth/cloud-platform \
  --tags=http-td-tag,http-server,https-server \
  --image-family=debian-11 \
  --image-project=debian-cloud \
  --metadata=startup-script='#! /usr/bin/env bash

# Set variables
export ENVOY_CONTROL_PLANE_REGION="us-central1"
export ENVOY_USER="envoy"
export ENVOY_USER_UID="1337"
export ENVOY_USER_GID="1337"
export ENVOY_USER_HOME="/opt/envoy"
export ENVOY_CONFIG="${ENVOY_USER_HOME}/config.yaml"
export ENVOY_PORT="15001"
export ENVOY_ADMIN_PORT="15000"
export ENVOY_TRACING_ENABLED="false"
export ENVOY_XDS_SERVER_CERT="/etc/ssl/certs/ca-certificates.crt"
export ENVOY_ACCESS_LOG="/dev/stdout"
export ENVOY_NODE_ID="$(cat /proc/sys/kernel/random/uuid)~$(hostname -i)"
export BOOTSTRAP_TEMPLATE="${ENVOY_USER_HOME}/bootstrap_template.yaml"
export GCE_METADATA_SERVER="169.254.169.254/32"
export INTERCEPTED_CIDRS="*"
export GCP_PROJECT_NUMBER=PROJECT_NUMBER
export VPC_NETWORK_NAME=mesh:sidecar-mesh
export GCE_ZONE=$(curl -sS -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/zone | cut -d"/" -f4)

# Create system user account for Envoy binary
sudo groupadd ${ENVOY_USER} \
  --gid=${ENVOY_USER_GID} \
  --system
sudo adduser ${ENVOY_USER} \
  --uid=${ENVOY_USER_UID} \
  --gid=${ENVOY_USER_GID} \
  --home=${ENVOY_USER_HOME} \
  --disabled-login \
  --system
# Download and extract the Cloud Service Mesh tar.gz file
cd ${ENVOY_USER_HOME}
sudo curl -sL https://storage.googleapis.com/traffic-director/traffic-director-xdsv3.tar.gz -o traffic-director-xdsv3.tar.gz
sudo tar -xvzf traffic-director-xdsv3.tar.gz traffic-director-xdsv3/bootstrap_template.yaml \
  -C bootstrap_template.yaml \
  --strip-components 1
sudo tar -xvzf traffic-director-xdsv3.tar.gz traffic-director-xdsv3/iptables.sh \
  -C iptables.sh \
  --strip-components 1
sudo rm traffic-director-xdsv3.tar.gz

# Generate Envoy bootstrap configuration
cat "${BOOTSTRAP_TEMPLATE}" \
  | sed -e "s|ENVOY_NODE_ID|${ENVOY_NODE_ID}|g" \
  | sed -e "s|ENVOY_ZONE|${GCE_ZONE}|g" \
  | sed -e "s|VPC_NETWORK_NAME|${VPC_NETWORK_NAME}|g" \
  | sed -e "s|CONFIG_PROJECT_NUMBER|${GCP_PROJECT_NUMBER}|g" \
  | sed -e "s|ENVOY_PORT|${ENVOY_PORT}|g" \
  | sed -e "s|ENVOY_ADMIN_PORT|${ENVOY_ADMIN_PORT}|g" \
  | sed -e "s|XDS_SERVER_CERT|${ENVOY_XDS_SERVER_CERT}|g" \
  | sed -e "s|TRACING_ENABLED|${ENVOY_TRACING_ENABLED}|g" \
  | sed -e "s|ACCESSLOG_PATH|${ENVOY_ACCESS_LOG}|g" \
  | sed -e "s|BACKEND_INBOUND_PORTS|${BACKEND_INBOUND_PORTS}|g" \
  | sed -e "s|trafficdirector.googleapis.com|trafficdirector.${ENVOY_CONTROL_PLANE_REGION}.rep.googleapis.com|g" \
  | sudo tee "${ENVOY_CONFIG}"

# Install Envoy binary
wget -O envoy_key https://apt.envoyproxy.io/signing.key
cat envoy_key | sudo gpg --dearmor > $(pwd)/envoy-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=$(pwd)/envoy-keyring.gpg] https://apt.envoyproxy.io bullseye main" | sudo tee /etc/apt/sources.list.d/envoy.list
sudo apt-get update
sudo apt-get install envoy

# Run Envoy as systemd service
sudo systemd-run --uid=${ENVOY_USER_UID} --gid=${ENVOY_USER_GID} \
  --working-directory=${ENVOY_USER_HOME} --unit=envoy.service \
  bash -c "/usr/bin/envoy --config-path ${ENVOY_CONFIG} | tee"

# Configure iptables for traffic interception and redirection
sudo ${ENVOY_USER_HOME}/iptables.sh \
  -p "${ENVOY_PORT}" \
 -u "${ENVOY_USER_UID}" \
  -g "${ENVOY_USER_GID}" \
  -m "REDIRECT" \
  -i "${INTERCEPTED_CIDRS}" \
  -x "${GCE_METADATA_SERVER}"
'

gcloud compute instances create td-vm-client \
  --zone=${ZONE} \
  --source-instance-template td-vm-template
  1. 생성된 VM에 로그인합니다.

    gcloud compute ssh td-vm-client --zone=${ZONE}
    
  2. 생성된 테스트 서비스에 대한 HTTP 연결을 확인합니다.

    curl -H "Host: helloworld-gce" http://10.0.0.1/
    

    이 명령어는 관리형 인스턴스 그룹에 있는 VM 중 하나에서 응답을 반환하고 호스트 이름이 콘솔에 출력됩니다.

리전 TCPRoute로 TCP 서비스 구성

이 구성 흐름은 백엔드 서비스가 TCP 서비스를 제공하고 HTTP 프로토콜 대신 TCP/IP 매개변수를 기반으로 하는 라우팅이 사용된다는 점을 제외하고 HTTP 서비스로 Envoy 프록시 설정과 매우 유사합니다.

편의를 위해 구성하는 Google Cloud 프로젝트 번호를 저장하여 이 가이드의 모든 예시를 명령줄에 복사하여 붙여넣을 수 있습니다.

export PROJECT_ID="PROJECT_ID"
export PROJECT="PROJECT_NUMBER"
export REGION="us-central1"
export ZONE="us-central1-a"

다음을 바꿉니다.

  • PROJECT_ID를 프로젝트 ID로 바꿉니다.
  • PROJECT_NUMBER를 프로젝트 번호로 바꿉니다.

원하는 경우 다음을 바꿀 수 있습니다.

  • us-central1을 사용하려는 다른 리전으로 바꿉니다.
  • us-central1-a을 사용하려는 다른 영역으로 바꿉니다.

메시 구성

  1. 리전별 메시 사양을 만들고 mesh.yaml 파일에 저장합니다.

    cat <<EOF > mesh.yaml
    name: sidecar-mesh
    EOF
    
  2. mesh.yaml 사양을 사용하여 리전 메시를 만듭니다.

    gcloud network-services meshes import sidecar-mesh \
        --source=mesh.yaml \
        --location=${REGION}
    

TCP 서버 구성

데모를 위해 포트 10000에서 gRPC 프로토콜을 사용하여 'hello world'를 제공하는 자동 확장 VM (관리형 인스턴스 그룹 - MIG 사용)이 있는 리전 백엔드 서비스를 만듭니다.

  1. netcat 유틸리티를 사용하여 포트 10000에서 테스트 서비스를 사용하여 Compute Engine VM 인스턴스 템플릿을 만듭니다.

    gcloud compute instance-templates create tcp-td-vm-template \
      --scopes=https://www.googleapis.com/auth/cloud-platform \
      --tags=allow-health-checks \
      --image-family=debian-11 \
      --image-project=debian-cloud \
      --metadata=startup-script="#! /bin/bash
    sudo apt-get update -y
    sudo apt-get install netcat -y
    while true;
      do echo 'Hello from TCP service' | nc -l -s 0.0.0.0 -p 10000;
    done &"
    
  2. 템플릿을 기반으로 MIG를 만듭니다.

    gcloud compute instance-groups managed create tcp-td-mig-us-central1 \
      --zone=${ZONE} \
      --size=1 \
      --template=tcp-td-vm-template
    
  3. 생성된 관리형 인스턴스 그룹에서 이름이 지정된 포트를 port 10000로 설정합니다.

    gcloud compute instance-groups set-named-ports tcp-td-mig-us-central1 \
      --zone=${ZONE} --named-ports=tcp:10000
    
  4. 리전 상태 점검을 만듭니다.

    gcloud compute health-checks create tcp tcp-helloworld-health-check --port 10000 --region=${REGION}
    
  5. 네트워크 인스턴스에 들어오는 상태 점검 연결을 허용하는 방화벽 규칙을 만듭니다.

    gcloud compute firewall-rules create tcp-vm-allow-health-checks \
      --network default --action allow --direction INGRESS \
      --source-ranges 35.191.0.0/16,209.85.152.0/22,209.85.204.0/22 \
      --target-tags allow-health-checks \
      --rules tcp:10000
    
  6. 부하 분산 스킴이 INTERNAL_SELF_MANAGED인 리전 백엔드 서비스를 만들고 백엔드 서비스에 상태 확인과 관리형 또는 비관리형 인스턴스 그룹을 추가합니다.

    gcloud compute backend-services create tcp-helloworld-service \
        --region=${REGION} \
        --load-balancing-scheme=INTERNAL_SELF_MANAGED \
        --protocol=TCP \
        --port-name=tcp \
        --health-checks="https://www.googleapis.com/compute/v1/projects/${PROJECT}/regions/${REGION}/healthChecks/tcp-helloworld-health-check"
    
  7. MIG를 BackendService에 추가합니다.

    gcloud compute backend-services add-backend tcp-helloworld-service \
      --instance-group tcp-td-mig-us-central1 \
      --instance-group-zone=${ZONE} \
      --region=${REGION}
    

리전 TCPRoute로 라우팅 설정

  1. TCPRoute 사양을 만들고 tcp_route.yaml 파일에 저장합니다.

    cat <<EOF > tcp_route.yaml
    name: helloworld-tcp-route
    meshes:
    - projects/$PROJECT_NUMBER/locations/$REGION/meshes/sidecar-mesh
    rules:
    - action:
        destinations:
        - serviceName: projects/$PROJECT_NUMBER/locations/$REGION/backendServices/tcp-helloworld-service
      matches:
      - address: '10.0.0.1/32'
        port: '10000'
    EOF
    
  2. tcp_route.yaml 사양을 사용하여 TCPRoute를 만듭니다.

    gcloud network-services tcp-routes import helloworld-tcp-route \
        --source=tcp_route.yaml \
        --location=${REGION}
    

Envoy 사이드카로 TCP 클라이언트 만들기

  1. Cloud Service Mesh에 연결된 Envoy로 VM을 만듭니다.

    gcloud compute instance-templates create td-vm-template \
      --scopes=https://www.googleapis.com/auth/cloud-platform \
      --tags=http-td-tag,http-server,https-server \
      --image-family=debian-11 \
      --image-project=debian-cloud \
      --metadata=startup-script='#! /usr/bin/env bash
    
    # Set variables
    export ENVOY_CONTROL_PLANE_REGION="us-central1"
    export ENVOY_USER="envoy"
    export ENVOY_USER_UID="1337"
    export ENVOY_USER_GID="1337"
    export ENVOY_USER_HOME="/opt/envoy"
    export ENVOY_CONFIG="${ENVOY_USER_HOME}/config.yaml"
    export ENVOY_PORT="15001"
    export ENVOY_ADMIN_PORT="15000"
    export ENVOY_TRACING_ENABLED="false"
    export ENVOY_XDS_SERVER_CERT="/etc/ssl/certs/ca-certificates.crt"
    export ENVOY_ACCESS_LOG="/dev/stdout"
    export ENVOY_NODE_ID="$(cat /proc/sys/kernel/random/uuid)~$(hostname -i)"
    export BOOTSTRAP_TEMPLATE="${ENVOY_USER_HOME}/bootstrap_template.yaml"
    export GCE_METADATA_SERVER="169.254.169.254/32"
    export INTERCEPTED_CIDRS="*"
    export GCP_PROJECT_NUMBER=PROJECT_NUMBER
    export VPC_NETWORK_NAME=mesh:sidecar-mesh
    
    export GCE_ZONE=$(curl -sS -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/zone | cut -d"/" -f4)
    
    # Create system user account for Envoy binary
    sudo groupadd ${ENVOY_USER} \
      --gid=${ENVOY_USER_GID} \
      --system
    sudo adduser ${ENVOY_USER} \
      --uid=${ENVOY_USER_UID} \
      --gid=${ENVOY_USER_GID} \
      --home=${ENVOY_USER_HOME} \
      --disabled-login \
      --system
    # Download and extract the Cloud Service Mesh tar.gz file
    cd ${ENVOY_USER_HOME}
    sudo curl -sL https://storage.googleapis.com/traffic-director/traffic-director-xdsv3.tar.gz -o traffic-director-xdsv3.tar.gz
    sudo tar -xvzf traffic-director-xdsv3.tar.gz traffic-director-xdsv3/bootstrap_template.yaml \
      -C bootstrap_template.yaml \
      --strip-components 1
    sudo tar -xvzf traffic-director-xdsv3.tar.gz traffic-director-xdsv3/iptables.sh \
      -C iptables.sh \
      --strip-components 1
    sudo rm traffic-director-xdsv3.tar.gz
    
    # Generate Envoy bootstrap configuration
    cat "${BOOTSTRAP_TEMPLATE}" \
      | sed -e "s|ENVOY_NODE_ID|${ENVOY_NODE_ID}|g" \
      | sed -e "s|ENVOY_ZONE|${GCE_ZONE}|g" \
      | sed -e "s|VPC_NETWORK_NAME|${VPC_NETWORK_NAME}|g" \
      | sed -e "s|CONFIG_PROJECT_NUMBER|${GCP_PROJECT_NUMBER}|g" \
      | sed -e "s|ENVOY_PORT|${ENVOY_PORT}|g" \
      | sed -e "s|ENVOY_ADMIN_PORT|${ENVOY_ADMIN_PORT}|g" \
      | sed -e "s|XDS_SERVER_CERT|${ENVOY_XDS_SERVER_CERT}|g" \
      | sed -e "s|TRACING_ENABLED|${ENVOY_TRACING_ENABLED}|g" \
      | sed -e "s|ACCESSLOG_PATH|${ENVOY_ACCESS_LOG}|g" \
      | sed -e "s|BACKEND_INBOUND_PORTS|${BACKEND_INBOUND_PORTS}|g" \
      | sed -e "s|trafficdirector.googleapis.com|trafficdirector.${ENVOY_CONTROL_PLANE_REGION}.rep.googleapis.com|g" \
      | sudo tee "${ENVOY_CONFIG}"
    
    # Install Envoy binary
    wget -O envoy_key https://apt.envoyproxy.io/signing.key
    cat envoy_key | sudo gpg --dearmor > $(pwd)/envoy-keyring.gpg
    echo "deb [arch=$(dpkg --print-architecture) signed-by=$(pwd)/envoy-keyring.gpg] https://apt.envoyproxy.io bullseye main" | sudo tee /etc/apt/sources.list.d/envoy.list
    sudo apt-get update
    sudo apt-get install envoy
    
    # Run Envoy as systemd service
    sudo systemd-run --uid=${ENVOY_USER_UID} --gid=${ENVOY_USER_GID} \
      --working-directory=${ENVOY_USER_HOME} --unit=envoy.service \
      bash -c "/usr/bin/envoy --config-path ${ENVOY_CONFIG} | tee"
    
    # Configure iptables for traffic interception and redirection
    sudo ${ENVOY_USER_HOME}/iptables.sh \
      -p "${ENVOY_PORT}" \
    -u "${ENVOY_USER_UID}" \
      -g "${ENVOY_USER_GID}" \
      -m "REDIRECT" \
      -i "${INTERCEPTED_CIDRS}" \
      -x "${GCE_METADATA_SERVER}"
    '
    
    gcloud compute instances create td-vm-client \
      --zone=${ZONE} \
      --source-instance-template td-vm-template
    
  2. 생성된 VM에 로그인합니다.

    gcloud compute ssh td-vm-client --zone=${ZONE}
    
  3. 생성된 테스트 서비스와의 연결을 확인합니다.

    curl 10.0.0.1:10000 --http0.9 -v
    

    Hello from TCP service 텍스트가 반환되고 원격 VM에서 실행되는 netcat 서비스에서 입력한 텍스트가 다시 반환되는 것을 확인할 수 있습니다.

호스트 프로젝트의 리전 메시 구성

프로젝트를 호스트 프로젝트로 지정합니다. 이 프로젝트에서 메시를 생성/업데이트/삭제할 권한이 있는 모든 서비스 계정은 이 프로젝트의 지역 메시에 연결된 라우팅 구성을 제어할 수 있습니다.

  1. 예시 전체에서 사용할 변수를 정의합니다.

    export REGION="us-central1"
    

    원하는 경우 us-central1을 사용하려는 다른 리전으로 바꿀 수 있습니다.

  2. 메시 사양을 만들고 mesh.yaml 파일에 저장합니다.

    cat <<EOF > mesh.yaml
    name: shared-mesh
    EOF
    
  3. 필요한 구성으로 이 프로젝트에서 메시 리소스를 정의합니다.

    gcloud network-services meshes import shared-mesh \
        --source=mesh.yaml \
        --location=${REGION}
    

    이 메시 리소스의 전체 URI를 기록해 둡니다. 서비스 소유자는 나중에 이 메시지에 경로를 연결할 때 이 정보가 필요합니다.

  4. 이 메시와 서비스 정보를 이 메시에 연결할 수 있어야 하는 교차 프로젝트 서비스 계정에 networkservices.meshes.use IAM 권한을 부여합니다.

    gcloud projects add-iam-policy-binding HOST_PROJECT_NUMBER --member='HTTP_ROUTE_SERVICE_OWNER_ACCOUNT' --role='roles/compute.networkAdmin'
    

    이제 networkservices.meshes.use 권한이 부여된 모든 서비스 소유자는 이 메시지에 라우팅 규칙을 추가할 수 있습니다.

서비스 프로젝트의 경로 구성

각 서비스 소유자는 HTTP 서비스로 Envoy 프록시 설정과 비슷하게 해당 프로젝트에 리전별 백엔드 서비스 및 리전별 경로 리소스를 만들어야 합니다. 유일한 차이점은 각 HTTPRoute/GRPCRoute/TCPRoute의 meshes 필드에 호스트 프로젝트의 메시 리소스 URI가 있다는 점입니다.

  1. sharedvpc-http-route를 만듭니다.

    echo "name: sharedvpc-http-route
    hostnames:
    - helloworld-gce
    meshes:
    - /projects/HOST_PROJECT_NUMBER/locations/${REGION}/meshes/shared-mesh
    rules:
    - action:
        destinations:
        - serviceName: \"SERVICE_URL\"" | \
    gcloud network-services http-routes import sharedvpc-http-route \
        --source=- \
        --location=${REGION}
    

서비스 프로젝트에서 클라이언트 서비스 구성

서비스 프로젝트에 있는 Cloud Service Mesh 클라이언트 (Envoy 프록시 또는 프록시리스)를 구성할 때는 부트스트랩 구성에서 메시 리소스가 있는 프로젝트 번호와 메시 이름을 지정해야 합니다.

TRAFFICDIRECTOR_GCP_PROJECT_NUMBER=HOST_PROJECT_NUMBER
TRAFFICDIRECTOR_MESH_NAME=MESH_NAME

게이트웨이 TLS 라우팅

이 섹션에서는 리전 게이트웨이 및 리전 TLSRoute 리소스를 사용하여 Envoy 프록시 기반 인그레스 게이트웨이를 설정하는 방법을 보여줍니다.

리전 외부 패스 스루 네트워크 부하 분산기는 인그레스 게이트웨이로 작동하는 Envoy 프록시로 트래픽을 전달합니다. Envoy 프록시는 TLS 패스스루 라우팅을 사용하고 백엔드 VM 인스턴스에서 실행되는 HTTPS 서버로 트래픽을 전달합니다.

예제 전체에서 사용할 변수를 정의합니다.

export PROJECT_ID="PROJECT_ID"
export PROJECT_NUMBER="PROJECT_NUMBER"
export REGION="us-central1"
export ZONE="us-central1-b"
export NETWORK_NAME = "default"

다음을 바꿉니다. default

  • PROJECT_ID를 프로젝트 ID로 바꿉니다.
  • PROJECT_NUMBER를 프로젝트 번호로 바꿉니다.

원하는 경우 다음을 바꿀 수 있습니다.

  • us-central1을 사용하려는 다른 리전으로 바꿉니다.
  • us-central1-b을 사용하려는 다른 영역으로 바꿉니다.
  • default을 사용하려는 다른 네트워크 이름으로 바꿉니다.

다중 프로젝트 공유 VPC 환경에서 리전 메시 및 리전 경로 리소스 교차 참조

서비스 메시 구성이 서로 다른 프로젝트에서 소유한 서비스로 구성되는 시나리오가 있습니다. 예를 들어 공유 VPC 또는 피어링된 VPC 배포에서 각 프로젝트 소유자가 이러한 서비스를 다른 모든 프로젝트에서 사용할 수 있도록 자체 서비스 집합을 정의할 수 있습니다.

이 구성은 여러 프로젝트에 정의된 여러 리소스가 조합되어 프록시 또는 프록시리스 클라이언트에 제공될 수 있는 단일 구성을 형성하기 때문에 '교차 프로젝트' 구성이라고 합니다.

방화벽 규칙 구성

  1. 모든 소스의 트래픽을 허용하도록 방화벽 규칙을 구성합니다. 포트 및 소스 IP 주소 범위에 대한 명령어를 수정합니다.

    gcloud compute firewall-rules create allow-gateway-health-checks \
    --network=${NETWORK_NAME} \
    --direction=INGRESS \
    --action=ALLOW \
    --rules=tcp \
    --source-ranges="35.191.0.0/16,209.85.152.0/22,209.85.204.0/22" \
    --target-tags=gateway-proxy
    

IAM 권한 구성

  1. 게이트웨이 프록시에 대한 서비스 계정 ID를 만듭니다.

    gcloud iam service-accounts create gateway-proxy
    
  2. 필요한 IAM 역할을 서비스 계정 ID에 할당합니다.

    gcloud projects add-iam-policy-binding ${PROJECT_ID} \
      --member="serviceAccount:gateway-proxy@${PROJECT_ID}.iam.gserviceaccount.com" \
      --role="roles/trafficdirector.client"
    
    gcloud projects add-iam-policy-binding ${PROJECT_ID} \
      --member="serviceAccount:gateway-proxy@${PROJECT_ID}.iam.gserviceaccount.com" \
      --role="roles/logging.logWriter"
    

리전 게이트웨이를 구성합니다.

  1. gateway8443.yaml이라는 파일에 HTTP 트래픽의 게이트웨이 사양을 만듭니다.

    cat <<EOF > gateway8443.yaml
    name: gateway8443
    scope: gateway-proxy-8443
    ports:
    - 8443
    type: OPEN_MESH
    EOF
    
  2. gateway8443.yaml 사양을 사용하여 리전별 게이트웨이 리소스를 만듭니다.

    gcloud network-services gateways import gateway8443 \
        --source=gateway8443.yaml \
        --location=${REGION}
    

Envoy 프록시를 사용하여 관리형 인스턴스 그룹 만들기

이 섹션에서는 자동으로 배포된 Envoy 서비스 프록시를 실행하는 VM의 인스턴스 템플릿을 만듭니다. Envoy 범위가 gateway-proxy로 설정되었습니다. 제공 포트를 --service-proxy 플래그의 매개변수로 전달하지 마세요.

  1. Envoy 프록시를 사용하여 관리형 인스턴스 그룹을 만듭니다.

    gcloud beta compute instance-templates create gateway-proxy \
      --scopes=https://www.googleapis.com/auth/cloud-platform \
      --tags=gateway-proxy,http-td-tag,http-server,https-server \
      --image-family=debian-11 \
      --image-project=debian-cloud \
      --network-interface=network=${NETWORK_NAME} \
      --service-account="gateway-proxy@${PROJECT_ID}.iam.gserviceaccount.com" \
      --metadata=startup-script='#! /usr/bin/env bash
    
    # Set variables
    export ENVOY_CONTROL_PLANE_REGION="us-central1"
    export GCP_PROJECT_NUMBER=PROJECT_NUMBER
    export VPC_NETWORK_NAME=scope:gateway-proxy-8443
    export ENVOY_USER="envoy"
    export ENVOY_USER_UID="1337"
    export ENVOY_USER_GID="1337"
    export ENVOY_USER_HOME="/opt/envoy"
    export ENVOY_CONFIG="${ENVOY_USER_HOME}/config.yaml"
    export ENVOY_PORT="15001"
    export ENVOY_ADMIN_PORT="15000"
    export ENVOY_TRACING_ENABLED="false"
    export ENVOY_XDS_SERVER_CERT="/etc/ssl/certs/ca-certificates.crt"
    export ENVOY_ACCESS_LOG="/dev/stdout"
    export ENVOY_NODE_ID="$(cat /proc/sys/kernel/random/uuid)~$(hostname -i)"
    export BOOTSTRAP_TEMPLATE="${ENVOY_USER_HOME}/bootstrap_template.yaml"
    export GCE_METADATA_SERVER="169.254.169.254/32"
    export INTERCEPTED_CIDRS="*"
    
    export GCE_ZONE=$(curl -sS -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/zone | cut -d"/" -f4)
    
    # Create system user account for Envoy binary
    sudo groupadd ${ENVOY_USER} \
      --gid=${ENVOY_USER_GID} \
      --system
    sudo adduser ${ENVOY_USER} \
      --uid=${ENVOY_USER_UID} \
      --gid=${ENVOY_USER_GID} \
      --home=${ENVOY_USER_HOME} \
      --disabled-login \
      --system
    # Download and extract the Cloud Service Mesh tar.gz file
    cd ${ENVOY_USER_HOME}
    sudo curl -sL https://storage.googleapis.com/traffic-director/traffic-director-xdsv3.tar.gz -o traffic-director-xdsv3.tar.gz
    sudo tar -xvzf traffic-director-xdsv3.tar.gz traffic-director-xdsv3/bootstrap_template.yaml \
      -C bootstrap_template.yaml \
      --strip-components 1
    sudo tar -xvzf traffic-director-xdsv3.tar.gz traffic-director-xdsv3/iptables.sh \
      -C iptables.sh \
      --strip-components 1
    sudo rm traffic-director-xdsv3.tar.gz
    
    # Generate Envoy bootstrap configuration
    cat "${BOOTSTRAP_TEMPLATE}" \
      | sed -e "s|ENVOY_NODE_ID|${ENVOY_NODE_ID}|g" \
      | sed -e "s|ENVOY_ZONE|${GCE_ZONE}|g" \
      | sed -e "s|VPC_NETWORK_NAME|${VPC_NETWORK_NAME}|g" \
      | sed -e "s|CONFIG_PROJECT_NUMBER|${GCP_PROJECT_NUMBER}|g" \
      | sed -e "s|ENVOY_PORT|${ENVOY_PORT}|g" \
      | sed -e "s|ENVOY_ADMIN_PORT|${ENVOY_ADMIN_PORT}|g" \
      | sed -e "s|XDS_SERVER_CERT|${ENVOY_XDS_SERVER_CERT}|g" \
      | sed -e "s|TRACING_ENABLED|${ENVOY_TRACING_ENABLED}|g" \
      | sed -e "s|ACCESSLOG_PATH|${ENVOY_ACCESS_LOG}|g" \
      | sed -e "s|BACKEND_INBOUND_PORTS|${BACKEND_INBOUND_PORTS}|g" \
      | sed -e "s|trafficdirector.googleapis.com|trafficdirector.${ENVOY_CONTROL_PLANE_REGION}.rep.googleapis.com|g" \
      | sudo tee "${ENVOY_CONFIG}"
    
    # Install Envoy binary
    wget -O envoy_key https://apt.envoyproxy.io/signing.key
    cat envoy_key | sudo gpg --dearmor > $(pwd)/envoy-keyring.gpg
    echo "deb [arch=$(dpkg --print-architecture) signed-by=$(pwd)/envoy-keyring.gpg] https://apt.envoyproxy.io bullseye main" | sudo tee /etc/apt/sources.list.d/envoy.list
    sudo apt-get update
    sudo apt-get install envoy
    
    # Run Envoy as systemd service
    sudo systemd-run --uid=${ENVOY_USER_UID} --gid=${ENVOY_USER_GID} \
      --working-directory=${ENVOY_USER_HOME} --unit=envoy.service \
      bash -c "/usr/bin/envoy --config-path ${ENVOY_CONFIG} | tee"
    
    # Configure iptables for traffic interception and redirection
    sudo ${ENVOY_USER_HOME}/iptables.sh \
      -p "${ENVOY_PORT}" \
    -u "${ENVOY_USER_UID}" \
      -g "${ENVOY_USER_GID}" \
      -m "REDIRECT" \
      -i "${INTERCEPTED_CIDRS}" \
      -x "${GCE_METADATA_SERVER}"
    '
    
  2. 인스턴스 템플릿에서 리전 관리형 인스턴스 그룹을 만듭니다.

    gcloud compute instance-groups managed create gateway-proxy \
      --region=${REGION} \
      --size=1 \
      --template=gateway-proxy
    
  3. 관리형 인스턴스 그룹의 제공 포트 이름을 설정합니다.

    gcloud compute instance-groups managed set-named-ports gateway-proxy \
      --named-ports=https:8443 \
      --region=${REGION}
    

리전 외부 패스 스루 네트워크 부하 분산기 설정

  1. 고정 외부 리전 IP 주소를 만듭니다.

    gcloud compute addresses create xnlb-${REGION} \
      --region=${REGION}
    
  2. 외부 부하 분산기에 예약된 IP 주소를 가져옵니다.

    gcloud compute addresses describe xnlb-${REGION} \
      --region=${REGION} --format='value(address)'
    
  3. 게이트웨이 프록시의 상태 점검을 만듭니다.

    gcloud compute health-checks create tcp xnlb-${REGION} \
      --region=${REGION} \
      --use-serving-port
    
  4. 게이트웨이 프록시에 대한 백엔드 서비스를 만듭니다.

    gcloud compute backend-services create xnlb-${REGION} \
      --health-checks=xnlb-${REGION} \
      --health-checks-region=${REGION} \
      --load-balancing-scheme=EXTERNAL \
      --protocol=TCP \
      --region=${REGION} \
      --port-name=https
    
  5. 관리형 인스턴스 그룹을 백엔드로 추가합니다.

    gcloud compute backend-services add-backend xnlb-${REGION} \
      --instance-group=gateway-proxy \
      --instance-group-region=${REGION} \
      --region=${REGION}
    
  6. 게이트웨이 프록시로 트래픽을 라우팅하는 전달 규칙을 만듭니다.

    gcloud compute forwarding-rules create xnlb-${REGION} \
      --region=${REGION} \
      --load-balancing-scheme=EXTERNAL \
      --address=${IP_ADDRESS} \
      --ip-protocol=TCP \
      --ports=8443 \
      --backend-service=xnlb-${REGION} \
      --backend-service-region=${REGION}
    

HTTPS 서비스를 실행하는 관리형 인스턴스 그룹 구성

  1. 포트 8443에 노출된 HTTPS 서비스로 인스턴스 템플릿을 만듭니다.

    gcloud compute instance-templates create td-https-vm-template \
      --scopes=https://www.googleapis.com/auth/cloud-platform \
      --tags=https-td-server \
      --image-family=debian-11 \
      --image-project=debian-cloud \
      --metadata=startup-script='#! /bin/bash
    
    sudo rm -rf /var/lib/apt/lists/*
    sudo apt-get -y clean
    sudo apt-get -y update
    sudo apt-get -y install apt-transport-https ca-certificates curl gnupg2 software-properties-common
    sudo curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
    sudo add-apt-repository -y "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
    sudo apt-get -y update
    sudo apt-get -y install docker-ce
    sudo which docker
    echo "{ \"registry-mirrors\": [\"https://mirror.gcr.io\"] }" | sudo tee -a /etc/docker/daemon.json
    sudo service docker restart
    sudo docker run -e HTTPS_PORT=9999 -p 8443:9999 --rm -dt mendhak/http-https-echo:22'
    
  2. 인스턴스 템플릿을 기반으로 관리형 인스턴스 그룹을 만듭니다.

    gcloud compute instance-groups managed create https-td-mig-us-${REGION} \
      --zone=${ZONE} \
      --size=2 \
      --template=td-https-vm-template
    
  3. 관리형 인스턴스 그룹에 대해 제공 포트 이름을 설정합니다.

    gcloud compute instance-groups managed set-named-ports https-td-mig-us-${REGION} \
      --named-ports=https:8443 \
      --zone=${ZONE}
    
  4. 상태 확인을 만듭니다.

    gcloud compute health-checks create https https-helloworld-health-check \
      --port=8443 --region=${REGION}
    
  5. 네트워크 인스턴스에 들어오는 상태 점검 연결을 허용하는 방화벽 규칙을 만듭니다.

    gcloud compute firewall-rules create https-vm-allow-health-checks \
      --network ${NETWORK_NAME} --action allow --direction INGRESS \
      --source-ranges 35.191.0.0/16,130.211.0.0/22 \
      --target-tags https-td-server \
      --rules tcp:8443
    
  6. 부하 분산 스키마가 INTERNAL_SELF_MANAGED인 리전 백엔드 서비스를 만들고 상태 점검을 추가합니다.

    gcloud compute backend-services create https-helloworld-service \
      --region=${REGION} \
      --load-balancing-scheme=INTERNAL_SELF_MANAGED \
      --port-name=https \
      --health-checks="https://www.googleapis.com/compute/v1/projects/${PROJECT}/regions/${REGION}/healthChecks/https-helloworld-health-check"
    
  7. 관리형 인스턴스 그룹을 백엔드 서비스에 백엔드로 추가합니다.

    gcloud compute backend-services add-backend https-helloworld-service \
      --instance-group=https-td-mig-us-${REGION} \
      --instance-group-zone=${ZONE} \
      --region=${REGION}
    

TLSRoute 리소스로 라우팅 설정

  1. tls_route.yaml이라는 파일에서 TLSRoute 사양을 만듭니다.

    cat <<EOF > tls_route.yaml
    name: helloworld-tls-route
    gateways:
    - projects/${PROJECT_NUMBER}/locations/${REGION}/gateways/gateway8443
    rules:
    - matches:
      - sniHost:
        - example.com
        alpn:
        - h2
      action:
        destinations:
        - serviceName: projects/${PROJECT_NUMBER}/locations/${REGION}/backendServices/https-helloworld-service
    EOF
    

    이전 안내에서 TLSRoute는 example.com을 SNI로, h2를 ALPN으로 일치시킵니다. 일치가 다음과 같이 변경되면 TLSRoute가 SNI 또는 ALPN과 일치합니다.

    - matches:
      - sniHost:
        - example.com
      - alpn:
        - h2
    
  2. tls_route.yaml 사양을 사용하여 TLSRoute 리소스를 만듭니다.

    gcloud network-services tls-routes import helloworld-tls-route \
        --source=tls_route.yaml \
        --location=${REGION}
    

배포 검증

  1. 다음 curl 명령어를 실행하여 만든 테스트 서비스에 대한 HTTP 연결을 확인합니다.

    curl https://example.com:8443 --resolve example.com:8443:${IP_ADDRESS} -k
    
  2. 이 명령어는 관리형 인스턴스 그룹에서 VM 중 하나로부터 응답을 반환합니다. 출력은 다음과 비슷합니다.

    {
      "path": "/",
      "headers": {
        "host": "example.com:8443",
        "user-agent": "curl/8.16.0",
        "accept": "*/*"
      },
      "method": "GET",
      "body": "",
      "fresh": false,
      "hostname": "example.com",
      "ip": "::ffff:10.128.0.59",
      "ips": [],
      "protocol": "https",
      "query": {},
      "subdomains": [],
      "xhr": false,
      "os": {
        "hostname": "19cd7812e792"
      },
      "connection": {
        "servername": "example.com"
      }
    

부정형 검증으로 확인

  1. 다음 명령어에서 SNI가 example.com과 일치하지 않기 때문에 게이트웨이가 연결을 거부합니다.

    curl https://invalid-server.com:8443 --resolve invalid-server.com:8443:${IP_ADDRESS} -k
    
  2. 다음 명령어에서 ALPN이 h2 (HTTP2 프로토콜)와 일치하지 않으므로 게이트웨이는 연결을 거부합니다.

    curl https://example.com:8443 --resolve example.com:8443:${IP_ADDRESS} -k --http1.1
    

    위의 명령어는 모두 다음 오류를 반환합니다.

    curl: (35) OpenSSL SSL_connect: Connection reset by peer in connection.
    
  3. 다음 명령어에서 클라이언트는 일반 텍스트 (암호화되지 않음) 연결을 생성하므로 게이트웨이는 404 Not Found 오류로 연결을 거부합니다.

    curl example.com:8443 --resolve example.com:8443:${IP_ADDRESS} -k