Enrutar el tráfico de los servicios de Cloud Run a las cargas de trabajo de Cloud Service Mesh en GKE

En esta página se muestra cómo enrutar de forma segura el tráfico de red desde servicios de Cloud Run a cargas de trabajo de Cloud Service Mesh en GKE para usar las APIs de Istio y aprovechar un sidecar de Envoy totalmente gestionado.

Antes de empezar

En las siguientes secciones se da por hecho que tienes un clúster de GKE con Cloud Service Mesh habilitado.

Si no tienes ningún servicio de GKE desplegado, usa el siguiente comando para desplegar un servicio de ejemplo:

cat <<EOF > /tmp/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: ads
spec:
  ports:
  - port: 9999
    targetPort: 8000
  selector:
    run: ads
  type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ads
spec:
  replicas: 1
  selector:
    matchLabels:
      run: ads
  template:
    metadata:
      labels:
        run: ads
    spec:
      containers:
      - image: docker.io/waip/simple-http:v1.0.1
        name: my-http2-svc
        ports:
        - protocol: TCP
          containerPort: 8000
      securityContext:
        fsGroup: 1337
EOF
kubectl apply -f /tmp/service.yaml

Configurar un dominio personalizado para hosts de VirtualService

Un servicio virtual define reglas de enrutamiento de tráfico. El tráfico coincidente se envía a un servicio de destino con nombre.

  1. Para crear una zona gestionada, sigue estos pasos:

    gcloud dns managed-zones create ZONE_NAME \
      --description="zone for service mesh routes" \
      --dns-name=DNS_SUFFIX. \
      --networks=default \
      --visibility=private
    

    donde:

    • ZONE_NAME es el nombre de tu zona (por ejemplo, "prod").
    • DNS_SUFFIX es cualquier host DNS válido (por ejemplo, "mesh.private").
  2. Crea un conjunto de registros de recursos:

    IP=10.0.0.1
    gcloud dns record-sets create '*.'"DNS_SUFFIX." --type=A --zone="ZONE_NAME" \
      --rrdatas=10.0.0.1 --ttl 3600
    

    Asegúrate de que la IP (RFC 1918 obligatorio) no se esté usando. También puedes reservar una IP interna estática.

  3. Exporta un VirtualService para clientes externos de Cloud Run:

    cat <<EOF > virtual-service.yaml
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: VIRTUAL_SERVICE_NAME
      namespace: NAMESPACE
    spec:
      hosts:
      - GKE_SERVICE_NAME.DNS_SUFFIX
      gateways:
      - external-mesh
      http:
      - route:
        - destination:
            host: GKE_SERVICE_NAME
    EOF
    kubectl apply -f virtual-service.yaml
    

    donde:

    • VIRTUAL_SERVICE_NAME es el nombre de tu VirtualService.
    • NAMESPACE es default si usas el servicio de ejemplo proporcionado. De lo contrario, sustituye NAMESPACE por el nombre de tu espacio de nombres.
    • GKE_SERVICE_NAME es ads si usas el servicio de ejemplo proporcionado. De lo contrario, sustituye GKE_SERVICE_NAME por el nombre de tu servicio de GKE.

Aunque es posible añadir una pasarela external-mesh como destino a un VirtualService preexistente, debes establecer un VirtualService independiente para exportar un servicio de Kubernetes a clientes externos de Cloud Run. Tener un VirtualService independiente facilita la gestión de los servicios exportados y sus configuraciones sin afectar a los clientes de GKE. Además, algunos campos de VirtualServices no se tienen en cuenta en la malla externa, pero siguen funcionando como se espera en los servicios de GKE.VirtualServices Por lo tanto, puede ser ventajoso gestionar y solucionar problemas de VirtualServices por separado.

Para que los clientes de GKE también reciban la configuración de VirtualService, se debe añadir la pasarela mesh o mesh/default.

El VirtualService externo de la malla debe definirse en el mismo espacio de nombres que el servicio de Kubernetes en el destino VirtualService.

Configurar un servicio de Cloud Run para que se una a una malla de servicios

Para unir un servicio de Cloud Run a una malla de servicios, sigue estos pasos:

  1. Determina el ID de la malla que respalda el clúster de GKE de Cloud Service Mesh:

    MESH=$(kubectl get controlplanerevision --namespace istio-system -o json | jq -r '.items[0].metadata.annotations["mesh.cloud.google.com/external-mesh"]')
    
  2. Despliega un servicio de Cloud Run con el ID de la malla. Asegúrate de conectarte también a la red de VPC del clúster:

    gcloud alpha run deploy --mesh "$MESH" --network default \
      mesh-svc --image=fortio/fortio \
      --region=REGION --project=PROJECT_ID --no-allow-unauthenticated
    
  3. Verifica que el servicio de Cloud Run pueda enviar una solicitud a la carga de trabajo de GKE:

    TEST_SERVICE_URL=$(gcloud run services describe mesh-svc --region REGION --format="value(status.url)" --project=PROJECT_ID)
    
    curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" "$TEST_SERVICE_URL/fortio/fetch/GKE_SERVICE_NAME.DNS_SUFFIX"
    

    La salida debe ser una respuesta HTTP 200 válida.

Solución de problemas

En esta sección se muestra cómo solucionar errores habituales con Cloud Service Mesh y Cloud Run.

Registros de Sidecar de Cloud Run

Los errores de Envoy se registran en Cloud Logging.

Por ejemplo, se registrará un error como el siguiente si no se asigna el rol de cliente trafficdirector a la cuenta de servicio de Cloud Run en el proyecto de malla:

StreamAggregatedResources gRPC config stream to trafficdirector.googleapis.com:443 closed: 7, Permission 'trafficdirector.networks.getConfigs' denied on resource '//trafficdirector.googleapis.com/projects/525300120045/networks/mesh:test-mesh/nodes/003fb3e0c8927482de85f052444d5e1cd4b3956e82b00f255fbea1e114e1c0208dbd6a19cc41694d2a271d1ab04b63ce7439492672de4499a92bb979853935b03d0ad0' (or it may not exist).

CSDS

El estado del cliente de Traffic Director se puede obtener mediante CSDS:

gcloud alpha container fleet mesh debug proxy-status --membership=<CLUSTER_MEMBERSHIP> --location=<CLUSTER_LOCATION>
External Clients:
....

Siguientes pasos