Cloud Service Mesh regional

Con el aislamiento regional, los clientes que se conecten a una región específica del plano de control de Cloud Service Mesh solo podrán acceder a los recursos de esa región. Del mismo modo, los recursos de API 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:

  • La API de Istio no se admite. No puedes usar Kubernetes con la API de Istio con Traffic Director regional. En esta vista previa, solo se admiten las APIs Google Cloud .
  • Se aplican las consideraciones y limitaciones actuales de las APIs de enrutamiento de servicios globales.
  • La versión mínima de Envoy para admitir esquemas de nomenclatura xdSTP es la 1.31.1.
  • No se admite Gateway for Mesh API.
  • La versión mínima de gRPC es la 1.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 ahora, los precios son los mismos que los globales.

Preparar el cliente xDS para Cloud Service Mesh

Envoy xDS de VM de Compute

Manual

Los pasos manuales se basan en el artículo Configurar máquinas virtuales con el despliegue manual de Envoy. La principal diferencia es que ENVOY_CONTROL_PLANE_REGION se define y se inserta en el bootstrap.

  1. Crea la plantilla de instancia:

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

gRPC xDS de VM de Compute

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

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

En este ejemplo, si se define xds-server-region como us-central1, se determinará automáticamente el endpoint regional de Cloud Service Mesh: trafficdirector.us-central1.rep.googleapis.com:443.

Inyección manual de Envoy en K8s

Los pasos manuales se basan en Configurar pods de Google Kubernetes Engine con la inserción manual de Envoy. Sin embargo, solo tienes que modificar la sección sobre la inyecció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 describen cinco configuraciones y modelos de implementación independientes. Todas estas guías son versiones regionalizadas de las guías de configuración de la API de enrutamiento de servicios global.

Configurar servicios gRPC sin proxy con GRPCRoute regional y Cloud Service Mesh regional

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

Para mayor comodidad, almacena el número de proyecto Google Cloud en el que vas a realizar la configuración, de forma 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"

Sustituye PROJECT_NUMBER por el número de tu proyecto.

También puede sustituir lo siguiente:

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

Configuración de la malla

Cuando una aplicación gRPC sin proxy se conecta a un xds://hostname, la biblioteca de cliente 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 guárdala 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}
    

    Una vez que se haya creado la malla regional, Cloud Service Mesh estará listo para proporcionar la configuración. Sin embargo, como aún no se ha definido ningún servicio, la configuración está vacía.

Configuración de servicios gRPC

Para hacer una demostración, crearás un servicio de backend regional con VMs escaladas automáticamente (mediante grupos de instancias gestionados) que servirá hello world mediante el protocolo gRPC en el puerto 50051.

  1. Crea la plantilla de instancia de VM de Compute Engine con un servicio helloworld gRPC 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 a partir de 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 gRPC. Este es el puerto en el que el servicio gRPC está configurado para escuchar 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 comprobaciones del 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 comprobación del estado de gRPC para que las comprobaciones del estado de gRPC funcionen correctamente. Para obtener más información, consulta el artículo Crear comprobaciones del estado.

  5. Crea una regla de cortafuegos para permitir las conexiones de comprobación del 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 carga INTERNAL_SELF_MANAGED y añade la comprobación de estado y un grupo de instancias gestionado que hayas creado anteriormente al servicio de backend. El puerto especificado en port-name se usa para conectarse a las VMs del grupo de instancias gestionado.

    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. Añade el grupo de instancias gestionado a BackendService:

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

Configurar el enrutamiento con Regional GRPCRoute

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

  1. Crea una especificación de GRPCRoute regional y guárdala 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 la carga del tráfico de los servicios especificados en la ruta gRPC entre los backends del grupo de instancias gestionado.

Crear un servicio de cliente gRPC

Para verificar la configuración, crea una instancia de una aplicación cliente con un plano de datos 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 endpoints asociados a helloworld-gce mediante el URI de servicio xds:///helloworld-gce.

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

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

Configurar 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 define la variable de entorno GRPC_XDS_BOOTSTRAP y usa una secuencia de comandos auxiliar para generar el archivo de arranque. Los valores de TRAFFICDIRECTOR_GCP_PROJECT_NUMBER y de la zona del archivo de arranque generado se obtienen del servidor de metadatos, que conoce estos detalles sobre tus instancias de VM de Compute Engine.

Puede proporcionar estos valores al script auxiliar manualmente mediante la opción -gcp-project-number. Debes proporcionar un nombre de malla que coincida con el recurso de malla mediante la opción -config-mesh-experimental.

  1. Para verificar la configuración, inicia sesión en el cliente:

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

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

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

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

    Greeting: Hello world, from INSTANCE_HOSTNAME
    

De esta forma, se verifica que el cliente de gRPC sin proxy se ha conectado correctamente a Cloud Service Mesh y ha obtenido información sobre los backends del servicio helloworld-gce mediante el resolvedor de nombres xDS. El cliente ha enviado una solicitud a uno de los back-ends del servicio sin necesidad de conocer la dirección IP ni de realizar una resolución de DNS.

Configurar la configuración del proxy sidecar de Envoy con servicios HTTP con HTTPRoute regional y Mesh regional

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

Para mayor comodidad, almacena el número de proyecto Google Cloud en el que vas a realizar la configuración, de forma 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"

Sustituye lo siguiente:

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

También puede sustituir lo siguiente:

  • us-central1 con otra región que quieras usar.
  • us-central1-a con la zona que quieras usar.

Configuración de la malla

El proxy Envoy 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 recibida de Cloud Service Mesh se usa para dirigir el tráfico que pasa por el proxy sidecar a varios servicios de backend regionales en función de los parámetros de solicitud, como el nombre de host o los encabezados, configurados en los recursos de ruta.

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

  1. Crea una especificación de malla regional y guárdala en el archivo mesh.yaml:

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

    Si no se especifica, el puerto de intercepción es 15001 de forma predeterminada.

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

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

    Una vez que se haya creado la malla regional, Cloud Service Mesh estará listo para proporcionar la configuración. Sin embargo, como aún no se ha definido ningún servicio, la configuración estará vacía.

Configuración del servidor HTTP

Para hacer una demostración, crearás un servicio de backend regional con VMs escaladas automáticamente (mediante grupos de instancias gestionadas o MIG) que ofrecerá el mensaje "Hello world" mediante el protocolo gRPC en el puerto 80.

  1. Crea la plantilla de instancia de VM de Compute Engine con un servicio helloworld HTTP expuesto 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 a partir de 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 comprobaciones del estado:

    gcloud compute health-checks create http http-helloworld-health-check --region=${REGION}
    
  4. Crea una regla de cortafuegos para permitir las conexiones de comprobación del 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 carga 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. Añade la comprobación de estado y un grupo de instancias gestionado o no gestionado 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 gestionadas con la plantilla de VM de Compute Engine que ejecuta el servicio HTTP de ejemplo que hemos creado anteriormente.

Configurar el enrutamiento con HTTPRoute regional

Se configuran el recurso de malla y el servidor HTTP. Ahora puedes conectarlos mediante un recurso HTTPRoute que asocia un nombre de host con un servicio de backend.

  1. Crea la especificación 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 el 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 la carga del tráfico de los servicios especificados en HTTPRoute entre los backends del grupo de instancias gestionado.

Crear un cliente HTTP con un sidecar de Envoy

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

    gcloud compute ssh td-vm-client --zone=${ZONE}
    
  2. Verifica la conectividad HTTP con 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 gestionadas con su nombre de host impreso en la consola.

Configurar servicios TCP con TCPRoute regional

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

Para mayor comodidad, almacena el número de proyecto Google Cloud en el que vas a realizar la configuración, de forma 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"

Sustituye lo siguiente:

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

También puede sustituir lo siguiente:

  • us-central1 con otra región que quieras usar.
  • us-central1-a con la zona que quieras usar.

Configuración de la malla

  1. Crea una especificación de malla regional y guárdala 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

Para hacer una demostración, crearás un servicio de backend regional con VMs escaladas automáticamente (mediante grupos de instancias gestionadas o MIG) que ofrecerá el mensaje "hello world" mediante el protocolo gRPC en el puerto 10000.

  1. Crea la plantilla de instancia de VM de Compute Engine con un servicio de prueba en el puerto 10000 mediante 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 a partir de la plantilla:

    gcloud compute instance-groups managed create tcp-td-mig-us-central1 \
      --zone=${ZONE} \
      --size=1 \
      --template=tcp-td-vm-template
    
  3. Define los puertos con nombre del grupo de instancias gestionado que has creado como port 10000:

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

    gcloud compute health-checks create tcp tcp-helloworld-health-check --port 10000 --region=${REGION}
    
  5. Crea una regla de cortafuegos para permitir las conexiones de comprobación del 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 backend regional con un esquema de balanceo de carga INTERNAL_SELF_MANAGED y añade la comprobación del estado y un grupo de instancias gestionado o no gestionado al servicio 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. Añade 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}
    

Configurar el enrutamiento con TCPRoute regional

  1. Crea una especificación de TCPRoute y guárdala 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 un TCPRoute con la especificación tcp_route.yaml:

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

Crear un cliente TCP con un sidecar de Envoy

  1. Crea una VM con Envoy conectada 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. Inicia sesión en la VM creada:

    gcloud compute ssh td-vm-client --zone=${ZONE}
    
  3. Verifica la conectividad con 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 y que te devuelva el servicio netcat que se ejecuta en la máquina virtual remota.

Configuración de la malla regional en el proyecto host

Designa un proyecto como proyecto del host. Cualquier cuenta de servicio que tenga permiso para crear, actualizar o eliminar mallas en este proyecto puede controlar las configuraciones de enrutamiento asociadas a las mallas regionales de este proyecto.

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

    export REGION="us-central1"
    

    También puedes sustituir us-central1 por otra región que quieras usar.

  2. Crea la especificación de la malla y guárdala 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 necesaria:

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

    Anota el URI completo de este recurso de malla. Los propietarios de los servicios lo necesitarán en el futuro para adjuntar sus rutas a esta malla.

  4. Concede el permiso de gestión de identidades y accesos networkservices.meshes.use a esta malla y a las cuentas de servicio entre proyectos que deban 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 tengan el permiso networkservices.meshes.use pueden añadir sus reglas de enrutamiento a esta malla.

Configuración de rutas en proyectos de servicio

Cada propietario de un servicio debe crear servicios de backend regionales y recursos de ruta regionales en su proyecto de forma similar a lo que se explica en el artículo Configurar proxies de Envoy con servicios HTTP. La única diferencia es que cada HTTPRoute, GRPCRoute o TCPRoute tendría el URI del recurso de malla del proyecto host en el campo meshes.

  1. Crea una ruta http de VPC compartida:

    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 servicios de cliente en proyectos de servicio

Al configurar un cliente de Cloud Service Mesh (proxy de Envoy o sin proxy) que se encuentra en un proyecto de servicio, se debe especificar el número del 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 pasarela

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

Un balanceador de carga de red de paso a través externo regional dirige el tráfico a los proxies de Envoy, que actúan como una pasarela de entrada. Los proxies de Envoy usan el enrutamiento de transferencia de TLS y dirigen el tráfico a los servidores HTTPS que se ejecutan en las instancias de VM de backend.

Define algunas variables que se usarán a lo largo del ejemplo.

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

Sustituye lo siguiente: default

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

También puede sustituir lo siguiente:

  • us-central1 con otra región que quieras usar.
  • us-central1-b con la zona que quieras usar.
  • default con el nombre de la red que quieras usar.

Hacer referencias cruzadas a recursos de malla regional y de ruta regional en un entorno de VPC compartida con 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 las implementaciones de VPC compartida o de VPC emparejada, cada propietario de un proyecto puede definir su propio conjunto de servicios con el fin de que estos servicios estén disponibles para el resto de los proyectos.

Esta configuración es "entre proyectos" porque se combinan varios recursos definidos en diferentes proyectos para formar una única configuración que se puede ofrecer a un cliente con o sin proxy.

Configurar reglas de cortafuegos

  1. Configura reglas de cortafuegos para permitir el tráfico de cualquier origen. Edita los comandos de tus puertos y los intervalos 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
    

Configurar permisos de gestión de identidades y accesos

  1. Crea una identidad de cuenta de servicio para los proxies de la pasarela:

    gcloud iam service-accounts create gateway-proxy
    
  2. Asigna los roles de gestión de identidades y accesos 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 pasarela 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 Gateway regional con la especificación gateway8443.yaml:

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

Crear un grupo de instancias gestionado con proxies de Envoy

En esta sección, crearás una plantilla de instancia para una VM que ejecute un proxy de servicio Envoy desplegado automáticamente. Los Envoys tienen el ámbito definido como gateway-proxy. No transmita el puerto de servicio como parámetro de la marca --service-proxy.

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

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

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

Configurar el balanceador de carga de red de paso a través 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 reservada para el balanceador de carga externo:

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

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

    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. Añade el grupo de instancias gestionado 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 la pasarela:

    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}
    

Configurar un grupo de instancias gestionado que ejecute un servicio HTTPS

  1. Crea una plantilla de instancia con un servicio HTTPS expuesto 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 gestionado basado en la plantilla de instancia:

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

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

    gcloud compute health-checks create https https-helloworld-health-check \
      --port=8443 --region=${REGION}
    
  5. Crea una regla de cortafuegos para permitir las conexiones de comprobación del 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 carga INTERNAL_SELF_MANAGED y añade la comprobación del 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. Añada el grupo de instancias gestionado 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}
    

Configurar el enrutamiento con un recurso TLSRoute

  1. En un archivo llamado tls_route.yaml, crea la especificación 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 cambian de la siguiente manera, TLSRoute coincide con SNI o ALPN:

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

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

Validar la implementación

  1. Ejecuta el siguiente comando curl para verificar la conectividad HTTP con los servicios de prueba que has creado:

    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 gestionado. El resultado debería ser similar al 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"
      }
    

Verificar con una verificación negativa

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

    curl https://invalid-server.com:8443 --resolve invalid-server.com:8443:${IP_ADDRESS} -k
    
  2. En el siguiente comando, el 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 devuelven 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 cifrar), por lo que la pasarela rechaza la conexión con un error 404 Not Found:

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