Cloud Service Mesh regional

Con el aislamiento regional, los clientes que se conectan a una región específica del plano de control de Cloud Service Mesh solo pueden acceder a los recursos dentro de esa región. Del mismo modo, los recursos de la API dentro de una región específica solo pueden hacer referencia a otros recursos de esa región.

Cloud Service Mesh regional tiene las siguientes limitaciones:

  • No se admite la API de Istio. No puedes usar Kubernetes con la API de Istio a través de Traffic Director regional. En esta versión preliminar, solo se admiten las APIs de Google Cloud .
  • Se aplican las consideraciones y limitaciones existentes de las APIs de enrutamiento de servicios globales.
  • La versión mínima de Envoy para admitir esquemas de nomenclatura de xdSTP es la v1.31.1.
  • No se admite la API de Gateway for Mesh.
  • La versión mínima de gRPC es la v1.65.
  • Solo se admiten las siguientes regiones:

    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
    

Precios

Cada región en la que se admita Cloud Service Mesh regional tendrá un SKU regional cuando esta función esté disponible de forma general. Por el momento, los precios son los mismos que los globales.

Prepara el cliente de xDS para Cloud Service Mesh

VM de Compute Envoy xDS

Manual

Los pasos manuales se basan en Configura VM mediante la implementación manual de Envoy. La principal diferencia es que ENVOY_CONTROL_PLANE_REGION se configura y se inyecta en el proceso de arranque.

  1. Crea la plantilla de instancias:

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

xDS de gRPC de VM de Compute

Al igual que con Cloud Service Mesh global, los clientes de gRPC deben configurar un bootstrap para indicarle cómo conectarse a Cloud Service Mesh regional.

Puedes usar el generador de arranque de gRPC para generar este arranque. Para configurarlo de modo que use Cloud Service Mesh regional, especifica una marca nueva: --xds-server-region.

En este ejemplo, establecer xds-server-region en us-central1 determina automáticamente el extremo regional de Cloud Service Mesh: trafficdirector.us-central1.rep.googleapis.com:443.

Inserción manual de Envoy en K8s

Los pasos manuales se basan en Configura los Pods de Google Kubernetes Engine con la inserción manual de Envoy. Sin embargo, solo debes modificar la sección sobre la inserción manual de Pods.

  1. Cambia el plano de control de global a 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. Aplica los cambios:

      kubectl apply -f trafficdirector_client_new_api_sample_xdsv3.yaml
        ```
      

Guías de configuración

En esta sección, se abarcan cinco modelos de configuración y de implementación independientes. Todas estas son versiones regionalizadas de las guías de configuración de la API de enrutamiento de servicios global existentes.

Configura servicios de gRPC sin proxy con GRPCRoute regional y Cloud Service Mesh regional

En esta sección, se explica cómo configurar una malla de servicios de gRPC sin proxy con recursos regionales de Cloud Service Mesh y GRPCRoute.

Para tu comodidad, almacena el número de proyecto Google Cloud en el que realizas la configuración, de modo que todos los ejemplos de esta guía se puedan copiar y pegar en la línea de comandos:

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

Reemplaza PROJECT_NUMBER por el número del proyecto.

De manera opcional, puedes reemplazar lo siguiente:

  • us-central1 por otra región que quieras usar
  • us-central1-a por otra zona que quieras usar
  • default con un VPC_NAME diferente.

Configuración de la malla

Cuando una aplicación de gRPC sin proxy se conecta a un xds://hostname, la biblioteca cliente de gRPC establece una conexión con Cloud Service Mesh para obtener la configuración de enrutamiento necesaria para enrutar las solicitudes del nombre de host.

  1. Crea una especificación de malla y almacénala en el archivo mesh.yaml:

    cat <<EOF > mesh.yaml
    name: grpc-mesh
    EOF
    
  2. Crea una malla con la especificación mesh.yaml:

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

    Después de crear la malla regional, Cloud Service Mesh estará listo para entregar la configuración. Sin embargo, como aún no se definieron servicios, la configuración está vacía.

Configuración del servicio de gRPC

A modo de demostración, crearás un servicio de backend regional con VMs con ajuste de escala automático (con grupos de instancias administrados, MIG) que entregará hello world con el protocolo gRPC en el puerto 50051.

  1. Crea la plantilla de instancias de VM de Compute Engine con un servicio de gRPC helloworld que se exponga en el puerto 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. Crea un MIG basado en la plantilla:

    gcloud compute instance-groups managed create grpc-td-mig-us-central1 \
      --zone=${ZONE} \
      --size=2 \
      --template=grpc-td-vm-template
    
  3. Configura un puerto con nombre para el servicio de gRPC. Este es el puerto en el que se configura el servicio de gRPC para escuchar las solicitudes.

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

    En este ejemplo, el puerto es 50051.

  4. Crea verificaciones de estado de gRPC.

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

    Los servicios deben implementar el protocolo de verificación de estado de gRPC para que las verificaciones de estado de gRPC funcionen correctamente. Para obtener más información, consulta Crea verificaciones de estado.

  5. Crea una regla de firewall que permita las conexiones de verificación de estado entrantes a las instancias de tu red:

    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. Crea un servicio de backend regional con un esquema de balanceo de cargas de INTERNAL_SELF_MANAGED y agrega la verificación de estado y un grupo de instancias administrado que se creó anteriormente al servicio de backend. El puerto del nombre de puerto especificado se usa para conectarse a las VMs del grupo de instancias administrado.

    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. Agrega el grupo de instancias administrado a BackendService:

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

Configura el enrutamiento con GRPCRoute regional

En este punto, se configuran la malla regional y el servicio del servidor de gRPC. Ahora puedes configurar el enrutamiento necesario.

  1. Crea la especificación de GRPCRoute regional y almacénala en el archivo 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. Crea un GRPCRoute regional con la especificación grpc_route.yaml:

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

    Cloud Service Mesh ahora está configurado para balancear las cargas del tráfico de los servicios especificados en la ruta de gRPC en los backends del grupo de instancias administrado.

Crea un servicio de cliente de gRPC

Para verificar la configuración, crea una instancia de una aplicación cliente con un plano de datos de gRPC sin proxy. Esta aplicación debe especificar (en su archivo de arranque) el nombre de la malla.

Una vez configurada, esta aplicación puede enviar una solicitud a las instancias o los extremos asociados con helloworld-gce a través del URI de servicio xds:///helloworld-gce.

En los siguientes ejemplos, usa la herramienta de grpcurl para probar el servicio de gRPC.

  1. Crea una 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')
    

Configura la variable de entorno y el archivo de arranque

La aplicación cliente necesita un archivo de configuración de arranque. La secuencia de comandos de inicio de la sección anterior configura la variable de entorno GRPC_XDS_BOOTSTRAP y usa una secuencia de comandos auxiliar para generar el archivo de arranque. Los valores para TRAFFICDIRECTOR_GCP_PROJECT_NUMBER y la zona del archivo de arranque generado se obtienen del servidor de metadatos que conoce estos detalles de las instancias de VM de Compute Engine.

Puedes proporcionar estos valores a la secuencia de comandos auxiliar de forma manual con la opción -gcp-project-number. Debes proporcionar un nombre de malla que coincida con el recurso de malla usando la opción -config-mesh-experimental.

  1. Para verificar la configuración, accede al cliente:

    gcloud compute ssh grpc-client --zone=${ZONE}
    
  2. Descarga y, luego, instala la herramienta de 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. Ejecuta la herramienta de grpcurl con xds:///helloworld-gce como el URI del servicio y helloworld.Greeter/SayHello como el nombre del servicio y el método que se invocará.

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

    Los parámetros del método SayHello se pasan con la opción -d.

    Deberías ver un resultado similar a este, en el que INSTANCE_NAME es el nombre de la instancia de VM:

    Greeting: Hello world, from INSTANCE_HOSTNAME
    

Esto verifica que el cliente de gRPC sin proxy se conectó de forma correcta a Cloud Service Mesh y aprendió sobre los backends para el servicio helloworld-gce con el agente de resolución de nombres de xDS. El cliente envió una solicitud a uno de los backends del servicio sin necesidad de conocer la dirección IP ni realizar la resolución de DNS.

Configura el proxy de sidecar de Envoy con servicios HTTP con HTTPRoute regional y malla regional

En esta sección, se explica cómo configurar una malla de servicios basada en el proxy de Envoy con recursos de malla regional y HTTPRoute regional.

Para tu comodidad, almacena el número de proyecto Google Cloud en el que realizas la configuración, de modo que todos los ejemplos de esta guía se puedan copiar y pegar en la línea de comandos:

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

Reemplaza lo siguiente

  • PROJECT_ID por el ID del proyecto
  • PROJECT_NUMBER por el número de tu proyecto.

De manera opcional, puedes reemplazar lo siguiente:

  • us-central1 por otra región que quieras usar
  • us-central1-a por otra zona que quieras usar

Configuración de la malla

El proxy de Envoy de sidecar recibe la configuración de enrutamiento de servicios de Cloud Service Mesh. El sidecar presenta el nombre del recurso de malla regional para identificar la malla de servicios específica configurada. La configuración de enrutamiento que se recibe de Cloud Service Mesh se usa para dirigir el tráfico que pasa por el proxy de sidecar a varios servicios de backend regionales según los parámetros de la solicitud, como el nombre de host o los encabezados, configurados en los recursos de Route.

Ten en cuenta que el nombre de la malla es la clave que usa el proxy de sidecar para solicitar la configuración asociada con esta malla.

  1. Crea la especificación de malla regional y almacénala en el archivo mesh.yaml:

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

    Si no se especifica, el puerto de interceptación se establece de forma predeterminada en 15001.

  2. Crea una malla regional con la especificación mesh.yaml:

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

    Después de crear la malla regional, Cloud Service Mesh estará listo para entregar la configuración. Sin embargo, como aún no se definieron servicios, la configuración estará vacía.

Configuración del servidor HTTP

A modo de demostración, crearás un servicio de backend regional con VMs con ajuste de escala automático (con grupos de instancias administrados, MIG) que entregará "hello world" con el protocolo de gRPC en el puerto 80.

  1. Crea la plantilla de instancias de VM de Compute Engine con un servicio HTTP helloworld que se exponga en el puerto 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. Crea un MIG basado en la plantilla:

    gcloud compute instance-groups managed create http-td-mig-us-central1 \
      --zone=${ZONE} \
      --size=2 \
      --template=td-httpd-vm-template
    
  3. Crea las verificaciones de estado:

    gcloud compute health-checks create http http-helloworld-health-check --region=${REGION}
    
  4. Crea una regla de firewall que permita las conexiones de verificación de estado entrantes a las instancias de tu red:

    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. Crea un servicio de backend regional con un esquema de balanceo de cargas 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. Agrega la verificación de estado y un grupo de instancias administrado o no administrado al servicio de backend:

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

    En este ejemplo, se usa el grupo de instancias administrado con la plantilla de VM de Compute Engine que ejecuta el servicio HTTP de muestra que creamos antes.

Configura el enrutamiento con HTTPRoute regional

El recurso de malla y el servidor HTTP están configurados. Ahora puedes conectarlos con un recurso HTTPRoute que asocie un nombre de host con un servicio de backend.

  1. Crea la especificación de HTTPRoute y guárdala 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. Crea la HTTPRoute con la especificación http_route.yaml:

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

    Cloud Service Mesh ahora está configurado para balancear las cargas del tráfico de los servicios especificados en HTTPRoute en los backends del grupo de instancias administrado.

Crea un cliente HTTP con un sidecar de Envoy

En esta sección, crearás una instancia de una VM cliente con un proxy de sidecar de Envoy para solicitar la configuración de Cloud Service Mesh que creaste anteriormente. Ten en cuenta que el parámetro mesh del comando de Google Cloud CLI hace referencia al recurso de malla creado 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. Accede a la VM creada:

    gcloud compute ssh td-vm-client --zone=${ZONE}
    
  2. Verifica la conectividad HTTP a los servicios de prueba creados:

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

    El comando devuelve una respuesta de una de las VMs del grupo de instancias administrado con su nombre de host impreso en la consola.

Configura servicios TCP con TCPRoute regional

Este flujo de configuración es muy similar a Configura proxies de Envoy con servicios HTTP, con la excepción de que el servicio de backend proporciona un servicio de TCP y se usa el enrutamiento basado en los parámetros de TCP/IP en lugar de basarse en el protocolo HTTP.

Para tu comodidad, almacena el número de proyecto Google Cloud en el que realizas la configuración, de modo que todos los ejemplos de esta guía se puedan copiar y pegar en la línea de comandos:

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

Reemplaza lo siguiente

  • PROJECT_ID por el ID del proyecto
  • PROJECT_NUMBER por el número de tu proyecto.

De manera opcional, puedes reemplazar lo siguiente:

  • us-central1 por otra región que quieras usar
  • us-central1-a por otra zona que quieras usar

Configuración de la malla

  1. Crea la especificación de malla regional y almacénala en el archivo mesh.yaml:

    cat <<EOF > mesh.yaml
    name: sidecar-mesh
    EOF
    
  2. Crea una malla regional con la especificación mesh.yaml:

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

Configuración del servidor TCP

A modo de demostración, crearás un servicio de backend regional con VMs con ajuste de escala automático (mediante grupos de instancias administrados, MIG) que entregará "hello world" con el protocolo de gRPC en el puerto 10000.

  1. Crea la plantilla de instancias de VM de Compute Engine con un servicio de prueba en el puerto 10000 con la utilidad 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. Crea un MIG basado en la plantilla:

    gcloud compute instance-groups managed create tcp-td-mig-us-central1 \
      --zone=${ZONE} \
      --size=1 \
      --template=tcp-td-vm-template
    
  3. Configura los puertos con nombre en el grupo de instancias administrado creado en port 10000:

    gcloud compute instance-groups set-named-ports tcp-td-mig-us-central1 \
      --zone=${ZONE} --named-ports=tcp:10000
    
  4. Crea una verificación de estado regional:

    gcloud compute health-checks create tcp tcp-helloworld-health-check --port 10000 --region=${REGION}
    
  5. Crea una regla de firewall que permita las conexiones de verificación de estado entrantes a las instancias de tu red:

    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. Crea un servicio de backend regional con un esquema de balanceo de cargas de INTERNAL_SELF_MANAGED y agrega la verificación de estado y un grupo de instancias administrado o no administrado al servicio de backend.

    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. Agrega el MIG al BackendService:

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

Configura el enrutamiento con TCPRoute regional

  1. Crea la especificación de TCPRoute y almacénala en el archivo 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. Crea TCPRoute con la especificación tcp_route.yaml:

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

Crea un cliente de TCP con un sidecar de Envoy

  1. Crea una VM con Envoy conectado a Cloud Service 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
    
  2. Accede a la VM creada:

    gcloud compute ssh td-vm-client --zone=${ZONE}
    
  3. Verifica la conectividad a los servicios de prueba creados:

    curl 10.0.0.1:10000 --http0.9 -v
    

    Deberías ver un texto Hello from TCP service que se te devuelve, así como cualquier texto que escribas que te devuelva el servicio netcat que se ejecuta en la VM remota.

Configuración de malla regional en el proyecto host

Designa un proyecto como proyecto host. Cualquier cuenta de servicio con permiso para crear, actualizar o borrar mallas en este proyecto puede controlar las configuraciones de enrutamiento conectadas a las mallas regionales en este proyecto.

  1. Define una variable que se usará en todo el ejemplo:

    export REGION="us-central1"
    

    De manera opcional, puedes reemplazar us-central1 por otra región que quieras usar.

  2. Crea la especificación de malla y almacénala en el archivo mesh.yaml:

    cat <<EOF > mesh.yaml
    name: shared-mesh
    EOF
    
  3. Define un recurso de malla en este proyecto con la configuración requerida:

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

    Toma nota del URI completo de este recurso de malla. Los propietarios del servicio lo necesitarán en el futuro para adjuntar sus rutas a esta malla.

  4. Otorga el permiso de IAM networkservices.meshes.use a esta malla y a las cuentas de servicio entre proyectos que deberían poder adjuntar la información de sus servicios a esta malla:

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

    Ahora, todos los propietarios de servicios que tienen el permiso networkservices.meshes.use otorgado pueden agregar sus reglas de enrutamiento a esta malla.

Configuración de rutas en proyectos de servicio

Cada propietario del servicio debe crear servicios de backend regionales y recursos de ruta regionales en su proyecto de manera similar a Configura proxies de Envoy con servicios HTTP. La única diferencia es que cada HTTPRoute/GRPCRoute/TCPRoute tendría el URI del recurso de malla del proyecto host en el campo meshes.

  1. Crea una ruta http de sharedvpc:

    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}
    

Configura servicios del cliente en proyectos de servicio

Cuando configuras un cliente de Cloud Service Mesh (proxy de Envoy o sin proxy) que se encuentra en un proyecto de servicio, debes especificar el número de proyecto en el que se encuentra el recurso de malla y el nombre de la malla en su configuración de arranque:

TRAFFICDIRECTOR_GCP_PROJECT_NUMBER=HOST_PROJECT_NUMBER
TRAFFICDIRECTOR_MESH_NAME=MESH_NAME

Enrutamiento TLS de la puerta de enlace

En esta sección, se muestra cómo configurar una puerta de enlace de entrada basada en el proxy de Envoy con recursos regionales de Gateway y TLSRoute.

Un balanceador de cargas de red de transferencia externo regional dirige el tráfico a los proxies de Envoy que actúan como una puerta de enlace de entrada. Los proxies de Envoy usan el enrutamiento de transferencia de TLS y el tráfico directo a los servidores HTTPS que se ejecutan en las instancias de VM de backend.

Define algunas variables que se usarán en todo el ejemplo.

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

Reemplaza lo siguiente: default

  • PROJECT_ID por el ID del proyecto
  • PROJECT_NUMBER por el número de tu proyecto.

De manera opcional, puedes reemplazar lo siguiente:

  • us-central1 por otra región que quieras usar
  • us-central1-b por otra zona que quieras usar
  • default por otro nombre de red que quieras usar.

Referencias cruzadas a recursos de malla regional y ruta regional en un entorno de VPC compartida de varios proyectos

Hay situaciones en las que la configuración de la malla de servicios consta de servicios que pertenecen a diferentes proyectos. Por ejemplo, en implementaciones de VPC compartida o VPC con intercambio de tráfico, es posible que cada propietario de proyecto defina su propio conjunto de servicios con el propósito de que estos servicios estén disponibles para todos los demás proyectos.

Esta configuración es "de varios proyectos" porque se combinan varios recursos definidos en diferentes proyectos para formar una sola configuración que se puede entregar en un cliente con proxy o sin proxy.

Configura reglas de firewall

  1. Configura las reglas de firewall para permitir el tráfico desde cualquier fuente. Edita los comandos para tus puertos y rangos de direcciones IP de origen.

    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
    

Configura los permisos de IAM

  1. Crea una identidad de cuenta de servicio para los proxies de puerta de enlace:

    gcloud iam service-accounts create gateway-proxy
    
  2. Asigna los roles de IAM necesarios a la identidad de la cuenta de servicio:

    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"
    

Configura la puerta de enlace regional:

  1. En un archivo llamado gateway8443.yaml, crea la especificación de Gateway para el tráfico HTTP:

    cat <<EOF > gateway8443.yaml
    name: gateway8443
    scope: gateway-proxy-8443
    ports:
    - 8443
    type: OPEN_MESH
    EOF
    
  2. Crea el recurso de Gateway regional con la especificación gateway8443.yaml:

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

Crea un grupo de instancias administrado con proxies de Envoy

En esta sección, crearás una plantilla de instancias para una VM que ejecute un proxy de servicio de Envoy implementado de forma automática. Los Envoys tienen el permiso establecido en gateway-proxy. No pases el puerto de entrega como un parámetro de la marca --service-proxy.

  1. Crea un grupo de instancias administrado con proxies de 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. Crea un grupo de instancias administrado regional a partir de la plantilla de instancias:

    gcloud compute instance-groups managed create gateway-proxy \
      --region=${REGION} \
      --size=1 \
      --template=gateway-proxy
    
  3. Establece el nombre del puerto de entrega para el grupo de instancias administrado:

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

Configura el balanceador de cargas de red de transferencia externo regional

  1. Crea una dirección IP regional externa estática:

    gcloud compute addresses create xnlb-${REGION} \
      --region=${REGION}
    
  2. Obtén la dirección IP que está reservada para el balanceador de cargas externo:

    gcloud compute addresses describe xnlb-${REGION} \
      --region=${REGION} --format='value(address)'
    
  3. Crea una verificación de estado para los proxies de puerta de enlace:

    gcloud compute health-checks create tcp xnlb-${REGION} \
      --region=${REGION} \
      --use-serving-port
    
  4. Crea un servicio de backend para los proxies de puerta de enlace:

    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. Agrega el grupo de instancias administrado como backend:

    gcloud compute backend-services add-backend xnlb-${REGION} \
      --instance-group=gateway-proxy \
      --instance-group-region=${REGION} \
      --region=${REGION}
    
  6. Crea una regla de reenvío para enrutar el tráfico a los proxies de puerta de enlace:

    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}
    

Configura un grupo de instancias administrado que ejecute un servicio HTTPS

  1. Crea una plantilla de instancias con un servicio HTTPS que se exponga en el puerto 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. Crea un grupo de instancias administrado basado en la plantilla de instancias:

    gcloud compute instance-groups managed create https-td-mig-us-${REGION} \
      --zone=${ZONE} \
      --size=2 \
      --template=td-https-vm-template
    
  3. Configura el nombre del puerto de entrega para el grupo de instancias administrado:

    gcloud compute instance-groups managed set-named-ports https-td-mig-us-${REGION} \
      --named-ports=https:8443 \
      --zone=${ZONE}
    
  4. Crea una verificación de estado de la siguiente forma:

    gcloud compute health-checks create https https-helloworld-health-check \
      --port=8443 --region=${REGION}
    
  5. Crea una regla de firewall que permita las conexiones de verificación de estado entrantes a las instancias de tu red:

    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. Crea un servicio de backend regional con un esquema de balanceo de cargas de INTERNAL_SELF_MANAGED y agrega la verificación de estado:

    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. Agrega el grupo de instancias administrado como backend al servicio de backend:

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

Configura el enrutamiento con un recurso TLSRoute

  1. En un archivo llamado tls_route.yaml, crea la especificación de 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
    

    En la instrucción anterior, TLSRoute coincide con example.com como SNI y h2 como ALPN. Si las coincidencias se cambian como se muestra a continuación, TLSRoute coincide con SNI o ALPN:

    - matches:
      - sniHost:
        - example.com
      - alpn:
        - h2
    
  2. Usa la especificación de tls_route.yaml para crear el recurso TLSRoute:

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

Valida la implementación

  1. Ejecuta el siguiente comando curl para verificar la conectividad HTTP a los servicios de prueba que creaste:

    curl https://example.com:8443 --resolve example.com:8443:${IP_ADDRESS} -k
    
  2. El comando devuelve una respuesta de una de las VMs del grupo de instancias administrado. El resultado es similar a lo siguiente:

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

Verifica con una verificación negativa

  1. En el siguiente comando, la SNI no coincide con example.com, por lo que la puerta de enlace rechaza la conexión:

    curl https://invalid-server.com:8443 --resolve invalid-server.com:8443:${IP_ADDRESS} -k
    
  2. En el siguiente comando, ALPN no coincide con h2 (protocolo HTTP2), por lo que la puerta de enlace rechaza la conexión:

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

    Todos los comandos anteriores muestran el siguiente error:

    curl: (35) OpenSSL SSL_connect: Connection reset by peer in connection.
    
  3. En el siguiente comando, el cliente crea una conexión de texto sin formato (sin encriptar), por lo que la puerta de enlace rechaza la conexión con un error 404 Not Found:

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