Configurar la seguridad de los servicios con Envoy

Sigue las instrucciones de esta guía para configurar la autenticación y la autorización de los servicios implementados con Cloud Service Mesh y proxies de Envoy. Para obtener información completa sobre la seguridad de los servicios de Cloud Service Mesh, consulta el artículo Seguridad de los servicios de Cloud Service Mesh.

Requisitos

Antes de configurar la seguridad de los servicios de Cloud Service Mesh con Envoy, asegúrate de que tu configuración cumpla los siguientes requisitos:

Prepararse para la configuración

En las siguientes secciones se describen las tareas que debes completar antes de configurar el servicio de seguridad de Cloud Service Mesh. Estas tareas son las siguientes:

  • Actualizar Google Cloud CLI
  • Configurar variables
  • Habilitar las APIs necesarias para que Cloud Service Mesh funcione con el Servicio de Autoridades de Certificación

Actualizar la herramienta de línea de comandos gcloud

Para actualizar Google Cloud CLI, ejecuta lo siguiente en tu máquina local:

gcloud components update

Configurar variables

Define las siguientes variables para poder copiar y pegar código con valores coherentes mientras sigues el ejemplo de este documento. Usa los siguientes valores.

  • PROJECT_ID: sustituye el ID de tu proyecto.
  • CLUSTER_NAME: sustituye el nombre del clúster que quieras usar; por ejemplo, secure-td-cluster.
  • ZONE: sustituye la zona en la que se encuentra tu clúster.
  • GKE_CLUSTER_URL: Sustituir https://container.googleapis.com/v1/projects/PROJECT_ID/locations/ZONE/clusters/CLUSTER_NAME
  • WORKLOAD_POOL: Sustituir PROJECT_ID.svc.id.goog
  • K8S_NAMESPACE: Sustituir default.
  • DEMO_CLIENT_KSA: sustituye el nombre de tu cuenta de servicio de Kubernetes de cliente.
  • DEMO_SERVER_KSA: sustituye el nombre de la cuenta de servicio de Kubernetes de tu servidor.
  • PROJNUM: sustituye el número de proyecto de tu proyecto, que puedes determinar desde la Google Cloud consola o con este comando:

    gcloud projects describe PROJECT_ID --format="value(projectNumber)"
    
  • SA_GKE: Sustituir service-PROJNUM@container-engine-robot.iam.gserviceaccount.com

  • CLUSTER_VERSION: sustituye la versión más reciente disponible. Puedes consultar esta información en las notas de la versión del canal rápido. La versión mínima requerida es 1.21.4-gke.1801. Esta es la versión del clúster de GKE que se va a usar en este ejemplo.

Define los valores aquí:

# Substitute your project ID
PROJECT_ID=PROJECT_ID

# GKE cluster name and zone for this example.
CLUSTER_NAME=CLUSTER_NAME
ZONE=ZONE

# GKE cluster URL derived from the above
GKE_CLUSTER_URL="https://container.googleapis.com/v1/projects/PROJECT_ID/locations/ZONE/clusters/CLUSTER_NAME"

# Workload pool to be used with the GKE cluster
WORKLOAD_POOL="PROJECT_ID.svc.id.goog"

# Kubernetes namespace to run client and server demo.
K8S_NAMESPACE=K8S_NAMESPACE
DEMO_CLIENT_KSA=DEMO_CLIENT_KSA
DEMO_SERVER_KSA=DEMO_SERVER_KSA

# Compute other values
# Project number for your project
PROJNUM=PROJNUM

CLUSTER_VERSION=CLUSTER_VERSION
SA_GKE=service-PROJNUM@container-engine-robot.iam.gserviceaccount.com

Habilitar las APIs

Usa el comando gcloud services enable para habilitar todas las APIs que necesites para configurar la seguridad de Cloud Service Mesh con el Servicio de Autoridades de Certificación.

gcloud services enable \
   container.googleapis.com \
   cloudresourcemanager.googleapis.com \
   compute.googleapis.com \
   trafficdirector.googleapis.com \
   networkservices.googleapis.com \
   networksecurity.googleapis.com \
   privateca.googleapis.com \
   gkehub.googleapis.com

Crear o actualizar un clúster de GKE

La seguridad de los servicios de Cloud Service Mesh depende de la integración del servicio de CA con GKE. El clúster de GKE debe cumplir los siguientes requisitos, además de los requisitos de configuración:

  • Usa una versión de clúster mínima de 1.21.4-gke.1801. Si necesitas funciones que estén en una versión posterior, puedes obtenerla del canal de lanzamiento rápido.
  • El clúster de GKE debe estar habilitado y configurado con certificados de malla, tal como se describe en el artículo Crear autoridades de certificación para emitir certificados.
  1. Crea un clúster que use Workload Identity Federation para GKE. Si vas a actualizar un clúster, ve al siguiente paso. El valor que proporciones para --tags debe coincidir con el nombre que se haya pasado a la marca --target-tags del comando firewall-rules create en la sección Configurar Cloud Service Mesh con componentes de Cloud Load Balancing.

    # Create a GKE cluster with GKE managed mesh certificates.
    gcloud container clusters create CLUSTER_NAME \
      --release-channel=rapid \
      --scopes=cloud-platform \
      --image-type=cos_containerd \
      --machine-type=e2-standard-2 \
      --zone=ZONE \
      --workload-pool=PROJECT_ID.svc.id.goog \
      --enable-mesh-certificates \
      --cluster-version=CLUSTER_VERSION \
      --enable-ip-alias \
      --tags=allow-health-checks \
      --workload-metadata=GKE_METADATA
    

    La creación del clúster puede tardar varios minutos en completarse.

  2. Si utilizas un clúster, activa Workload Identity Federation para GKE y los certificados de malla de GKE. Asegúrate de que el clúster se haya creado con la marca --enable-ip-alias, que no se puede usar con el comando update.

    gcloud container clusters update CLUSTER_NAME \
      --enable-mesh-certificates
    
  3. Ejecuta el siguiente comando para cambiar al nuevo clúster como clúster predeterminado para tus comandos kubectl:

    gcloud container clusters get-credentials CLUSTER_NAME \
      --zone ZONE
    

Despliegue en un entorno de varios clústeres

Si vas a implementar en un entorno de varios clústeres, sigue el procedimiento general descrito en esta sección. En estas instrucciones se da por hecho que los pods de cliente se ejecutan en un clúster y los pods de servidor, en otro.

  1. Crea o actualiza los clústeres siguiendo las instrucciones de la sección anterior.

  2. Captura los intervalos de direcciones IP de los pods de cada clúster con el siguiente comando:

    gcloud compute firewall-rules list \
      --filter="name~gke-{CLUSTER_NAME}-[0-9a-z]*-all" \
      --format="value(sourceRanges)"
    

    Por ejemplo, en el caso de los clústeres cluster-a y cluster-b, los comandos devuelven resultados como los siguientes:

    cluster-a, pod CIDR: 10.4.0.0/14, node network tag: gke-cluster-a-9cd18751-node
    cluster-b, pod CIDR: 10.8.0.0/14, node network tag: gke-cluster-b-acd14479-node
    
  3. Crea reglas de cortafuegos de VPC que permitan que los clústeres se comuniquen entre sí. Por ejemplo, el siguiente comando crea una regla de cortafuegos que permite que las direcciones IP del pod cluster-a se comuniquen con los nodos cluster-b:

    gcloud compute firewall-rules create per-cluster-a-pods \
      --allow="tcp,udp,icmp,esp,ah,sctp" \
      --target-tags="gke-cluster-b-acd14479-node"
    

    El siguiente comando crea una regla de cortafuegos que permite que las cluster-bdirecciones IP de los pods se comuniquen con los nodos cluster-a:

    gcloud compute firewall-rules create per-cluster-b-pods \
      --allow="tcp,udp,icmp,esp,ah,sctp" \
      --target-tags="gke-cluster-a-9cd18751-node"
    

Registrar clústeres en una flota

Registra el clúster que has creado o actualizado en Crear un clúster de GKE con una flota. Si registras el clúster, te resultará más fácil configurar clústeres en varios proyectos.

Ten en cuenta que cada uno de estos pasos puede tardar hasta diez minutos en completarse.

  1. Registra tu clúster en la flota:

    gcloud container fleet memberships register CLUSTER_NAME \
      --gke-cluster=ZONE/CLUSTER_NAME \
      --enable-workload-identity --install-connect-agent \
      --manifest-output-file=MANIFEST-FILE_NAME
    

    Sustituye las variables de la siguiente manera:

    • CLUSTER_NAME: el nombre del clúster.
    • ZONE: la zona de tu clúster.
    • MANIFEST-FILE_NAME: la ruta en la que estos comandos generan el archivo de manifiesto para el registro.

    Si el proceso de registro se completa correctamente, verás un mensaje como el siguiente:

    Finished registering the cluster CLUSTER_NAME with the fleet.
  2. Aplica el archivo de manifiesto generado a tu clúster:

    kubectl apply -f MANIFEST-FILE_NAME
    

    Si el proceso de solicitud se completa correctamente, verás mensajes como los siguientes:

    namespace/gke-connect created
    serviceaccount/connect-agent-sa created
    podsecuritypolicy.policy/gkeconnect-psp created
    role.rbac.authorization.k8s.io/gkeconnect-psp:role created
    rolebinding.rbac.authorization.k8s.io/gkeconnect-psp:rolebinding created
    role.rbac.authorization.k8s.io/agent-updater created
    rolebinding.rbac.authorization.k8s.io/agent-updater created
    role.rbac.authorization.k8s.io/gke-connect-agent-20210416-01-00 created
    clusterrole.rbac.authorization.k8s.io/gke-connect-impersonation-20210416-01-00 created
    clusterrolebinding.rbac.authorization.k8s.io/gke-connect-impersonation-20210416-01-00 created
    clusterrolebinding.rbac.authorization.k8s.io/gke-connect-feature-authorizer-20210416-01-00 created
    rolebinding.rbac.authorization.k8s.io/gke-connect-agent-20210416-01-00 created
    role.rbac.authorization.k8s.io/gke-connect-namespace-getter created
    rolebinding.rbac.authorization.k8s.io/gke-connect-namespace-getter created
    secret/http-proxy created
    deployment.apps/gke-connect-agent-20210416-01-00 created
    service/gke-connect-monitoring created
    secret/creds-gcp create
    
  3. Obtén el recurso de pertenencia del clúster:

    kubectl get memberships membership -o yaml
    

    El resultado debe incluir el grupo de identidades de carga de trabajo asignado por la flota, donde PROJECT_ID es el ID de tu proyecto:

    workload_identity_pool: PROJECT_ID.svc.id.goog
    

    Esto significa que el clúster se ha registrado correctamente.

Crear autoridades de certificación para emitir certificados

Para emitir certificados a tus pods, crea un grupo de Servicio de Autoridades de Certificación y las siguientes autoridades de certificación (ACs):

  • CA raíz. Es la raíz de confianza de todos los certificados de malla emitidos. Puedes usar una CA raíz que ya tengas. Crea la AC raíz en el nivel enterprise, que está pensado para la emisión de certificados de larga duración y bajo volumen.
  • Autoridad de certificación subordinada. Esta CA emite certificados para cargas de trabajo. Crea la CA subordinada en la región en la que se haya desplegado tu clúster. Crea la AC subordinada en el nivel devops, que está diseñado para la emisión de certificados de gran volumen y de corta duración.

Crear una AC subordinada es opcional, pero te recomendamos que lo hagas en lugar de usar tu AC raíz para emitir certificados de malla de GKE. Si decides usar la AC raíz para emitir certificados de malla, asegúrate de que el modo de emisión basado en la configuración predeterminado siga permitido.

La CA subordinada puede estar en una región diferente a la de tu clúster, pero te recomendamos que la crees en la misma región que tu clúster para optimizar el rendimiento. Sin embargo, puedes crear las autoridades de certificación raíz y subordinadas en diferentes regiones sin que esto afecte al rendimiento ni a la disponibilidad.

Estas regiones se admiten en el servicio de autoridades de certificación:

Nombre de la región Descripción de la región
asia-east1 Taiwán
asia-east2 Hong Kong
asia-northeast1 Tokio
asia-northeast2 Osaka
asia-northeast3 Seúl
asia-south1 Bombay
asia-south2 Deli
asia-southeast1 Singapur
asia-southeast2 Yakarta
australia-southeast1 Sídney
australia-southeast2 Melbourne
europe-central2 Varsovia
europe-north1 Finlandia
europe-southwest1 Madrid
europe-west1 Bélgica
europe-west2 Londres
europe-west3 Fráncfort
europe-west4 Países Bajos
europe-west6 Zúrich
europe-west8 Milán
europe-west9 París
europe-west10 Berlín
europe-west12 Turín
me-central1 Doha
me-central2 Dammam
me-west1 Tel Aviv
northamerica-northeast1 Montreal
northamerica-northeast2 Toronto
southamerica-east1 São Paulo
southamerica-west1 Santiago
us-central1 Iowa
us-east1 Carolina del Sur
us-east4 Norte de Virginia
us-east5 Columbus
us-south1 Dallas
us-west1 Oregón
us-west2 Los Ángeles
us-west3 Salt Lake City
us-west4 Las Vegas

También puedes consultar la lista de ubicaciones admitidas ejecutando el siguiente comando:

gcloud privateca locations list
  1. Concede el permiso roles/privateca.caManager de IAM a las personas que creen un grupo de AC y una AC. Ten en cuenta que, en el caso de MEMBER, el formato correcto es user:userid@example.com. Si esa persona es el usuario actual, puedes obtener su ID con el comando de shell $(gcloud auth list --filter=status:ACTIVE --format="value(account)").

    gcloud projects add-iam-policy-binding PROJECT_ID \
      --member=MEMBER \
      --role=roles/privateca.caManager
    
  2. Asigna el rol role/privateca.admin al servicio de CA a las personas que necesiten modificar las políticas de gestión de identidades y accesos, donde MEMBER es una persona que necesita este acceso, en concreto, cualquier persona que realice los pasos que se indican a continuación para asignar los roles privateca.auditor y privateca.certificateManager:

    gcloud projects add-iam-policy-binding PROJECT_ID \
      --member=MEMBER \
      --role=roles/privateca.admin
    
  3. Crea el grupo de servicios de la CA raíz.

    gcloud privateca pools create ROOT_CA_POOL_NAME \
      --location ROOT_CA_POOL_LOCATION \
      --tier enterprise
    
  4. Crea una CA raíz.

    gcloud privateca roots create ROOT_CA_NAME --pool ROOT_CA_POOL_NAME \
      --subject "CN=ROOT_CA_NAME, O=ROOT_CA_ORGANIZATION" \
      --key-algorithm="ec-p256-sha256" \
      --max-chain-length=1 \
      --location ROOT_CA_POOL_LOCATION
    

    Para esta configuración de demostración, utilice los siguientes valores para las variables:

    • ROOT_CA_POOL_NAME=td_sec_pool
    • ROOT_CA_NAME=pkcs2-ca
    • ROOT_CA_POOL_LOCATION=us-east1
    • ROOT_CA_ORGANIZATION="TestCorpLLC"
  5. Crea el grupo subordinado y la AC subordinada. Asegúrate de que el modo de emisión basado en la configuración predeterminado siga permitido.

    gcloud privateca pools create SUBORDINATE_CA_POOL_NAME \
      --location SUBORDINATE_CA_POOL_LOCATION \
      --tier devops
    
    gcloud privateca subordinates create SUBORDINATE_CA_NAME \
      --pool SUBORDINATE_CA_POOL_NAME \
      --location SUBORDINATE_CA_POOL_LOCATION \
      --issuer-pool ROOT_CA_POOL_NAME \
      --issuer-location ROOT_CA_POOL_LOCATION \
      --subject "CN=SUBORDINATE_CA_NAME, O=SUBORDINATE_CA_ORGANIZATION" \
      --key-algorithm "ec-p256-sha256" \
      --use-preset-profile subordinate_mtls_pathlen_0
    

    Para esta configuración de demostración, utilice los siguientes valores para las variables:

    • SUBORDINATE_CA_POOL_NAME="td-ca-pool"
    • SUBORDINATE_CA_POOL_LOCATION=us-east1
    • SUBORDINATE_CA_NAME="td-ca"
    • SUBORDINATE_CA_ORGANIZATION="TestCorpLLC"
    • ROOT_CA_POOL_NAME=td_sec_pool
    • ROOT_CA_POOL_LOCATION=us-east1
  6. Asigna el rol privateca.auditor de gestión de identidades y accesos al grupo de AC raíz para permitir el acceso desde la cuenta de servicio de GKE:

    gcloud privateca pools add-iam-policy-binding ROOT_CA_POOL_NAME \
     --location ROOT_CA_POOL_LOCATION \
     --role roles/privateca.auditor \
     --member="serviceAccount:service-PROJNUM@container-engine-robot.iam.gserviceaccount.com"
    
  7. Concede el rol de gestión de identidades y accesos privateca.certificateManager al grupo de CAs subordinadas para permitir el acceso desde la cuenta de servicio de GKE:

    gcloud privateca pools add-iam-policy-binding SUBORDINATE_CA_POOL_NAME \
      --location SUBORDINATE_CA_POOL_LOCATION \
      --role roles/privateca.certificateManager \
      --member="serviceAccount:service-PROJNUM@container-engine-robot.iam.gserviceaccount.com"
    
  8. Guarda la siguiente configuración WorkloadCertificateConfig YAML para indicar a tu clúster cómo emitir certificados de malla:

    apiVersion: security.cloud.google.com/v1
    kind: WorkloadCertificateConfig
    metadata:
      name: default
    spec:
      # Required. The CA service that issues your certificates.
      certificateAuthorityConfig:
        certificateAuthorityServiceConfig:
          endpointURI: ISSUING_CA_POOL_URI
    
      # Required. The key algorithm to use. Choice of RSA or ECDSA.
      #
      # To maximize compatibility with various TLS stacks, your workloads
      # should use keys of the same family as your root and subordinate CAs.
      #
      # To use RSA, specify configuration such as:
      #   keyAlgorithm:
      #     rsa:
      #       modulusSize: 4096
      #
      # Currently, the only supported ECDSA curves are "P256" and "P384", and the only
      # supported RSA modulus sizes are 2048, 3072 and 4096.
      keyAlgorithm:
        rsa:
          modulusSize: 4096
    
      # Optional. Validity duration of issued certificates, in seconds.
      #
      # Defaults to 86400 (1 day) if not specified.
      validityDurationSeconds: 86400
    
      # Optional. Try to start rotating the certificate once this
      # percentage of validityDurationSeconds is remaining.
      #
      # Defaults to 50 if not specified.
      rotationWindowPercentage: 50
    
    

    Haz los cambios siguientes:

    • El ID del proyecto en el que se ejecuta el clúster:
      PROJECT_ID
    • El URI completo de la AC que emite los certificados de tu malla (ISSUING_CA_POOL_URI). Puede ser tu AC subordinada (opción recomendada) o tu AC raíz. El formato es el siguiente:
      //privateca.googleapis.com/projects/PROJECT_ID/locations/SUBORDINATE_CA_POOL_LOCATION/caPools/SUBORDINATE_CA_POOL_NAME
  9. Guarda la siguiente configuración TrustConfig YAML para indicar a tu clúster cómo confiar en los certificados emitidos:

    apiVersion: security.cloud.google.com/v1
    kind: TrustConfig
    metadata:
      name: default
    spec:
      # You must include a trustStores entry for the trust domain that
      # your cluster is enrolled in.
      trustStores:
      - trustDomain: PROJECT_ID.svc.id.goog
        # Trust identities in this trustDomain if they appear in a certificate
        # that chains up to this root CA.
        trustAnchors:
        - certificateAuthorityServiceURI: ROOT_CA_POOL_URI
    

    Haz los cambios siguientes:

    • El ID del proyecto en el que se ejecuta el clúster:
      PROJECT_ID
    • El URI completo del grupo de AC raíz (ROOT_CA_POOL_URI). El formato es el siguiente:
      //privateca.googleapis.com/projects/PROJECT_ID/locations/ROOT_CA_POOL_LOCATION/caPools/ROOT_CA_POOL_NAME
  10. Aplica las configuraciones a tu clúster:

    kubectl apply -f WorkloadCertificateConfig.yaml
    kubectl apply -f TrustConfig.yaml
    

Configurar la gestión de identidades y accesos

Para crear los recursos necesarios para la configuración, debe tener el rol compute.NetworkAdmin. Este rol contiene todos los permisos necesarios para crear, actualizar, eliminar, enumerar y usar (es decir, hacer referencia a este en otros recursos) los recursos necesarios. Si eres el propietario y editor de tu proyecto, tienes este rol automáticamente.

Ten en cuenta que networksecurity.googleapis.com.clientTlsPolicies.use y networksecurity.googleapis.com.serverTlsPolicies.use no se aplican cuando haces referencia a estos recursos en el servicio de backend.

Si estos permisos se aplican en el futuro y usas el rol compute.NetworkAdmin, no notarás ningún problema cuando se aplique esta comprobación.

Si usas roles personalizados y esta comprobación se aplica en el futuro, debes incluir el permiso .use correspondiente. De lo contrario, en el futuro, es posible que tu rol personalizado no tenga los permisos necesarios para hacer referencia a clientTlsPolicy o serverTlsPolicy desde el servicio backend o la política de endpoint.

Las siguientes instrucciones permiten que la cuenta de servicio predeterminada acceda a la API Cloud Service Mesh Security y cree las cuentas de servicio de Kubernetes.

  1. Configura IAM para permitir que la cuenta de servicio predeterminada acceda a la API de seguridad de Cloud Service Mesh.

    GSA_EMAIL=$(gcloud iam service-accounts list --format='value(email)' \
       --filter='displayName:Compute Engine default service account')
    
    gcloud projects add-iam-policy-binding PROJECT_ID \
      --member serviceAccount:${GSA_EMAIL} \
      --role roles/trafficdirector.client
    
  2. Configura cuentas de servicio de Kubernetes. Las implementaciones de cliente y servidor de las secciones siguientes usan los nombres de Kubernetes de las cuentas de servicio del servidor y del cliente.

    kubectl create serviceaccount --namespace K8S_NAMESPACE DEMO_SERVER_KSA
    kubectl create serviceaccount --namespace K8S_NAMESPACE DEMO_CLIENT_KSA
    
  3. Permite que las cuentas de servicio de Kubernetes suplanten la identidad de la cuenta de servicio predeterminada de Compute Engine creando un enlace de política de gestión de identidades y accesos entre ambas. Esta vinculación permite que la cuenta de servicio de Kubernetes actúe como la cuenta de servicio predeterminada de Compute Engine.

    gcloud iam service-accounts add-iam-policy-binding  \
      --role roles/iam.workloadIdentityUser \
      --member "serviceAccount:PROJECT_ID.svc.id.goog[K8S_NAMESPACE/DEMO_SERVER_KSA]" ${GSA_EMAIL}
    
    gcloud iam service-accounts add-iam-policy-binding  \
      --role roles/iam.workloadIdentityUser  \
      --member "serviceAccount:PROJECT_ID.svc.id.goog[K8S_NAMESPACE/DEMO_CLIENT_KSA]" ${GSA_EMAIL}
    
  4. Anota las cuentas de servicio de Kubernetes para asociarlas con la cuenta de servicio predeterminada de Compute Engine.

    kubectl annotate --namespace K8S_NAMESPACE \
      serviceaccount DEMO_SERVER_KSA \
      iam.gke.io/gcp-service-account=${GSA_EMAIL}
    
    kubectl annotate --namespace K8S_NAMESPACE \
      serviceaccount DEMO_CLIENT_KSA \
      iam.gke.io/gcp-service-account=${GSA_EMAIL}
    

Configurar Cloud Service Mesh

Sigue estas instrucciones para instalar el inyector sidecar, configurar un servicio de prueba y completar otras tareas de implementación.

Instalar el inyector adicional de Envoy en el clúster

Sigue las instrucciones de las dos secciones siguientes de la guía de configuración de Cloud Service Mesh para pods de GKE con inyección automática de Envoy para desplegar y habilitar la inyección de sidecar de Envoy en tu clúster:

Asegúrate de completar ambos conjuntos de instrucciones antes de configurar un servicio de prueba.

Configurar un servicio de prueba

Después de instalar el inyector de sidecar de Envoy, sigue estas instrucciones para configurar un servicio de prueba para tu implementación.

wget -q -O -  https://storage.googleapis.com/traffic-director/security/ga/service_sample.yaml | sed -e s/DEMO_SERVER_KSA_PLACEHOLDER/DEMO_SERVER_KSA/g > service_sample.yaml

kubectl apply -f service_sample.yaml

El archivo service_sample.yaml contiene el archivo podspec de tu aplicación de servidor de demostración. Hay algunas anotaciones específicas de la seguridad de Cloud Service Mesh.

Metadatos de proxy de Cloud Service Mesh

El archivo podspec especifica la anotación proxyMetadata:

spec:
...
      annotations:
        cloud.google.com/proxyMetadata: '{"app": "payments"}'
...

Cuando se inicializa el pod, el proxy adicional recoge esta anotación y la transmite a Cloud Service Mesh. Cloud Service Mesh puede usar esta información para devolver una configuración filtrada:

  • Más adelante en esta guía, verás que la política de endpoint especifica un matcher de endpoint.
  • El matcher de endpoint especifica que solo los clientes que presenten una etiqueta con el nombre app y el valor payments recibirán la configuración filtrada.

Usar certificados y claves de malla firmados por el Servicio de Autoridades de Certificación

El archivo podspec especifica la anotación enableManagedCerts:

spec:
...
      annotations:
        ...
        cloud.google.com/enableManagedCerts: "true"
...

Cuando se inicializa el pod, los certificados y las claves firmados por el servicio de AC se montan automáticamente en el sistema de archivos del proxy sidecar local.

Configurar el puerto de intercepción del tráfico entrante

El archivo podspec especifica la anotación includeInboundPorts:

spec:
...
      annotations:
        ...
        cloud.google.com/includeInboundPorts: "8000"
...

Es el puerto en el que tu aplicación de servidor escucha las conexiones. Cuando se inicializa el pod, el proxy sidecar recoge esta anotación y la transmite a Cloud Service Mesh. Cloud Service Mesh puede usar esta información para enviar una configuración filtrada que intercepte todo el tráfico entrante a este puerto y pueda aplicar políticas de seguridad.

El puerto de comprobación del estado debe ser diferente del puerto de la aplicación. De lo contrario, se aplicarán las mismas políticas de seguridad a las conexiones entrantes al puerto de comprobación de estado, lo que puede provocar que se rechacen las conexiones y que el servidor se marque incorrectamente como no disponible.

Configurar servicios de GKE con NEGs

Los servicios de GKE deben exponerse a través de grupos de puntos finales de red (NEGs) para que puedas configurarlos como backends de un servicio de backend de Cloud Service Mesh. El paquete service_sample.yaml que se proporciona con esta guía de configuración usa el nombre de NEG service-test-neg en la siguiente anotación:

...
metadata:
  annotations:
    cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "service-test-neg"}}}'
spec:
  ports:
  - port: 80
    name: service-test
    protocol: TCP
    targetPort: 8000

No es necesario que cambies el archivo service_sample.yaml.

Guarda el nombre del NEG.

Guarda el nombre del NEG en la variable NEG_NAME:

NEG_NAME="service-test-neg"

Desplegar una aplicación cliente en GKE

Ejecuta el siguiente comando para iniciar un cliente de demostración con un proxy de Envoy como sidecar, que necesitas para demostrar las funciones de seguridad.

wget -q -O -  https://storage.googleapis.com/traffic-director/security/ga/client_sample.yaml | sed -e s/DEMO_CLIENT_KSA_PLACEHOLDER/DEMO_CLIENT_KSA/g > client_sample.yaml

kubectl apply -f client_sample.yaml

El archivo podspec del cliente solo incluye la anotación enableManagedCerts. Es necesario para montar los volúmenes necesarios para los certificados y las claves de la malla gestionada de GKE, que están firmados por la instancia del servicio de AC.

Configurar recursos de comprobación del estado, reglas de cortafuegos y servicios de backend

En esta sección, crearás recursos de comprobación del estado, reglas de cortafuegos y servicios backend para Cloud Service Mesh.

  1. Crea la comprobación del estado.

    gcloud compute health-checks create http td-gke-health-check \
      --use-serving-port
    
  2. Crea la regla de cortafuegos para permitir los intervalos de direcciones IP del comprobador de estado.

    gcloud compute firewall-rules create fw-allow-health-checks \
       --action ALLOW \
       --direction INGRESS \
       --source-ranges 35.191.0.0/16,130.211.0.0/22 \
      --rules tcp
    
  3. Crea el servicio de backend y asocia la comprobación del estado al servicio de backend.

    gcloud compute backend-services create td-gke-service \
      --global \
      --health-checks td-gke-health-check \
      --load-balancing-scheme INTERNAL_SELF_MANAGED
    
  4. Añade el NEG que has creado anteriormente como backend al servicio de backend.

    gcloud compute backend-services add-backend td-gke-service \
      --global \
      --network-endpoint-group ${NEG_NAME} \
      --network-endpoint-group-zone ZONE \
      --balancing-mode RATE \
     --max-rate-per-endpoint 5
    

Configurar recursos de Mesh y HTTPRoute

En esta sección, crearás recursos Mesh y HTTPRoute.

  1. Crea la especificación de recursos Mesh y guárdala en un archivo llamado mesh.yaml.

    name: sidecar-mesh
    interceptionPort: 15001
    

    El puerto de intercepción es 15001 de forma predeterminada si no lo especificas en el archivo mesh.yaml.

  2. Crea el recurso Mesh con la especificación mesh.yaml.

    gcloud network-services meshes import sidecar-mesh \
      --source=mesh.yaml \
      --location=global
    
  3. Crea la especificación HTTPRoute y guárdala en un archivo llamado http_route.yaml.

    Puedes usar PROJECT_ID o PROJECT_NUMBER.

    name: helloworld-http-route
    hostnames:
    - service-test
    meshes:
    - projects/PROJNUM/locations/global/meshes/sidecar-mesh
    rules:
    - action:
       destinations:
       - serviceName: "projects/PROJNUM/locations/global/backendServices/td-gke-service"
    
  4. Crea el recurso HTTPRoute con la especificación del archivo http_route.yaml.

    gcloud network-services http-routes import helloworld-http-route \
      --source=http_route.yaml \
      --location=global
    

La configuración de Cloud Service Mesh se ha completado y ahora puedes configurar políticas de autenticación y autorización.

Configurar la seguridad de servicio a servicio

Sigue las instrucciones de las secciones siguientes para configurar la seguridad de servicio a servicio.

Habilitar mTLS en la malla

Para configurar mTLS en tu malla, debes proteger el tráfico saliente al servicio de backend y el tráfico entrante al endpoint.

Formato de las referencias de la política

Ten en cuenta el siguiente formato obligatorio para hacer referencia a TLS de servidor, TLS de cliente y políticas de autorización:

projects/PROJECT_ID/locations/global/[serverTlsPolicies|clientTlsPolicies|authorizationPolicies]/[server-tls-policy|client-mtls-policy|authz-policy]

Por ejemplo:

projects/PROJECT_ID/locations/global/serverTlsPolicies/server-tls-policy
projects/PROJECT_ID/locations/global/clientTlsPolicies/client-mtls-policy
projects/PROJECT_ID/locations/global/authorizationPolicies/authz-policy

Proteger el tráfico saliente al servicio de backend

Para proteger el tráfico saliente, primero debes crear una política de TLS de cliente que haga lo siguiente:

  • Usa google_cloud_private_spiffe como complemento de clientCertificate, que programa Envoy para usar certificados de malla gestionados por GKE como identidad de cliente.
  • Usa google_cloud_private_spiffe como complemento de serverValidationCa que programa Envoy para usar certificados de malla gestionados por GKE para la validación de servidores.

A continuación, adjunta la política de TLS de cliente al servicio de backend. Esto hace lo siguiente:

  • Aplica la política de autenticación de la política de TLS de cliente a las conexiones salientes con los endpoints del servicio de backend.
  • Los SANs (nombres alternativos del sujeto) indican al cliente que afirme la identidad exacta del servidor al que se está conectando.
  1. Crea la política de TLS de cliente en un archivo client-mtls-policy.yaml:

    name: "client-mtls-policy"
    clientCertificate:
      certificateProviderInstance:
        pluginInstance: google_cloud_private_spiffe
    serverValidationCa:
    - certificateProviderInstance:
        pluginInstance: google_cloud_private_spiffe
    
  2. Importa la política de TLS de cliente:

    gcloud network-security client-tls-policies import client-mtls-policy \
        --source=client-mtls-policy.yaml --location=global
    
  3. Adjunta la política de TLS de cliente al servicio de backend. De esta forma, se aplica la autenticación mTLS en todas las solicitudes salientes del cliente a este servicio backend.

    gcloud compute backend-services export td-gke-service \
        --global --destination=demo-backend-service.yaml
    

    Añade las siguientes líneas a demo-backend-service.yaml:

    securitySettings:
      clientTlsPolicy: projects/PROJECT_ID/locations/global/clientTlsPolicies/client-mtls-policy
      subjectAltNames:
        - "spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA"
    
  4. Importa los valores:

    gcloud compute backend-services import td-gke-service \
        --global --source=demo-backend-service.yaml
    
  5. También puedes ejecutar el siguiente comando para comprobar si la solicitud falla. Se trata de un error esperado, ya que el cliente espera certificados del endpoint, pero este no está programado con una política de seguridad.

    # Get the name of the Podrunning Busybox.
    BUSYBOX_POD=$(kubectl get po -l run=client -o=jsonpath='{.items[0].metadata.name}')
    
    # Command to execute that tests connectivity to the service service-test.
    TEST_CMD="wget -q -O - service-test; echo"
    
    # Execute the test command on the pod.
    kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"
    

    Verás un resultado como este:

    wget: server returned error: HTTP/1.1 503 Service Unavailable
    

Proteger el tráfico entrante al endpoint

Para proteger el tráfico entrante, primero debes crear una política de TLS de servidor que haga lo siguiente:

  • Usa google_cloud_private_spiffe como complemento de serverCertificate, que programa Envoy para usar certificados de malla gestionados por GKE como identidad de servidor.
  • Usa google_cloud_private_spiffe como complemento de clientValidationCa, que programa Envoy para usar certificados de malla gestionados por GKE para la validación de clientes.
  1. Guarda los valores de la política TLS del servidor en un archivo llamado server-mtls-policy.yaml.

    name: "server-mtls-policy"
    serverCertificate:
      certificateProviderInstance:
        pluginInstance: google_cloud_private_spiffe
    mtlsPolicy:
      clientValidationCa:
      - certificateProviderInstance:
          pluginInstance: google_cloud_private_spiffe
    
  2. Crea la política TLS del servidor:

    gcloud network-security server-tls-policies import server-mtls-policy \
        --source=server-mtls-policy.yaml --location=global
    
  3. Crea un archivo llamado ep_mtls.yaml que contenga el matcher de endpoints y adjunta la política de TLS del servidor.

    endpointMatcher:
      metadataLabelMatcher:
        metadataLabelMatchCriteria: MATCH_ALL
        metadataLabels:
        - labelName: app
          labelValue: payments
    name: "ep"
    serverTlsPolicy: projects/PROJECT_ID/locations/global/serverTlsPolicies/server-mtls-policy
    type: SIDECAR_PROXY
    
  4. Importa el matcher de endpoints.

    gcloud network-services endpoint-policies import ep \
        --source=ep_mtls.yaml --location=global
    

Validar la configuración

Ejecuta el siguiente comando curl. Si la solicitud se completa correctamente, verás x-forwarded-client-cert en el resultado. El encabezado se imprime solo cuando la conexión es una conexión mTLS.

# Get the name of the Podrunning Busybox.
BUSYBOX_POD=$(kubectl get po -l run=client -o=jsonpath='{.items[0].metadata.name}')

# Command to execute that tests connectivity to the service service-test.
TEST_CMD="wget -q -O - service-test; echo"

# Execute the test command on the pod.
kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"

Verás un resultado como el siguiente:

GET /get HTTP/1.1
Host: service-test
content-length: 0
x-envoy-internal: true
accept: */*
x-forwarded-for: 10.48.0.6
x-envoy-expected-rq-timeout-ms: 15000
user-agent: curl/7.35.0
x-forwarded-proto: http
x-request-id: redacted
x-forwarded-client-cert: By=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA;Hash=Redacted;Subject="Redacted;URI=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA

Ten en cuenta que la cabecera x-forwarded-client-cert la inserta el Envoy del lado del servidor y contiene su propia identidad (servidor) y la identidad del cliente de origen. Como vemos las identidades del cliente y del servidor, esta es una señal de una conexión mTLS.

Configurar el acceso a nivel de servicio con una política de autorización

Estas instrucciones crean una política de autorización que permite las solicitudes enviadas por la cuenta DEMO_CLIENT_KSA en la que el nombre de host es service-test, el puerto es 8000 y el método HTTP es GET. Antes de crear políticas de autorización, lea la advertencia de la sección Restringir el acceso mediante la autorización.

  1. Crea una política de autorización creando un archivo llamado authz-policy.yaml.

    action: ALLOW
    name: authz-policy
    rules:
    - sources:
      - principals:
        - spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA
      destinations:
      - hosts:
        - service-test
        ports:
        - 8000
        methods:
        - GET
    
  2. Importa la política:

    gcloud network-security authorization-policies import authz-policy \
      --source=authz-policy.yaml \
      --location=global
    
  3. Actualiza la política de endpoint para que haga referencia a la nueva política de autorización añadiendo lo siguiente al archivo ep_mtls.yaml:

    authorizationPolicy: projects/PROJECT_ID/locations/global/authorizationPolicies/authz-policy
    

    La política de endpoint ahora especifica que tanto mTLS como la política de autorización deben aplicarse a las solicitudes entrantes a los pods cuyos proxies sidecar de Envoy presenten la etiqueta app:payments.

  4. Importa la política:

    gcloud network-services endpoint-policies import ep \
        --source=ep_mtls.yaml --location=global
    

Validar la configuración

Ejecuta los siguientes comandos para validar la configuración.

# Get the name of the Podrunning Busybox.
BUSYBOX_POD=$(kubectl get po -l run=client -o=jsonpath='{.items[0].metadata.name}')

# Command to execute that tests connectivity to the service service-test.
# This is a valid request and will be allowed.
TEST_CMD="wget -q -O - service-test; echo"

# Execute the test command on the pod.
kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"

El resultado esperado es similar al siguiente:

GET /get HTTP/1.1
Host: service-test
content-length: 0
x-envoy-internal: true
accept: */*
x-forwarded-for: redacted
x-envoy-expected-rq-timeout-ms: 15000
user-agent: curl/7.35.0
x-forwarded-proto: http
x-request-id: redacted
x-forwarded-client-cert: By=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA;Hash=Redacted;Subject="Redacted;URI=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA

Ejecuta los siguientes comandos para comprobar si la política de autorización rechaza correctamente las solicitudes no válidas:

# Failure case
# Command to execute that tests connectivity to the service service-test.
# This is an invalid request and server will reject because the server
# authorization policy only allows GET requests.
TEST_CMD="wget -q -O - service-test --post-data='' ; echo"

# Execute the test command on the pod.
kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"

El resultado esperado es similar al siguiente:

<RBAC: access denied HTTP/1.1 403 Forbidden>

Configurar la seguridad de la pasarela de entrada

En esta sección se da por hecho que has completado la sección sobre seguridad entre servicios, lo que incluye configurar tu clúster de GKE con el inyector automático de sidecar, crear una autoridad de certificación y crear una política de endpoint.

En esta sección, desplegarás un proxy de Envoy como una pasarela de entrada que finaliza las conexiones TLS y autoriza las solicitudes de los clientes internos de un clúster.

Finalización de TLS en una pasarela de entrada (haga clic para ampliar)
Finalización de TLS en una pasarela de entrada (haz clic en la imagen para ampliarla)

Para configurar una pasarela de entrada que termine la conexión TLS, haz lo siguiente:

  1. Despliega un servicio de Kubernetes al que se pueda acceder mediante una dirección IP interna del clúster.
    1. El despliegue consta de un proxy de Envoy independiente que se expone como un servicio de Kubernetes y se conecta a Cloud Service Mesh.
  2. Crea una política de TLS de servidor para finalizar TLS.
  3. Crea una política de autorización para autorizar las solicitudes entrantes.

Desplegar un servicio de pasarela de entrada en GKE

Ejecuta el siguiente comando para desplegar el servicio de pasarela de entrada en GKE:

wget -q -O -  https://storage.googleapis.com/traffic-director/security/ga/gateway_sample_xdsv3.yaml | sed -e s/PROJECT_NUMBER_PLACEHOLDER/PROJNUM/g | sed -e s/NETWORK_PLACEHOLDER/default/g | sed -e s/DEMO_CLIENT_KSA_PLACEHOLDER/DEMO_CLIENT_KSA/g > gateway_sample.yaml

kubectl apply -f gateway_sample.yaml

El archivo gateway_sample.yaml es la especificación de la pasarela de entrada. En las siguientes secciones se describen algunas adiciones a la especificación.

Inhabilitar la inyección de sidecar de Cloud Service Mesh

La especificación gateway_sample.yaml despliega un proxy de Envoy como único contenedor. En los pasos anteriores, Envoy se insertó como un contenedor auxiliar en un contenedor de aplicación. Para evitar que varios Envoys gestionen las solicitudes, puedes inhabilitar la inyección de sidecar en este servicio de Kubernetes con la siguiente instrucción:

sidecar.istio.io/inject: "false"

Montar el volumen correcto

La especificación gateway_sample.yaml monta el volumen gke-workload-certificates. Este volumen también se usa en la implementación de sidecar, pero el inyector de sidecar lo añade automáticamente cuando ve la anotación cloud.google.com/enableManagedCerts: "true". El gke-workload-certificates volumen contiene los certificados y las claves SPIFFE gestionados por GKE que están firmados por la instancia del servicio de CA que has configurado.

Definir la dirección IP interna del clúster

Configura la pasarela de entrada con un servicio de tipo ClusterInternal. De esta forma, se crea un nombre de host DNS que se puede resolver internamente para mesh-gateway. Cuando un cliente envía una solicitud a mesh-gateway:443, Kubernetes dirige inmediatamente la solicitud al puerto de la implementación de la pasarela de entrada Envoy 8080.

Habilitar TLS en una pasarela de entrada

Sigue estas instrucciones para habilitar TLS en una pasarela de entrada.

  1. Crea un recurso de política de TLS de servidor para finalizar las conexiones TLS, con los valores de un archivo llamado server-tls-policy.yaml:

    description: tls server policy
    name: server-tls-policy
    serverCertificate:
      certificateProviderInstance:
        pluginInstance: google_cloud_private_spiffe
    
  2. Importa la política TLS del servidor:

    gcloud network-security server-tls-policies import server-tls-policy \
        --source=server-tls-policy.yaml --location=global
    
  3. Crea un nuevo destino Gateway y guárdalo en el archivo td-gke-gateway.yaml. De esta forma, se adjunta la política de TLS del servidor y se configura la puerta de enlace de entrada del proxy de Envoy para que termine el tráfico TLS entrante.

    name: td-gke-gateway
    scope: gateway-proxy
    ports:
    - 8080
    type: OPEN_MESH
    serverTlsPolicy: projects/PROJECT_ID/locations/global/serverTlsPolicies/server-tls-policy
    
  4. Importa la pasarela:

    gcloud network-services gateways import td-gke-gateway \
      --source=td-gke-gateway.yaml \
      --location=global
    
  5. Crea y guarda un nuevo HTTPRoute llamado td-gke-route que haga referencia a la pasarela y dirija todas las solicitudes a td-gke-service.

    name: td-gke-route
    hostnames:
    - mesh-gateway
    gateways:
    - projects/PROJECT_NUMBER/locations/global/gateways/td-gke-gateway
    rules:
    - action:
        destinations:
        - serviceName: "projects/PROJECT_NUMBER/locations/global/backendServices/td-gke-service"
    
  6. Importa el HTTPRoute:

    gcloud network-services http-routes import td-gke-route \
      --source=td-gke-route.yaml \
      --location=global
    
    
  7. De forma opcional, actualiza la política de autorización en los back-ends para permitir solicitudes cuando se cumplan todas las condiciones siguientes:

    • Solicitudes enviadas por DEMO_CLIENT_KSA. La implementación de la pasarela de entrada usa la cuenta de servicio DEMO_CLIENT_KSA.
    • Solicitudes con el host mesh-gateway o service-test
    • Puerto: 8000

    No es necesario ejecutar estos comandos a menos que hayas configurado una política de autorización para tus back-ends. Si no hay ninguna política de autorización en el endpoint o no contiene ninguna coincidencia de host o de principal de origen en la política de autorización, las solicitudes se permiten sin este paso. Añade estos valores a authz-policy.yaml.

    action: ALLOW
    name: authz-policy
    rules:
    - sources:
      - principals:
        - spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA
      destinations:
      - hosts:
        - service-test
        - mesh-gateway
        ports:
        - 8000
        methods:
        - GET
    
  8. Importa la política:

    gcloud network-security authorization-policies import authz-policy \
      --source=authz-policy.yaml \
      --location=global
    

Validar la implementación de la pasarela de entrada

Usa un nuevo contenedor llamado debug para enviar solicitudes a la puerta de enlace de entrada para validar la implementación.

En la siguiente especificación, la anotación "sidecar.istio.io/inject":"false" impide que el inyector de sidecar de Cloud Service Mesh inserte automáticamente un proxy de sidecar. No hay ningún sidecar que ayude al contenedor debug a enrutar las solicitudes. El contenedor debe conectarse a la pasarela de entrada para enrutar.

La especificación incluye la marca --no-check-certificate, que ignora la validación del certificado del servidor. El contenedor debug no tiene los certificados de validación de la autoridad de certificación necesarios para validar los certificados firmados por el servicio de la autoridad de certificación que usa la pasarela de entrada para finalizar TLS.

En un entorno de producción, te recomendamos que descargues el certificado de validación del servicio de AC y lo montes o instales en tu cliente. Después de instalar el certificado de validación, elimina la opción --no-check-certificate del comando wget.

Ejecuta el siguiente comando:

kubectl run -i --tty --rm debug --image=busybox --restart=Never  --overrides='{ "metadata": {"annotations": { "sidecar.istio.io/inject":"false" } } }'  -- /bin/sh -c "wget --no-check-certificate -qS -O - https://mesh-gateway; echo"

Verá un resultado similar a este:

GET / HTTP/1.1
Host: 10.68.7.132
x-forwarded-client-cert: By=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA;Hash=Redacted;Subject="Redacted;URI=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA
x-envoy-expected-rq-timeout-ms: 15000
x-envoy-internal: true
x-request-id: 5ae429e7-0e18-4bd9-bb79-4e4149cf8fef
x-forwarded-for: 10.64.0.53
x-forwarded-proto: https
content-length: 0
user-agent: Wget

Ejecuta el siguiente comando de prueba negativa:

# Negative test
# Expect this to fail because gateway expects TLS.
kubectl run -i --tty --rm debug --image=busybox --restart=Never  --overrides='{ "metadata": {"annotations": { "sidecar.istio.io/inject":"false" } } }'  -- /bin/sh -c "wget --no-check-certificate -qS -O - http://mesh-gateway:443/headers; echo"

Verá un resultado similar al siguiente:

wget: error getting response: Connection reset by peer

Ejecuta el siguiente comando de prueba negativa:

# Negative test.
# AuthorizationPolicy applied on the endpoints expect a GET request. Otherwise
# the request is denied authorization.
kubectl run -i --tty --rm debug --image=busybox --restart=Never  --overrides='{ "metadata": {"annotations": { "sidecar.istio.io/inject":"false" } } }'  -- /bin/sh -c "wget --no-check-certificate -qS -O - https://mesh-gateway --post-data=''; echo"

Verá un resultado similar al siguiente:

HTTP/1.1 403 Forbidden
wget: server returned error: HTTP/1.1 403 Forbidden

Eliminar el despliegue

También puedes ejecutar estos comandos para eliminar el despliegue que has creado con esta guía.

Para eliminar el clúster, ejecuta este comando:

gcloud container clusters delete CLUSTER_NAME --zone ZONE --quiet

Para eliminar los recursos que has creado, ejecuta estos comandos:

gcloud compute backend-services delete td-gke-service --global --quiet
cloud compute network-endpoint-groups delete service-test-neg --zone ZONE --quiet
gcloud compute firewall-rules delete fw-allow-health-checks --quiet
gcloud compute health-checks delete td-gke-health-check --quiet
gcloud network-services endpoint-policies delete ep \
    --location=global --quiet
gcloud network-security authorization-policies delete authz-gateway-policy \
   --location=global --quiet
gcloud network-security authorization-policies delete authz-policy \
    --location=global --quiet
gcloud network-security client-tls-policies delete client-mtls-policy \
    --location=global --quiet
gcloud network-security server-tls-policies delete server-tls-policy \
    --location=global --quiet
gcloud network-security server-tls-policies delete server-mtls-policy \
    --location=global --quiet

Limitaciones

La seguridad de los servicios de Cloud Service Mesh solo se admite en GKE. No puedes implementar la seguridad de los servicios con Compute Engine.

Solución de problemas

En esta sección se explica cómo solucionar los problemas que puedan surgir durante la configuración del servicio de seguridad.

Errores de conexión

Si la conexión falla con un error upstream connect o disconnect/reset before headers, examina los registros de Envoy, donde puede que veas uno de los siguientes mensajes de registro:

gRPC config stream closed: 5, Requested entity was not found

gRPC config stream closed: 2, no credential token is found

Si ves estos errores en el registro de Envoy, es probable que el token de la cuenta de servicio se haya montado incorrectamente o que esté usando un audience diferente, o ambas cosas.

Para obtener más información, consulta el artículo Los mensajes de error de los registros de Envoy indican que hay un problema de configuración.

No se han creado pods

Para solucionar este problema, consulta el artículo Solucionar problemas de despliegues automáticos de pods de GKE.

Envoy no se autentica con Cloud Service Mesh

Cuando Envoy (envoy-proxy) se conecta a Cloud Service Mesh para obtener la configuración de xDS, usa Workload Identity Federation para GKE y la cuenta de servicio predeterminada de la VM de Compute Engine (a menos que se haya cambiado el bootstrap). Si falla la autenticación, Envoy no pasará al estado listo.

No se puede crear un clúster con --workload-identity-certificate-authority flag

Si ves este error, asegúrate de que estás usando la versión más reciente de la CLI de Google Cloud:

gcloud components update

Los pods permanecen en estado pendiente

Si los pods permanecen en estado pendiente durante el proceso de configuración, aumenta los recursos de CPU y memoria de los pods en la especificación de tu implementación.

No se puede crear un clúster con la marca --enable-mesh-certificates

Asegúrate de que estás usando la versión más reciente de la CLI de gcloud:

gcloud components update

Ten en cuenta que la marca --enable-mesh-certificates solo funciona con gcloud beta.

Los pods no se inician

Es posible que los pods que usan certificados de malla de GKE no se inicien si falla el aprovisionamiento de certificados. Esto puede ocurrir en situaciones como las siguientes:

  • La configuración de WorkloadCertificateConfig o TrustConfig no es correcta o falta.
  • No se aprueban las CSRs.

Para comprobar si el aprovisionamiento de certificados está fallando, consulta los eventos de Pod.

  1. Comprueba el estado de tu Pod:

    kubectl get pod -n POD_NAMESPACE POD_NAME
    

    Haz los cambios siguientes:

    • POD_NAMESPACE: el espacio de nombres de tu pod.
    • POD_NAME: el nombre de tu Pod.
  2. Para consultar los eventos recientes de tu Pod, sigue estos pasos:

    kubectl describe pod -n POD_NAMESPACE POD_NAME
    
  3. Si el aprovisionamiento de certificados falla, verás un evento con Type=Warning, Reason=FailedMount y From=kubelet, así como un campo Message que empieza por MountVolume.SetUp failed for volume "gke-workload-certificates". El campo Message contiene información para solucionar problemas.

    Events:
      Type     Reason       Age                From       Message
      ----     ------       ----               ----       -------
      Warning  FailedMount  13s (x7 over 46s)  kubelet    MountVolume.SetUp failed for volume "gke-workload-certificates" : rpc error: code = Internal desc = unable to mount volume: store.CreateVolume, err: unable to create volume "csi-4d540ed59ef937fbb41a9bf5380a5a534edb3eedf037fe64be36bab0abf45c9c": caPEM is nil (check active WorkloadCertificateConfig)
    
  4. Consulta los siguientes pasos para solucionar problemas si tus pods no se inician debido a objetos mal configurados o a CSRs rechazadas.

WorkloadCertificateConfig o TrustConfig no están configurados correctamente

Asegúrate de que has creado los objetos WorkloadCertificateConfig y TrustConfig correctamente. Puedes diagnosticar errores de configuración en cualquiera de estos objetos con kubectl.

  1. Recupera el estado actual.

    Para WorkloadCertificateConfig:

    kubectl get WorkloadCertificateConfig default -o yaml
    

    Para TrustConfig:

    kubectl get TrustConfig default -o yaml
    
  2. Inspecciona el resultado del estado. Un objeto válido tendrá una condición con type: Ready y status: "True".

    status:
      conditions:
      - lastTransitionTime: "2021-03-04T22:24:11Z"
        message: WorkloadCertificateConfig is ready
        observedGeneration: 1
        reason: ConfigReady
        status: "True"
        type: Ready
    

    En el caso de los objetos no válidos, se muestra status: "False". Los campos reason y message contienen información adicional para solucionar problemas.

No se aprueban las CSRs

Si algo va mal durante el proceso de aprobación de la CSR, puede consultar los detalles del error en las condiciones type: Approved y type: Issued de la CSR.

  1. Lista las CSRs pertinentes con kubectl:

    kubectl get csr \
      --field-selector='spec.signerName=spiffe.gke.io/spiffe-leaf-signer'
    
  2. Elige un CSR que sea Approved y no Issued, o que no sea Approved.

  3. Obtén los detalles de la CSR seleccionada con kubectl:

    kubectl get csr CSR_NAME -o yaml
    

    Sustituye CSR_NAME por el nombre que hayas elegido para la CSR.

Una CSR válida tiene una condición con type: Approved y status: "True", y un certificado válido en el campo status.certificate:

status:
  certificate: <base64-encoded data>
  conditions:
  - lastTransitionTime: "2021-03-04T21:58:46Z"
    lastUpdateTime: "2021-03-04T21:58:46Z"
    message: Approved CSR because it is a valid SPIFFE SVID for the correct identity.
    reason: AutoApproved
    status: "True"
    type: Approved

La información para solucionar problemas relacionados con CSRs no válidos aparece en los campos message y reason.

Las aplicaciones no pueden usar las credenciales de mTLS emitidas

  1. Comprueba que el certificado no haya caducado:

    cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Not After"
    
  2. Comprueba que el tipo de clave que has usado sea compatible con tu aplicación.

    cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Public Key Algorithm" -A 3
    
  3. Comprueba que la AC emisora use la misma familia de claves que la clave del certificado.

    1. Obtén el estado de la instancia del servicio de CA (vista previa):

      gcloud privateca ISSUING_CA_TYPE describe ISSUING_CA_NAME \
        --location ISSUING_CA_LOCATION
      

      Haz los cambios siguientes:

      • ISSUING_CA_TYPE: el tipo de CA emisora, que debe ser subordinates o roots.
      • ISSUING_CA_NAME: el nombre de la autoridad de certificación emisora.
      • ISSUING_CA_LOCATION: la región de la entidad certificadora emisora.
    2. Comprueba que el keySpec.algorithm de la salida sea el mismo algoritmo de clave que has definido en el manifiesto YAML WorkloadCertificateConfig. La salida tiene este aspecto:

      config:
        ...
        subjectConfig:
          commonName: td-sub-ca
          subject:
            organization: TestOrgLLC
          subjectAltName: {}
      createTime: '2021-05-04T05:37:58.329293525Z'
      issuingOptions:
        includeCaCertUrl: true
      keySpec:
        algorithm: RSA_PKCS1_2048_SHA256
       ...
      

Se rechazan los certificados

  1. Verifica que la aplicación del otro extremo usa el mismo paquete de confianza para verificar el certificado.
  2. Comprueba que el certificado no haya caducado:

    cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Not After"
    
  3. Verifica que el código de cliente, si no usa la API de recarga de credenciales de gRPC Go, actualice periódicamente las credenciales del sistema de archivos.

  4. Verifica que tus cargas de trabajo estén en el mismo dominio de confianza que tu CA. Los certificados de malla de GKE admiten la comunicación entre cargas de trabajo de un único dominio de confianza.