Configura la seguridad del servicio con Envoy
Usa las instrucciones de esta guía para configurar la autenticación y la autorización para los servicios implementados con proxies de Cloud Service Mesh y Envoy. Para obtener información completa sobre la seguridad del servicio de Cloud Service Mesh, consulta Seguridad del servicio de Cloud Service Mesh.
Requisitos
Antes de configurar la seguridad de servicios para Cloud Service Mesh con Envoy, asegúrate de que cumpla con los siguientes requisitos previos:
Puedes cumplir con todos los requisitos para implementar Cloud Service Mesh. Para completa sobre estos requisitos, consulta Prepárate para configurar las APIs de Service Enrutamiento con Envoy y las cargas de trabajo sin proxy.
Tienes permisos suficientes para crear o actualizar Cloud Service Mesh y Recursos de la malla de servicios de Google Cloud para usar la seguridad del servicio, como se describe en Prepárate para configurar las APIs de enrutamiento de servicios con Envoy y las cargas de trabajo sin proxy.
Prepárate 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. Las tareas son las siguientes:
- Actualiza Google Cloud CLI
- Configurar variables
- Habilita las APIs necesarias para que funcione la malla de servicios de Cloud Certificate Authority Service
Actualiza la herramienta de línea de comandos de gcloud
Para actualizar Google Cloud CLI, ejecuta lo siguiente en tu máquina local:
gcloud components update
Configura variables
Configura las siguientes variables para que puedas copiar y pegar el código con valores coherentes a medida que trabajas con 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 deseas usar, por ejemplo,
secure-td-cluster
. - ZONE: Sustituye la zona en la que se encuentra el clúster.
- GKE_CLUSTER_URL: Sustituye
https://container.googleapis.com/v1/projects/PROJECT_ID/locations/ZONE/clusters/CLUSTER_NAME
- WORKLOAD_POOL: Sustituye
PROJECT_ID.svc.id.goog
- K8S_NAMESPACE: Sustituye
default
. - DEMO_CLIENT_KSA: Sustituye el nombre de tu cuenta de servicio de cliente de Kubernetes.
- DEMO_SERVER_KSA: Sustituye el nombre de la cuenta de servicio de Kubernetes de tu servidor.
PROJNUM: Sustituye el número de proyecto que puedes determinar desde la consola de Google Cloud o mediante este comando:
gcloud projects describe PROJECT_ID --format="value(projectNumber)"
SA_GKE: Sustituye
service-PROJNUM@container-engine-robot.iam.gserviceaccount.com
CLUSTER_VERSION: Sustituye la versión más reciente disponible. Puedes encontrarla 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 usará en este ejemplo.
Establece 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
Habilitación de las API
Usa el comando gcloud services enable
para habilitar todas las APIs que necesitas a fin de configurar la seguridad de Cloud Service Mesh con Certificate Authority Service.
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
Crea o actualiza un clúster de GKE
La seguridad del servicio de Cloud Service Mesh depende de la integración del servicio de AC con GKE. El clúster de GKE debe cumplir con los siguientes requisitos además de los requisitos para la configuración:
- Usa una versión de clúster mínima de 1.21.4-gke.1801. Si necesitas funciones que se encuentran en una versión posterior, puedes obtenerla del canal de versiones rápido.
- El clúster de GKE debe estar habilitado y configurado con certificados de malla de trabajo, como se describe en Crea autoridades certificadoras para emitir certificados.
Crea un clúster nuevo que use la Federación de identidades para cargas de trabajo para GKE. Si actualizas un clúster existente, avanza al siguiente paso. El valor que proporciones para
--tags
debe coincidir con el nombre que se pasó a la marca--target-tags
del comandofirewall-rules create
en la sección Configura 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 tomar varios minutos en completarse.
Si usas un clúster existente, activa la federación de identidades para cargas de trabajo 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 comandoupdate
.gcloud container clusters update CLUSTER_NAME \ --enable-mesh-certificates
Ejecuta el siguiente comando a fin de cambiar al clúster nuevo como el clúster predeterminado para los comandos de
kubectl
:gcloud container clusters get-credentials CLUSTER_NAME \ --zone ZONE
Implementa en un entorno de varios clústeres
Si realizas la implementación en un entorno de varios clústeres, sigue el procedimiento general que se describe en esta sección. En estas instrucciones, se supone que los Pods de cliente se ejecutan en un clúster y los Pods del servidor se ejecutan en el otro.
Crea o actualiza los clústeres mediante las instrucciones de la sección anterior.
Captura los rangos de direcciones IP del Pod para cada clúster mediante el siguiente comando:
gcloud compute firewall-rules list \ --filter="name~gke-{CLUSTER_NAME}-[0-9a-z]*-all" \ --format="value(sourceRanges)"
Por ejemplo, para los clústeres llamados
cluster-a
ycluster-b
, los comandos muestran 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
Crea reglas de firewall de VPC que permitan que los clústeres se comuniquen entre sí. Por ejemplo, el siguiente comando crea una regla de firewall que permite que las direcciones IP del Pod
cluster-a
se comuniquen con los nodoscluster-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 firewall que permite que las direcciones IP del pod
cluster-b
se comuniquen con los nodoscluster-a
:gcloud compute firewall-rules create per-cluster-b-pods \ --allow="tcp,udp,icmp,esp,ah,sctp" \ --target-tags="gke-cluster-a-9cd18751-node"
Registra clústeres con una flota
Registra el clúster que creaste o actualizaste en Crea un clúster de GKE con una flota. El registro del clúster facilita la configuración de clústeres en varios proyectos.
Ten en cuenta que estos pasos pueden demorar hasta diez minutos en completarse.
Registra tu clúster con 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
de la siguiente manera:
- CLUSTER_NAME: Es el nombre del clúster.
- ZONE: La zona del clúster.
- MANIFEST-FILE_NAME: Es la ruta de acceso en la que estos comandos generan el manifiesto para el registro.
Cuando el proceso de registro se realice de forma correcta, verás un mensaje como el siguiente:
Finished registering the cluster CLUSTER_NAME with the fleet.
Aplica el archivo de manifiesto generado a tu clúster:
kubectl apply -f MANIFEST-FILE_NAME
Cuando el proceso de la aplicación se realice de forma correcta, 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
Obtén el recurso de la membresía del clúster:
kubectl get memberships membership -o yaml
El resultado debe incluir el grupo de Workload Identity que asigna la flota, en el que PROJECT_ID es el ID de tu proyecto:
workload_identity_pool: PROJECT_ID.svc.id.goog
Esto significa que el clúster se registró correctamente.
Crea autoridades certificadoras para emitir certificados
Para emitir certificados a tus pods, crea un grupo de servicios de CA y las siguientes autoridades certificadoras (CA):
- CA raíz. Esta es la raíz de confianza de todos los certificados de malla emitidos. Puedes usar una CA raíz existente si tienes una. Crea la CA raíz en el nivel
enterprise
, que está destinado a la emisión de certificados de larga duración y bajo volumen. - CA subordinada. Esta CA emite certificados para cargas de trabajo. Crea la CA subordinada en la región en la que se implementa el clúster. Crea la CA subordinada en el nivel
devops
, que está destinado a la emisión de certificados de corta duración y gran volumen.
Crear una CA subordinada es opcional, pero te recomendamos crear una en lugar de usar tu CA raíz para emitir certificados de malla de GKE. Si decides usar la CA raíz para emitir certificados de malla, asegúrate de que se mantenga el modo de emisión basado en configuración predeterminado.
La CA subordinada puede estar en una región diferente de tu clúster, pero recomendamos crearla en la misma región que tu clúster para optimizar el rendimiento. Sin embargo, puedes crear las CA subordinadas y raíz en regiones diferentes sin ningún impacto en el rendimiento o la disponibilidad.
Estas regiones son compatibles con el servicio de CA:
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 |
Delhi |
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 |
Virginia del Norte |
us-east5 |
Columbus |
us-south1 |
Dallas |
us-west1 |
Oregón |
us-west2 |
Los Ángeles |
us-west3 |
Salt Lake City |
us-west4 |
Las Vegas |
La lista de ubicaciones compatibles también se puede verificar ejecutando el siguiente comando:
gcloud privateca locations list
Otorga la
roles/privateca.caManager
de IAM a las personas que crean un grupo de CA y una CA. Ten en cuenta que, para MEMBER, el formato correcto esuser:userid@example.com
. Si esa persona es el usuario actual, puedes obtener el ID del usuario actual 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
Otorga el rol
role/privateca.admin
en el servicio de AC a las personas que necesiten modificar las políticas de IAM. En este caso,MEMBER
es una persona que necesita este acceso, en particular, cualquier persona que realice los siguientes pasos que otorgan los rolesprivateca.auditor
yprivateca.certificateManager
:gcloud projects add-iam-policy-binding PROJECT_ID \ --member=MEMBER \ --role=roles/privateca.admin
Crea el grupo de servicios de CA raíz.
gcloud privateca pools create ROOT_CA_POOL_NAME \ --location ROOT_CA_POOL_LOCATION \ --tier enterprise
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
En esta configuración de demostración, usa 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"
Crea el grupo subordinado y la CA subordinada. Asegúrate de que el modo de emisión basado en la configuración predeterminado permanezca 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
En esta configuración de demostración, usa 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
Otorga la función
privateca.auditor
de IAM al grupo de CA 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"
Otorga la función
privateca.certificateManager
de IAM para que el grupo CA subordinado permita 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"
Guarda la siguiente configuración de YAML
WorkloadCertificateConfig
para indicarle 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
Reemplaza lo siguiente:
- El ID del proyecto del proyecto en el que se ejecuta tu clúster.
PROJECT_ID
- El URI completamente calificado de la CA que emite los certificados de malla (ISSUING_CA_POOL_URI). Puede ser tu CA subordinada (recomendada) o la CA raíz. El formato es:
//privateca.googleapis.com/projects/PROJECT_ID/locations/SUBORDINATE_CA_POOL_LOCATION/caPools/SUBORDINATE_CA_POOL_NAME
- El ID del proyecto del proyecto en el que se ejecuta tu clúster.
Guarda la siguiente configuración de YAML
TrustConfig
para indicarle 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
Reemplaza lo siguiente:
- El ID del proyecto del proyecto en el que se ejecuta tu clúster.
PROJECT_ID
- El URI completamente calificado del grupo de CA raíz (ROOT_CA_POOL_URI). El formato es:
//privateca.googleapis.com/projects/PROJECT_ID/locations/ROOT_CA_POOL_LOCATION/caPools/ROOT_CA_POOL_NAME
- El ID del proyecto del proyecto en el que se ejecuta tu clúster.
Aplica las configuraciones a tu clúster.
kubectl apply -f WorkloadCertificateConfig.yaml kubectl apply -f TrustConfig.yaml
Configura la administración de identidades y accesos
A fin de crear los recursos necesarios para la configuración, debes tener la función compute.NetworkAdmin
. Esta función contiene todos los permisos necesarios para crear, actualizar, borrar, enumerar y usar (es decir, hacer referencia a esto en otros recursos) los recursos necesarios. Si eres propietario o editor de tu proyecto, automáticamente tienes esta función.
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
compute.NetworkAdmin
, no notarás ningún problema cuando se realice la verificación
de manera forzosa.
Si usas funciones personalizadas y esta verificación se aplica en el futuro, debes asegurarte de incluir el permiso .use
correspondiente. De lo contrario, en el futuro, es posible que tu función personalizada no tenga los permisos necesarios para hacer referencia a clientTlsPolicy
o serverTlsPolicy
desde el servicio de backend o la política de extremo.
Las siguientes instrucciones permiten que la cuenta de servicio predeterminada acceda a la API de Cloud Service Mesh Security y crear las cuentas de servicio de Kubernetes.
Configura IAM para permitir que acceda la cuenta de servicio predeterminada 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
Configura cuentas de servicio de Kubernetes. En las implementaciones de cliente y servidor de las siguientes secciones, se usan los nombres de K del servidor de Kubernetes y las cuentas de servicio del cliente.
kubectl create serviceaccount --namespace K8S_NAMESPACE DEMO_SERVER_KSA kubectl create serviceaccount --namespace K8S_NAMESPACE DEMO_CLIENT_KSA
Para permitir que las cuentas de servicio de Kubernetes actúen en nombre de la cuenta de servicio predeterminada de Compute Engine, crea una vinculación de políticas de IAM entre las dos. Esta vinculación permite que la cuenta de servicio de Kubernetes actúe como la cuenta de servicio de Compute Engine predeterminada.
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}
Anotar las cuentas de servicio de Kubernetes para asociarlas con la configuración Cuenta de servicio 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}
Configura Cloud Service Mesh
Usa las siguientes instrucciones para instalar el inyector de sidecar, configurar un servicio de prueba y completar otras tareas de implementación.
Instala el inyector de sidecar de Envoy en el clúster
Sigue las instrucciones de las dos secciones siguientes del Configuración de la malla de servicios de Cloud para Pods de GKE con inyección automática de Envoy para implementar y habilitar la inserción del sidecar de Envoy en el clúster:
- Instala el inyector de sidecar de Envoy.
Asegúrate de configurar el nombre de la malla como
sidecar_mesh
y la red como "", una cadena vacía. - Habilita la inserción de sidecar
Asegúrate de completar ambos conjuntos de instrucciones antes de configurar un servicio de prueba.
Configura un servicio de prueba
Después de instalar el inyector de sidecar de Envoy, usa estas instrucciones a fin de configurar un servicio de prueba para la 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 podspec para tu aplicación de servidor de demostración. Hay algunas anotaciones que son específicas de la malla de servicios de Cloud
seguridad.
Metadatos del proxy de Cloud Service Mesh
El podspec especifica la anotación proxyMetadata
:
spec: ... annotations: cloud.google.com/proxyMetadata: '{"app": "payments"}' ...
Cuando se inicializa el Pod, el proxy de sidecar recoge esta anotación y lo transmite a Cloud Service Mesh. Luego, Cloud Service Mesh puede usar para devolver la configuración filtrada:
- Más adelante en esta guía, ten en cuenta que la política de extremos especifica un comparador de extremos.
- El comparador de extremos especifica que solo los clientes que presentan una etiqueta con el nombre
app
y el valorpayments
reciben la configuración filtrada.
Usa claves y certificados de malla firmados por el servicio de CA
El podspec especifica la anotación enableManagedCerts
:
spec: ... annotations: ... cloud.google.com/enableManagedCerts: "true" ...
Cuando se inicializa el Pod, los certificados y claves firmados por el Servicio de AC se activan de forma automática en el sistema de archivos del proxy de sidecar local.
Configura el puerto de interceptación de tráfico entrante
El podspec especifica la anotación includeInboundPorts
:
spec: ... annotations: ... cloud.google.com/includeInboundPorts: "8000" ...
Este es el puerto en el que tu aplicación de servidor escucha las conexiones. Cuando se inicializa el Pod, el proxy de sidecar detecta esta anotación y la transmite a Cloud Service Mesh. Luego, 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 que pueda aplicar políticas de seguridad en él.
El puerto de verificación de 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 verificación de estado, lo que puede ocasionar el rechazo de las conexiones, lo que dará como resultado que el servidor se marque incorrectamente como en mal estado.
Configura servicios de GKE con NEG
Los servicios de GKE deben exponerse a través de grupos de extremos de red
(NEG) 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"
Implementa una aplicación cliente en GKE
Ejecuta el siguiente comando para iniciar un cliente de demostración con un proxy de Envoy como un sidecar, que necesitas a fin de 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 podspec del cliente solo incluye la anotación enableManagedCerts
. Esto es necesario a fin de activar los volúmenes necesarios para las claves y los certificados de malla administrados de GKE que firma la instancia del servicio de CA.
Configura la verificación de estado, la regla de firewall y los recursos de servicios de backend
En esta sección, crearás recursos de verificación de estado, regla de firewall y servicio de backend para Cloud Service Mesh.
Crea la verificación de estado.
gcloud compute health-checks create http td-gke-health-check \ --use-serving-port
Crea la regla de firewall para permitir los rangos de direcciones IP del verificador 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
Crea el servicio de backend y asocia la verificación de estado con este.
gcloud compute backend-services create td-gke-service \ --global \ --health-checks td-gke-health-check \ --load-balancing-scheme INTERNAL_SELF_MANAGED
Agrega el NEG que creaste antes como un 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
Configura recursos Mesh
y HTTPRoute
En esta sección, crearás recursos Mesh
y HTTPRoute
.
Crea la especificación del recurso
Mesh
y guárdala en un archivo llamadomesh.yaml
name: sidecar-mesh interceptionPort: 15001
El puerto de intercepción se establece de forma predeterminada en
15001
si no lo especificas en el archivomesh.yaml
.Crea el recurso
Mesh
con la especificación Mesh.yaml.gcloud network-services meshes import sidecar-mesh \ --source=mesh.yaml \ --location=global
Crea la especificación
HTTPRoute
y guárdala en un archivo llamadohttp_route.yaml
.Puedes usar
PROJECT_ID
oPROJECT_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"
Crea el recurso
HTTPRoute
con la especificación del archivohttp_route.yaml
.gcloud network-services http-routes import helloworld-http-route \ --source=http_route.yaml \ --location=global
Se completó la configuración de Cloud Service Mesh y ahora puedes definir las políticas de autenticación y autorización.
Configura la seguridad de servicio a servicio
Usa las instrucciones de las siguientes secciones para configurar la seguridad entre servicios.
Habilita mTLS en la malla
Para configurar mTLS en la malla, debes proteger el tráfico saliente al servicio de backend y el tráfico entrante al extremo.
Formato de las referencias de políticas
Ten en cuenta el siguiente formato obligatorio para hacer referencia a la TLS del servidor, la TLS del cliente y las 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
Protege 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 el complemento declientCertificate
, que programa Envoy para usar certificados de malla administrados por GKE como la identidad del cliente. - Usa
google_cloud_private_spiffe
como complemento paraserverValidationCa
, que programa Envoy a fin de usar certificados de malla administrados por GKE a fin de validar el servidor.
Luego, adjunta la política de TLS del cliente al servicio de backend. Esto realiza las siguientes acciones:
- Aplica la política de autenticación de la política TLS del cliente a las conexiones salientes a los extremos del servicio de backend.
- SAN (nombres alternativos del asunto) indica al cliente que confirme la identidad exacta del servidor al que se está conectando.
Crea la política de TLS del 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
Importa la política de TLS del cliente:
gcloud network-security client-tls-policies import client-mtls-policy \ --source=client-mtls-policy.yaml --location=global
Vincula la política de TLS del cliente al servicio de backend. Esto aplica la autenticación mTLS en todas las solicitudes salientes del cliente a este servicio de backend.
gcloud compute backend-services export td-gke-service \ --global --destination=demo-backend-service.yaml
Agrega 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"
Importa los valores:
gcloud compute backend-services import td-gke-service \ --global --source=demo-backend-service.yaml
También puedes ejecutar el siguiente comando para comprobar si la solicitud falla. Esto es un error esperado, porque el cliente espera certificados del extremo, pero el extremo 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
Protege el tráfico entrante al extremo
Para proteger el tráfico entrante, primero debes crear una política de TLS del servidor que haga lo siguiente:
- Usa
google_cloud_private_spiffe
como el complemento paraserverCertificate
, que programa Envoy para usar certificados de malla administrados por GKE como la identidad del servidor. - Usa
google_cloud_private_spiffe
como el complemento paraclientValidationCa
, que programa Envoy a fin de usar certificados de malla administrados por GKE a fin de validar el cliente.
Guarda los valores de la política de 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
Crea la política de TLS del servidor:
gcloud network-security server-tls-policies import server-mtls-policy \ --source=server-mtls-policy.yaml --location=global
Crea un archivo llamado
ep_mtls.yaml
que contenga el comparador de extremos y conecta 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
Importa el comparador de extremos.
gcloud network-services endpoint-policies import ep \ --source=ep_mtls.yaml --location=global
Valida la configuración
Ejecuta el siguiente comando curl
. Si la solicitud finaliza de forma correcta, verás x-forwarded-client-cert
en el resultado. El encabezado se imprime solo cuando la conexión es 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 el encabezado x-forwarded-client-cert
lo inserta Envoy desde el servidor y que contiene su propia identidad (servidor) y la identidad del cliente de origen. Debido a que vemos las identidades del cliente y del servidor, esto es una señal de una conexión mTLS.
Configura el acceso a nivel de servicio con una política de autorización
Con estas instrucciones, se crea una política de autorización que permite las solicitudes que se envían mediante 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, lee la precaución en Restringir el acceso con autorización.
Para crear una política de autorización, crea 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
Importa la política:
gcloud network-security authorization-policies import authz-policy \ --source=authz-policy.yaml \ --location=global
Actualiza la política de extremos para hacer referencia a la política de autorización nueva. Para ello, agrega lo siguiente al archivo
ep_mtls.yaml
:authorizationPolicy: projects/PROJECT_ID/locations/global/authorizationPolicies/authz-policy
La política de extremos ahora especifica que mTLS y la política de autorización deben aplicarse a las solicitudes entrantes a los pods cuyos proxies de sidecar de Envoy presentan la etiqueta
app:payments
.Importa la política:
gcloud network-services endpoint-policies import ep \ --source=ep_mtls.yaml --location=global
Valida 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 probar 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>
Configura políticas de autorización en contenedores secundarios en GKE
En esta sección, se muestra cómo configurar diferentes tipos de políticas de autorización en los pares secundarios de Cloud Service Mesh en GKE.
Antes de crear una política de autorización, debes instalar la CustomResourceDefinition (CRD) GCPAuthzPolicy:
curl https://github.com/GoogleCloudPlatform/gke-networking-recipes/blob/main/gateway-api/config/mesh/crd/experimental/gcpauthzpolicy.yaml \
| kubectl apply -f -
Política de autorización para rechazar solicitudes
Cuando tienes una carga de trabajo que solo debe hacer llamadas salientes, como una
trabajo cron, puedes configurar una política de autorización para rechazar cualquier solicitud HTTP
las solicitudes a la carga de trabajo. En el siguiente ejemplo, se rechazan las solicitudes HTTP entrantes a
la carga de trabajo example-app
.
Sigue estos pasos para crear y aplicar la política de autorización de denegación:
Para crear una política personalizada, crea un archivo llamado
deny-all-authz-policy.yaml
:cat >deny-all-authz-policy.yaml <<EOF apiVersion: networking.gke.io/v1 kind: GCPAuthzPolicy metadata: name: my-workload-authz namespace: ns1 spec: targetRefs: - kind: Deployment name: example-app httpRules: - to: operations: - paths: - type: Prefix value: "/" action: DENY EOF
Aplica la política:
kubectl apply -f deny-all-authz-policy.yaml
Política de autorización para permitir solicitudes
También puedes configurar una política de permiso que solo permita las solicitudes que coincidan con un criterios específico y rechace el resto. En el siguiente ejemplo, se configura una
política de autorización en la implementación de example-app
para permitir solo solicitudes de mTLS
desde pods con la identidad spiffee://cluster.local/ns1/pod1
.
Sigue los pasos que se indican a continuación para crear y aplicar la política de autorización de permiso:
Para crear una política personalizada, crea un archivo llamado
allow-authz-policy.yaml
:cat >allow-authz-policy.yaml <<EOF apiVersion: networking.gke.io/v1 kind: GCPAuthzPolicy metadata: name: my-workload-authz namespace: ns1 spec: targetRefs: - kind: Deployment name: example-app httpRules: - from: sources: - principals: - type: Exact value: "spiffee://cluster.local/ns1/pod1" action: ALLOW EOF
Aplica la política:
kubectl apply -f allow-authz-policy.yaml
Configura la seguridad de la puerta de enlace de entrada
En esta sección, se asume que completaste la sección de seguridad entre servicios, incluida la configuración de tu clúster de GKE con el inyector automático de sidecar, la creación de una autoridad certificadora y la creación de una política de extremos.
En esta sección, implementarás un proxy de Envoy como una puerta de enlace de entrada que finaliza las conexiones TLS y autoriza solicitudes de los clientes internos de un clúster.
A fin de configurar una puerta de enlace de entrada para finalizar TLS, haz lo siguiente:
- Implementa un servicio de Kubernetes al que se pueda acceder mediante una dirección IP interna del clúster
- La implementación consiste en un proxy de Envoy independiente que se expone como un Kubernetes Service y se conecta a Cloud Service Mesh.
- Crea una política de TLS de servidor para finalizar TLS.
- Crea una política de autorización para autorizar solicitudes entrantes.
Implementa un servicio de puerta de enlace de entrada en GKE
Ejecuta el siguiente comando para implementar el servicio de puerta de enlace 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 puerta de enlace de entrada. Las siguientes secciones describen algunas adiciones a la especificación.
Inhabilita la inserción de archivos adicionales de Cloud Service Mesh
La especificación gateway_sample.yaml
implementa un proxy de Envoy como el único contenedor. En los pasos anteriores, Envoy se insertó como un sidecar a un contenedor de aplicación. Si deseas evitar que varias Envoy manejen las solicitudes, puedes inhabilitar la inserción de sidecar para este servicio de Kubernetes mediante la siguiente declaración:
sidecar.istio.io/inject: "false"
Activa el volumen correcto
La especificación gateway_sample.yaml
activa el volumen gke-workload-certificates
.
Este volumen también se usa en la implementación de sidecar, pero el inyector de sidecar lo agrega de forma automática cuando detecta la anotación cloud.google.com/enableManagedCerts: "true"
. El volumen gke-workload-certificates
contiene los certificados y las claves de SPIFFE administrados por GKE que firma la instancia del servicio de CA que configuraste.
Configura la dirección IP interna del clúster
Configura la puerta de enlace de entrada con un servicio de tipo ClusterInternal
. Esto crea un nombre de host DNS que se resuelve de forma interna para mesh-gateway
. Cuando un cliente envía una solicitud a mesh-gateway:443
, Kubernetes enruta la solicitud de inmediato al puerto 8080
de la implementación de Envoy de la puerta de enlace de entrada.
Habilita TLS en una puerta de enlace de entrada
Usa estas instrucciones para habilitar TLS en una puerta de enlace de entrada.
Crea un recurso de política de TLS de servidor para finalizar las conexiones TLS, con los valores en un archivo llamado
server-tls-policy.yaml
:description: tls server policy name: server-tls-policy serverCertificate: certificateProviderInstance: pluginInstance: google_cloud_private_spiffe
Importa la política de TLS del servidor:
gcloud network-security server-tls-policies import server-tls-policy \ --source=server-tls-policy.yaml --location=global
Crea un nuevo destino
Gateway
y guárdalo en el archivotd-gke-gateway.yaml
. Esto adjunta la política de TLS del servidor y configura la puerta de enlace de entrada del proxy de Envoy para finalizar 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
Importa la puerta de enlace:
gcloud network-services gateways import td-gke-gateway \ --source=td-gke-gateway.yaml \ --location=global
Crea y guarda un
HTTPRoute
nuevo llamadotd-gke-route
que haga referencia a la puerta de enlace y enrute todas las solicitudes atd-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"
Importa
HTTPRoute
:gcloud network-services httproutes import td-gke-route \ --source=td-gke-route.yaml \ --location=global
De manera opcional, actualiza la política de autorización en los backends para permitir solicitudes cuando se cumplan todas las siguientes condiciones:
- Solicitudes enviadas por
DEMO_CLIENT_KSA
. (La implementación de la puerta de enlace de entrada usa la cuenta de servicioDEMO_CLIENT_KSA
). - Solicitudes con el host
mesh-gateway
oservice-test
- Puerto
8000
No es necesario que ejecutes estos comandos, a menos que hayas configurado una política de autorización para tus backends. Si no hay una política de autorización en el extremo o no contiene la coincidencia principal o de host en la política de autorización, la solicitud se permite sin este paso. Agrega 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
- Solicitudes enviadas por
Importa la política:
gcloud network-security authorization-policies import authz-policy \ --source=authz-policy.yaml \ --location=global
Valida la implementación de la puerta de enlace de entrada
Usa un contenedor nuevo llamado debug
para enviar solicitudes a la puerta de enlace de entrada a fin de validar la implementación.
En la siguiente especificación, la anotación "sidecar.istio.io/inject":"false"
evita que el inyector de sidecar de Cloud Service Mesh inserte de forma automática un proxy de sidecar. No hay ningún sidecar para ayudar al contenedor debug
en el enrutamiento de solicitudes.
El contenedor debe conectarse a la puerta de enlace de entrada para el enrutamiento.
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 certificadora que se necesitan en los certificados válidos firmados por el servicio de CA que usa la puerta de enlace de entrada para finalizar TLS.
En un entorno de producción, te recomendamos descargar el certificado de validación del servicio de CA y activarlo o instalarlo en tu cliente. Después de instalar el certificado de validación, quita 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ás 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ás 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ás un resultado similar al siguiente:
HTTP/1.1 403 Forbidden wget: server returned error: HTTP/1.1 403 Forbidden
Borra la implementación
También puedes ejecutar estos comandos para borrar la implementación que creaste con esta guía.
Para borrar el clúster, ejecuta este comando:
gcloud container clusters delete CLUSTER_NAME --zone ZONE --quiet
Para borrar los recursos que creaste, 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 servicios de Cloud Service Mesh solo se admite con en GKE. No puedes implementar la seguridad del servicio con Compute Engine.
Soluciona problemas
Esta sección contiene información sobre cómo solucionar los problemas que encuentras durante la configuración del servicio de seguridad.
Fallas de conexión
Si la conexión falla con un error upstream connect
o disconnect/reset
before headers
, examina los registros de Envoy, en los que puedes ver 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 esté activado de forma incorrecta o que use un audience
diferente, o ambos.
Para obtener más información, consulta Mensajes de error en los registros de Envoy indican un problema de configuración.
No se crearon los Pods
Para solucionar este problema, consulta Soluciona problemas de implementaciones automáticas de pods de GKE.
Envoy no se autentica con Cloud Service Mesh
Cuando Envoy (envoy-proxy
) se conecta a Cloud Service Mesh para recuperar 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 modificado el arranque). Si la autenticación falla, Envoy no entra en el estado de listo.
No se puede crear un clúster con --workload-identity-certificate-authority flag
Si ves este error, asegúrate de que estás ejecutando la versión más reciente de Google Cloud CLI:
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 para los pods en tu especificación de implementación.
No se pudo crear el clúster con la marca --enable-mesh-certificates
Asegúrate de ejecutar 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 suceder en situaciones como las siguientes:
WorkloadCertificateConfig
oTrustConfig
no están bien configurados o no se encuentran.- No se aprueban las CSR.
Para verificar si el aprovisionamiento de certificados falla, revisa los eventos del pod.
Verifica el estado del Pod:
kubectl get pod -n POD_NAMESPACE POD_NAME
Reemplaza lo siguiente:
POD_NAMESPACE
: es el espacio de nombres del Pod.POD_NAME
: es el nombre del Pod.
Revisa los eventos recientes de tu pod:
kubectl describe pod -n POD_NAMESPACE POD_NAME
Si falla el aprovisionamiento de certificados, verás un evento con
Type=Warning
,Reason=FailedMount
,From=kubelet
y un campoMessage
que comienza conMountVolume.SetUp failed for volume "gke-workload-certificates"
. El campoMessage
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)
Consulta los siguientes pasos de solución de problemas si el motivo por el que tus pods no se inician es porque hay objetos mal configurados o CSR rechazadas.
La configuración de WorkloadCertificateConfig
o TrustConfig
es incorrecta
Asegúrate de haber creado los objetos WorkloadCertificateConfig
y TrustConfig
de forma correcta. Puedes diagnosticar una configuración incorrecta en cualquiera de estos objetos mediante kubectl
.
Recupera el estado actual.
Para
WorkloadCertificateConfig
:kubectl get WorkloadCertificateConfig default -o yaml
Para
TrustConfig
:kubectl get TrustConfig default -o yaml
Inspecciona el resultado del estado. Un objeto válido tendrá una condición con
type: Ready
ystatus: "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, aparece
status: "False"
en su lugar. Los camposreason
ymessage
contienen detalles adicionales sobre la solución de problemas.
Las CSR no están aprobadas.
Si algo sale mal durante el proceso de aprobación de la CSR, puedes verificar los detalles del error en las condiciones de type: Approved
y type: Issued
de la CSR.
Enumera las CSR relevantes mediante
kubectl
:kubectl get csr \ --field-selector='spec.signerName=spiffe.gke.io/spiffe-leaf-signer'
Elige una CSR que tenga el estado
Approved
y noIssued
, o que no tenga el estadoApproved
.Obtén detalles de la CSR seleccionada con kubectl:
kubectl get csr CSR_NAME -o yaml
Reemplaza
CSR_NAME
por el nombre de la CSR que elegiste.
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 de solución de problemas para CSR no válidas aparece en los campos message
y reason
.
Las aplicaciones no pueden usar las credenciales de mTLS emitidas
Verifica que el certificado no haya vencido:
cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Not After"
Comprueba que tu aplicación admita el tipo de clave que usaste.
cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Public Key Algorithm" -A 3
Comprueba que la CA emisora use la misma familia de claves que la clave del certificado.
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
Reemplaza lo siguiente:
ISSUING_CA_TYPE
: el tipo de CA de la emisión, que debe sersubordinates
oroots
.ISSUING_CA_NAME
: el nombre de la CA emisora.ISSUING_CA_LOCATION
: la región de la CA emisora.
Comprueba que el
keySpec.algorithm
en el resultado sea el mismo algoritmo de clave que definiste en el manifiesto de YAMLWorkloadCertificateConfig
. El resultado se verá así: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 ...
Los certificados se rechazan
- Verifica que la aplicación par use el mismo paquete de confianza para verificar el certificado.
Verifica que el certificado no haya vencido:
cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Not After"
Verifica que el código de cliente, si no usas la API de recarga de credenciales de gRPC para Go, actualice las credenciales del sistema de archivos de forma periódica.
Verifica que las cargas de trabajo estén en el mismo dominio de confianza que la CA. Los certificados de malla de GKE admiten la comunicación entre cargas de trabajo en un solo dominio de confianza.