Cloud Service Mesh regional

Com o isolamento regional, os clientes que se ligam a uma região específica do plano de controlo do Cloud Service Mesh só podem aceder a recursos nessa região. Da mesma forma, os recursos da API numa região específica só podem referir-se a outros recursos nessa região.

O Regional Cloud Service Mesh tem as seguintes limitações:

  • A API Istio não é suportada. Não pode usar o Kubernetes com a API Istio usando o Traffic Director regional. Apenas as APIs Google Cloud são suportadas nesta pré-visualização.
  • Aplicam-se as considerações e limitações existentes das APIs de encaminhamento de serviços globais.
  • A versão mínima do Envoy para suportar esquemas de nomenclatura xdSTP é a v1.31.1.
  • O gateway para a API Mesh não é suportado.
  • A versão mínima do gRPC é a v1.65.
  • Apenas são suportadas as seguintes regiões:

    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
    

Preços

Cada região na qual o Cloud Service Mesh regional é suportado terá um SKU regional quando esta funcionalidade estiver geralmente disponível. Por agora, os preços são os mesmos que os globais.

Prepare o cliente xDS para o Cloud Service Mesh

Compute VM Envoy xDS

Manual

Os passos manuais baseiam-se na configuração de VMs através da implementação manual do Envoy. A principal diferença é que ENVOY_CONTROL_PLANE_REGION é definido e injetado no arranque.

  1. Crie o modelo de instância:

    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

Semelhante à malha de serviços na nuvem global, os clientes gRPC têm de configurar uma inicialização para indicar como estabelecer ligação à malha de serviços na nuvem regional.

Pode usar o gerador de arranque do gRPC para gerar este arranque. Para o definir de modo a usar o Cloud Service Mesh regional, especifique uma nova flag: --xds-server-region.

Neste exemplo, a definição de xds-server-region como us-central1 determina automaticamente o ponto final do Cloud Service Mesh regional: trafficdirector.us-central1.rep.googleapis.com:443.

K8s Manual Envoy Injection

Os passos manuais baseiam-se no artigo Configure pods do Google Kubernetes Engine com injeção manual do Envoy. No entanto, só tem de modificar a secção sobre a injeção manual de pods.

  1. Altere o plano de controlo de global para regional:

    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. Aplique as alterações:

      kubectl apply -f trafficdirector_client_new_api_sample_xdsv3.yaml
        ```
      

Guias de configuração

A secção abrange cinco configurações e modelos de implementação independentes. Estas são todas as versões regionalizadas dos guias de configuração da API de encaminhamento de serviços global existentes.

Configure serviços gRPC sem proxy com GRPCRoute regional e Cloud Service Mesh regional

Estas secções explicam como configurar uma malha de serviços gRPC sem proxy com o Cloud Service Mesh regional e recursos GRPCRoute regionais.

Para sua conveniência, armazene o Google Cloud número do projeto no qual faz a configuração, para que todos os exemplos neste guia possam ser copiados e colados na linha de comandos:

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

Substitua PROJECT_NUMBER pelo número do seu projeto.

Opcionalmente, pode substituir o seguinte:

  • us-central1 com uma região diferente que quer usar.
  • us-central1-a com uma zona diferente que quer usar.
  • default com um VPC_NAME diferente.

Configuração da malha

Quando uma aplicação gRPC sem proxy se liga a um xds://hostname, a biblioteca do cliente gRPC estabelece uma ligação à Cloud Service Mesh para obter a configuração de encaminhamento necessária para encaminhar pedidos para o nome do anfitrião.

  1. Crie uma especificação de malha e armazene-a no ficheiro mesh.yaml:

    cat <<EOF > mesh.yaml
    name: grpc-mesh
    EOF
    
  2. Crie uma malha com a especificação mesh.yaml:

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

    Depois de criar a malha regional, a malha de serviço na nuvem está pronta para publicar a configuração. No entanto, como ainda não estão definidos serviços, a configuração está vazia.

Configuração do serviço gRPC

Para fins de demonstração, vai criar um serviço de back-end regional com VMs com escala automática (através de grupos de instâncias geridas, ou GIGs) que vai publicar hello world através do protocolo gRPC na porta 50051.

  1. Crie o modelo de instância de VM do Compute Engine com um serviço helloworldgRPC exposto na porta 50051:

    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. Crie um MIG com base no modelo:

    gcloud compute instance-groups managed create grpc-td-mig-us-central1 \
      --zone=${ZONE} \
      --size=2 \
      --template=grpc-td-vm-template
    
  3. Configure uma porta com nome para o serviço gRPC. Esta é a porta na qual o serviço gRPC está configurado para ouvir pedidos.

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

    Neste exemplo, a porta é 50051.

  4. Crie verificações de funcionamento de gRPC.

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

    Os serviços têm de implementar o protocolo de verificação de funcionamento do gRPC para que as verificações de funcionamento do gRPC funcionem corretamente. Para mais informações, consulte o artigo Criar verificações de funcionamento.

  5. Crie uma regra de firewall para permitir ligações de verificações de estado de funcionamento de entrada a instâncias na sua rede:

    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. Crie um serviço de back-end regional com um esquema de balanceamento de carga de INTERNAL_SELF_MANAGED e adicione a verificação de estado e um grupo de instâncias gerido criado anteriormente ao serviço de back-end. A porta no nome da porta especificado é usada para estabelecer ligação às VMs no grupo de instâncias gerido.

    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. Adicione o grupo de instâncias geridas ao BackendService:

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

Configure o encaminhamento com GRPCRoute regional

Neste ponto, a malha regional e o serviço de servidor gRPC estão configurados. Agora, pode configurar o encaminhamento necessário.

  1. Crie a especificação GRPCRoute regional e armazene-a no ficheiro 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. Crie uma GRPCRoute regional com a especificação grpc_route.yaml:

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

    O Cloud Service Mesh está agora configurado para equilibrar a carga do tráfego para os serviços especificados na rota gRPC em back-ends no grupo de instâncias gerido.

Crie um serviço de cliente gRPC

Para validar a configuração, instancie uma aplicação cliente com um plano de dados gRPC sem proxy. Esta aplicação tem de especificar (no respetivo ficheiro de arranque) o nome da malha.

Depois de configurada, esta aplicação pode enviar um pedido para as instâncias ou os pontos finais associados ao helloworld-gce através do URI do serviço xds:///helloworld-gce.

Nos exemplos seguintes, use a ferramenta grpcurl para testar o serviço gRPC.

  1. Crie uma VM de cliente:

    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')
    

Configure a variável de ambiente e o ficheiro de arranque

A aplicação cliente precisa de um ficheiro de configuração de arranque. O script de arranque na secção anterior define a variável de ambiente GRPC_XDS_BOOTSTRAP e usa um script auxiliar para gerar o ficheiro de arranque. Os valores de TRAFFICDIRECTOR_GCP_PROJECT_NUMBER e zona no ficheiro de arranque gerado são obtidos a partir do servidor de metadados que conhece estes detalhes sobre as instâncias de VMs do Compute Engine.

Pode fornecer estes valores ao script auxiliar manualmente através da opção -gcp-project-number. Tem de indicar um nome de malha que corresponda ao recurso de malha através da opção -config-mesh-experimental.

  1. Para validar a configuração, inicie sessão no cliente:

    gcloud compute ssh grpc-client --zone=${ZONE}
    
  2. Transfira e instale a ferramenta 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. Execute a ferramenta grpcurl com xds:///helloworld-gce como URI do serviço e helloworld.Greeter/SayHello como nome do serviço e método a invocar.

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

    Os parâmetros do método SayHello são transmitidos através da opção -d.

    Deverá ver uma saída semelhante a esta, em que INSTANCE_NAME é o nome da instância de VM:

    Greeting: Hello world, from INSTANCE_HOSTNAME
    

Isto verifica se o cliente gRPC sem proxy se ligou com êxito ao Cloud Service Mesh e aprendeu sobre os back-ends para o serviço helloworld-gce através do resolvedor de nomes xDS. O cliente enviou um pedido a um dos backends do serviço sem precisar de saber o endereço IP nem realizar a resolução de DNS.

Configurar a configuração do proxy sidecar do Envoy com serviços HTTP com HTTPRoute regional e malha regional

Esta secção explica como configurar uma malha de serviços baseada no proxy Envoy com recursos de malha regional e HTTPRoute regional.

Para sua conveniência, armazene o Google Cloud número do projeto no qual faz a configuração, para que todos os exemplos neste guia possam ser copiados e colados na linha de comandos:

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

Substitua o seguinte

  • PROJECT_ID com o ID do seu projeto.
  • PROJECT_NUMBER com o número do projeto.

Opcionalmente, pode substituir o seguinte:

  • us-central1 com uma região diferente que quer usar.
  • us-central1-a com uma zona diferente que quer usar.

Configuração da malha

O proxy Envoy sidecar recebe a configuração de encaminhamento de serviços do Cloud Service Mesh. O sidecar apresenta o nome do recurso de malha regional para identificar a malha de serviço específica configurada. A configuração de encaminhamento recebida do Cloud Service Mesh é usada para direcionar o tráfego que passa pelo proxy sidecar para vários serviços de back-end regionais, consoante os parâmetros de pedido, como o nome do anfitrião ou os cabeçalhos, configurados nos recursos de rota.

Tenha em atenção que o nome da malha é a chave que o proxy sidecar usa para pedir a configuração associada a esta malha.

  1. Crie a especificação da malha regional e armazene-a no ficheiro mesh.yaml:

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

    A porta de interceção é predefinida como 15001 se não for especificada.

  2. Crie uma malha regional com a especificação mesh.yaml:

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

    Depois de criar a malha regional, a malha de serviço na nuvem está pronta para publicar a configuração. No entanto, uma vez que ainda não estão definidos serviços, a configuração está vazia.

Configuração do servidor HTTP

Para fins de demonstração, vai criar um serviço de back-end regional com VMs com escala automática (através de grupos de instâncias geridas, ou GIGs) que vai publicar "hello world" através do protocolo gRPC na porta 80.

  1. Crie o modelo de instância de VM do Compute Engine com um serviço helloworld HTTP exposto na porta 80:

    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. Crie um MIG com base no modelo:

    gcloud compute instance-groups managed create http-td-mig-us-central1 \
      --zone=${ZONE} \
      --size=2 \
      --template=td-httpd-vm-template
    
  3. Crie as verificações de funcionamento:

    gcloud compute health-checks create http http-helloworld-health-check --region=${REGION}
    
  4. Crie uma regra de firewall para permitir ligações de verificações de estado de funcionamento de entrada a instâncias na sua rede:

    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. Crie um serviço de back-end regional com um esquema de balanceamento de carga de 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. Adicione a verificação de estado e um grupo de instâncias gerido ou não gerido ao serviço de back-end:

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

    Este exemplo usa o grupo de instâncias geridas com o modelo de VM do Compute Engine que executa o serviço HTTP de exemplo que criámos anteriormente.

Configure o encaminhamento com HTTPRoute regional

O recurso de malha e o servidor HTTP estão configurados. Agora, pode associá-los através de um recurso HTTPRoute que associa um nome do anfitrião a um serviço de back-end.

  1. Crie a especificação HTTPRoute e armazene-a como 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. Crie o HTTPRoute com a especificação http_route.yaml:

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

    O Cloud Service Mesh está agora configurado para equilibrar a carga do tráfego para os serviços especificados no HTTPRoute em back-ends no grupo de instâncias gerido.

Crie um cliente HTTP com o sidecar do Envoy

Nesta secção, vai instanciar uma VM cliente com o proxy sidecar do Envoy para pedir a configuração do Cloud Service Mesh criada anteriormente. Tenha em atenção que o parâmetro mesh no comando da CLI do Google Cloud faz referência ao recurso de malha criado anteriormente.

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. Inicie sessão na VM criada:

    gcloud compute ssh td-vm-client --zone=${ZONE}
    
  2. Valide a conetividade HTTP aos serviços de teste criados:

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

    O comando devolve uma resposta de uma das VMs no grupo de instâncias geridas com o respetivo nome de anfitrião impresso na consola.

Configurar serviços TCP com TCPRoute regional

Este fluxo de configuração é muito semelhante a Configurar proxies do Envoy com serviços HTTP com a exceção de que o serviço de back-end fornece um serviço TCP e o encaminhamento baseado nos parâmetros TCP/IP é usado em vez de baseado no protocolo HTTP.

Para sua conveniência, armazene o Google Cloud número do projeto no qual faz a configuração, para que todos os exemplos neste guia possam ser copiados e colados na linha de comandos:

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

Substitua o seguinte

  • PROJECT_ID com o ID do seu projeto.
  • PROJECT_NUMBER com o número do projeto.

Opcionalmente, pode substituir o seguinte:

  • us-central1 com uma região diferente que quer usar.
  • us-central1-a com uma zona diferente que quer usar.

Configuração da malha

  1. Crie a especificação da malha regional e armazene-a no ficheiro mesh.yaml:

    cat <<EOF > mesh.yaml
    name: sidecar-mesh
    EOF
    
  2. Crie uma malha regional com a especificação mesh.yaml:

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

Configuração do servidor TCP

Para fins de demonstração, vai criar um serviço de back-end regional com VMs de escala automática (através de grupos de instâncias geridas, ou GIGs) que vai publicar "hello world" através do protocolo gRPC na porta 10000.

  1. Crie o modelo de instância de VM do Compute Engine com um serviço de teste na porta 10000 através do utilitário netcat:

    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. Crie um MIG com base no modelo:

    gcloud compute instance-groups managed create tcp-td-mig-us-central1 \
      --zone=${ZONE} \
      --size=1 \
      --template=tcp-td-vm-template
    
  3. Defina as portas com nome no grupo de instâncias geridas criado para port 10000:

    gcloud compute instance-groups set-named-ports tcp-td-mig-us-central1 \
      --zone=${ZONE} --named-ports=tcp:10000
    
  4. Crie uma verificação de funcionamento regional:

    gcloud compute health-checks create tcp tcp-helloworld-health-check --port 10000 --region=${REGION}
    
  5. Crie uma regra de firewall para permitir ligações de verificações de estado de funcionamento de entrada a instâncias na sua rede:

    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. Crie um serviço de back-end regional com um esquema de balanceamento de carga de INTERNAL_SELF_MANAGED e adicione a verificação de estado e um grupo de instâncias gerido ou não gerido ao serviço de back-end.

    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. Adicione o MIG ao BackendService:

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

Configure o encaminhamento com TCPRoute regional

  1. Crie a especificação TCPRoute e armazene-a no ficheiro 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. Crie um TCPRoute com a especificação tcp_route.yaml:

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

Crie um cliente TCP com o sidecar do Envoy

  1. Crie uma VM com o Envoy ligado à malha de serviço do Google Cloud:

    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. Inicie sessão na VM criada:

    gcloud compute ssh td-vm-client --zone=${ZONE}
    
  3. Valide a conetividade aos serviços de teste criados:

    curl 10.0.0.1:10000 --http0.9 -v
    

    Deve ver um texto Hello from TCP service devolvido, bem como poder ver qualquer texto que escreva devolvido pelo serviço netcat em execução na VM remota.

Configuração da malha regional no projeto anfitrião

Designar um projeto como projeto anfitrião. Qualquer conta de serviço com autorização para criar/atualizar/eliminar malhas neste projeto pode controlar as configurações de encaminhamento anexadas a malhas regionais neste projeto.

  1. Defina uma variável que vai ser usada ao longo do exemplo:

    export REGION="us-central1"
    

    Opcionalmente, pode substituir us-central1 por uma região diferente que queira usar.

  2. Crie a especificação da malha e armazene-a no ficheiro mesh.yaml:

    cat <<EOF > mesh.yaml
    name: shared-mesh
    EOF
    
  3. Defina um recurso de malha neste projeto com a configuração necessária:

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

    Tome nota do URI completo deste recurso de malha. Os proprietários de serviços vão precisar dele no futuro para anexar as respetivas rotas a esta malha.

  4. Conceda a autorização do IAM networkservices.meshes.use a esta malha e às contas de serviço entre projetos que devem poder anexar as informações dos respetivos serviços a esta malha:

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

    Agora, todos os proprietários de serviços com autorização networkservices.meshes.use podem adicionar as respetivas regras de encaminhamento a esta malha.

Configuração de rotas em projetos de serviço

Cada proprietário do serviço tem de criar serviços de back-end regionais e recursos de rotas regionais no respetivo projeto, de forma semelhante à configuração de proxies do Envoy com serviços HTTP. A única diferença é que cada HTTPRoute/GRPCRoute/TCPRoute teria o URI do recurso de malha do projeto anfitrião no campo meshes.

  1. Crie um 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}
    

Configurar serviços de cliente em projetos de serviço

Ao configurar um cliente da Cloud Service Mesh (proxy Envoy ou sem proxy) que está localizado num projeto de serviço, tem de especificar o número do projeto onde o recurso da malha está localizado e o nome da malha na respetiva configuração de arranque:

TRAFFICDIRECTOR_GCP_PROJECT_NUMBER=HOST_PROJECT_NUMBER
TRAFFICDIRECTOR_MESH_NAME=MESH_NAME

Encaminhamento TLS do gateway

Esta secção demonstra como configurar um gateway de entrada baseado no proxy Envoy com recursos de gateway regional e TLSRoute regional.

Um Network Load Balancer de passagem externo regional direciona o tráfego para proxies Envoy que atuam como um gateway de entrada. Os proxies Envoy usam o encaminhamento de passagem de TLS e direcionam o tráfego para servidores HTTPS em execução nas instâncias de VMs de back-end.

Defina algumas variáveis que vão ser usadas ao longo do exemplo.

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

Substitua o seguinte: default

  • PROJECT_ID com o ID do seu projeto.
  • PROJECT_NUMBER com o número do projeto.

Opcionalmente, pode substituir o seguinte:

  • us-central1 com uma região diferente que quer usar.
  • us-central1-b com uma zona diferente que quer usar.
  • default com um nome de rede diferente que quer usar.

Referência cruzada de recursos de malha regional e de rota regional num ambiente de VPC partilhada com vários projetos

Existem cenários em que a configuração da malha de serviços consiste em serviços que pertencem a projetos diferentes. Por exemplo, nas implementações de VPC partilhada ou VPC com intercâmbio, é possível que cada proprietário do projeto defina o seu próprio conjunto de serviços com o objetivo de que estes serviços estejam disponíveis para todos os outros projetos.

Esta configuração é "entre projetos" porque vários recursos definidos em diferentes projetos são combinados para formar uma única configuração que pode ser fornecida a um proxy ou a um cliente sem proxy.

Configure regras de firewall

  1. Configure regras de firewall para permitir tráfego de qualquer origem. Edite os comandos para as suas portas e intervalos de endereços IP de origem.

    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
    

Configure as autorizações de IAM

  1. Crie uma identidade de conta de serviço para os proxies de gateway:

    gcloud iam service-accounts create gateway-proxy
    
  2. Atribua as funções do IAM necessárias à identidade da conta de serviço:

    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"
    

Configure o gateway regional:

  1. Num ficheiro denominado gateway8443.yaml, crie a especificação do gateway para tráfego HTTP:

    cat <<EOF > gateway8443.yaml
    name: gateway8443
    scope: gateway-proxy-8443
    ports:
    - 8443
    type: OPEN_MESH
    EOF
    
  2. Crie o recurso de gateway regional com a especificação gateway8443.yaml:

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

Crie um grupo de instâncias geridas com proxies Envoy

Nesta secção, cria um modelo de instância para uma VM que executa um proxy de serviço Envoy implementado automaticamente. Os Envoys têm o âmbito definido como gateway-proxy. Não transmita a porta de publicação como um parâmetro da flag --service-proxy.

  1. Crie um grupo de instâncias geridas com proxies 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. Crie um grupo de instâncias geridas regional a partir do modelo de instância:

    gcloud compute instance-groups managed create gateway-proxy \
      --region=${REGION} \
      --size=1 \
      --template=gateway-proxy
    
  3. Defina o nome da porta de publicação para o grupo de instâncias geridas:

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

Configure o balanceador de carga de encaminhamento externo regional

  1. Crie um endereço IP regional externo estático:

    gcloud compute addresses create xnlb-${REGION} \
      --region=${REGION}
    
  2. Obtenha o endereço IP reservado para o balanceador de carga externo:

    gcloud compute addresses describe xnlb-${REGION} \
      --region=${REGION} --format='value(address)'
    
  3. Crie uma verificação de funcionamento para os proxies de gateway:

    gcloud compute health-checks create tcp xnlb-${REGION} \
      --region=${REGION} \
      --use-serving-port
    
  4. Crie um serviço de back-end para os proxies de gateway:

    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. Adicione o grupo de instâncias geridas como um back-end:

    gcloud compute backend-services add-backend xnlb-${REGION} \
      --instance-group=gateway-proxy \
      --instance-group-region=${REGION} \
      --region=${REGION}
    
  6. Crie uma regra de encaminhamento para encaminhar o tráfego para os proxies de gateway:

    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}
    

Configure um grupo de instâncias geridas que execute um serviço HTTPS

  1. Crie um modelo de instância com um serviço HTTPS exposto na porta 8443:

    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. Crie um grupo de instâncias geridas com base no modelo de instância:

    gcloud compute instance-groups managed create https-td-mig-us-${REGION} \
      --zone=${ZONE} \
      --size=2 \
      --template=td-https-vm-template
    
  3. Defina o nome da porta de publicação para o grupo de instâncias geridas:

    gcloud compute instance-groups managed set-named-ports https-td-mig-us-${REGION} \
      --named-ports=https:8443 \
      --zone=${ZONE}
    
  4. Crie uma verificação de funcionamento:

    gcloud compute health-checks create https https-helloworld-health-check \
      --port=8443 --region=${REGION}
    
  5. Crie uma regra de firewall para permitir ligações de verificações de estado de funcionamento de entrada a instâncias na sua rede:

    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. Crie um serviço de back-end regional com um esquema de balanceamento de carga de INTERNAL_SELF_MANAGED e adicione a verificação de funcionamento:

    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. Adicione o grupo de instâncias geridas como back-end ao serviço de back-end:

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

Configure o encaminhamento com um recurso TLSRoute

  1. Num ficheiro denominado tls_route.yaml, crie a especificação 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
    

    Na instrução anterior, TLSRoute corresponde a example.com como SNI e h2 como ALPN. Se as correspondências forem alteradas da seguinte forma, TLSRoute corresponde a SNI ou ALPN:

    - matches:
      - sniHost:
        - example.com
      - alpn:
        - h2
    
  2. Use a especificação tls_route.yaml para criar o recurso TLSRoute:

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

Valide a implementação

  1. Execute o seguinte comando curl para validar a conetividade HTTP aos serviços de teste que criou:

    curl https://example.com:8443 --resolve example.com:8443:${IP_ADDRESS} -k
    
  2. O comando devolve uma resposta de uma das VMs no grupo de instâncias geridas. O resultado é semelhante ao seguinte:

    {
      "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"
      }
    

Faça a validação com uma validação negativa

  1. No comando seguinte, o SNI não corresponde a example.com, pelo que o gateway rejeita a ligação:

    curl https://invalid-server.com:8443 --resolve invalid-server.com:8443:${IP_ADDRESS} -k
    
  2. No comando seguinte, o ALPN não corresponde a h2 (protocolo HTTP2), pelo que o gateway rejeita a ligação:

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

    Todos os comandos anteriores devolvem o seguinte erro:

    curl: (35) OpenSSL SSL_connect: Connection reset by peer in connection.
    
  3. No comando seguinte, o cliente está a criar uma ligação de texto simples (não encriptada), pelo que o gateway rejeita a ligação com um erro 404 Not Found:

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