En esta guía, se describe cómo integrar Identity-Aware Proxy (IAP) en Anthos Service Mesh. La integración de IAP en Anthos Service Mesh te permite acceder de forma segura a los servicios según los principios de BeyondCorp de Google. IAP verifica la identidad del usuario y el contexto de la solicitud para determinar si el usuario debe tener acceso a una aplicación o un recurso. La integración de IAP en Anthos Service Mesh te brinda los siguientes beneficios:
Completa el control de acceso adaptado al contexto en las cargas de trabajo que se ejecutan en Anthos Service Mesh. Puedes configurar políticas de acceso detalladas según los atributos de la solicitud de origen, como la identidad del usuario, la dirección IP y el tipo de dispositivo. Puedes combinar tus políticas de acceso con restricciones según el nombre de host y la ruta de acceso de una URL de solicitud.
Habilita la compatibilidad con reclamaciones contextuales en la autorización de Anthos Service Mesh.
Proporciona acceso escalable, seguro y con alta disponibilidad a tu aplicación a través de un balanceador de cargas de Google Cloud. El balanceo de cargas de alto rendimiento proporciona protección integrada contra ataques de denegación de servicio distribuido (DSD) y compatibilidad con direcciones IP Anycast globales.
Requisitos previos
En esta guía, suponemos que ya tienes lo siguiente:
Configura un clúster con Anthos Service Mesh
La integración de IAP requiere una configuración específica en tu proyecto, tu clúster y los archivos de configuración que usas cuando instalas Anthos Service Mesh.
Instalaciones nuevas
Los pasos de esta sección complementan los pasos en la guía Instalación avanzada en GKE. En estos pasos, se usan las variables de entorno que creas en la guía de instalación.
Cuando configuras tu proyecto, habilita
iap.googleapis.com
además de las otras API requeridas.gcloud services enable \ --project=PROJECT_ID \ iap.googleapis.com
Cuando actualizas tu clúster, habilita el complemento
HttpLoadBalancing
además de las otras actualizaciones del clúster requeridas. El complementoHttpLoadBalancing
habilita un controlador de balanceo de cargas de HTTP (L7) para el clúster.gcloud container clusters update ${CLUSTER_NAME} \ --project=PROJECT_ID \ --update-addons=HttpLoadBalancing=ENABLED
Si no configuraste una zona o una región predeterminada, debes proporcionar la región (--region=${CLUSTER_LOCATION}) o la zona (--zone=${CLUSTER_LOCATION}) en el comando anterior.
Después de actualizar el clúster, continúa con la guía de instalación para configurar credenciales y permisos y descargar el archivo de instalación. Detente en la sección Prepara archivos de configuración de los recursos y realiza los siguientes pasos en su lugar.
Crea un directorio nuevo para los archivos de configuración de recursos del paquete de Anthos Service Mesh. Recomendamos que uses el nombre del clúster como el nombre del directorio.
Cambia al directorio en el que deseas descargar el paquete de Anthos Service Mesh.
Descarga el paquete
asm-iap
. Este paquete configura el campotype
en el servicioistio-ingressgateway
comoNodePort
. En esta configuración,istio-ingressgateway
abre un puerto específico en la malla de servicios. Esto te permite configurar un balanceador de cargas, que enruta el tráfico enviado a tu nombre de dominio a este puerto.kpt pkg get https://github.com/GoogleCloudPlatform/anthos-service-mesh-packages.git/asm-iap@release-1.6-asm asm
Configura el ID del proyecto en el que se creó el clúster:
kpt cfg set asm gcloud.core.project PROJECT_ID
Configura el número de proyecto para el proyecto host de la flota:
kpt cfg set asm gcloud.project.environProjectNumber ${FLEET_PROJECT_NUMBER}
Configura el nombre del clúster:
kpt cfg set asm gcloud.container.cluster ${CLUSTER_NAME}
Establece la zona o región predeterminada:
kpt cfg set asm gcloud.compute.location ${CLUSTER_LOCATION}
Configura el webhook de validación para usar una etiqueta de revisión:
kpt cfg set asm anthos.servicemesh.rev asm-1614-2
Establece el perfil de configuración. Para la integración de IAP, configura el perfil
asm-gcp
:kpt cfg set asm anthos.servicemesh.profile asm-gcp
Configura los puertos de estado y HTTP para el balanceador de cargas. El puerto de estado predeterminado es 31223, y el puerto HTTP predeterminado es 31224. Si estos puertos ya están en uso, configúralos:
kpt cfg set asm gcloud.container.cluster.ingress.httpPort HTTP_PORT
kpt cfg set asm gcloud.container.cluster.ingress.statusPort STATUS_PORT
Muestra los valores de los métodos set de
kpt
:kpt cfg list-setters asm
En el resultado del comando, verifica que los valores de los siguientes métodos set sean correctos:
- anthos.servicemesh.rev
- gcloud.compute.location
- gcloud.container.cluster
- gcloud.container.cluster.ingress.httpPort
- gcloud.container.cluster.ingress.statusPort
- gcloud.core.project
- gcloud.project.environProjectNumber
Continúa con la guía de instalación en la sección Instala Anthos Service Mesh. Después de instalar Anthos Service Mesh, regresa a esta guía y continúa con la siguiente sección para configurar la integración con IAP.
Actualizaciones
Los pasos de esta sección complementan los pasos en la guía Actualiza Anthos Service Mesh en GKE. En estos pasos, se usan las variables de entorno que creas en la guía de actualización. En esta sección, se abarcan los siguientes casos de uso de actualización:
Ya configuraste la integración de IAP y realizas la actualización de Anthos Service Mesh. En este caso, ya habilitaste
iap.googleapis.com
en el proyecto y el complementoHttpLoadBalancing
en el clúster, por lo que puedes pasar al paso 3.Estás actualizando Anthos Service Mesh y quieres configurar la integración con IAP por primera vez. En este caso, debes completar todos los pasos siguientes, actualizar Anthos Service Mesh y volver a esta guía después de la actualización para completar la integración.
Habilita
iap.googleapis.com
.gcloud services enable \ --project=$PROJECT_ID \ iap.googleapis.com
Habilita el complemento
HttpLoadBalancing
. El complementoHttpLoadBalancing
habilita un controlador de balanceo de cargas HTTP (L7) para el clúster.gcloud container clusters update ${CLUSTER_NAME} \ --project=PROJECT_ID \ --update-addons=HttpLoadBalancing=ENABLED
Si no configuraste una zona o una región predeterminada, debes proporcionar la región (--region=${CLUSTER_LOCATION}) o la zona (--zone=${CLUSTER_LOCATION}) en el comando anterior.
Continúa con la guía de actualización para configurar credenciales y permisos y descargar el archivo de instalación. Detente en la sección Prepara archivos de configuración de los recursos y realiza los siguientes pasos en su lugar.
Crea un directorio nuevo para los archivos de configuración de recursos del paquete de Anthos Service Mesh. Recomendamos que uses el nombre del clúster como el nombre del directorio.
Cambia al directorio en el que deseas descargar el paquete de Anthos Service Mesh.
Descarga el paquete
asm-iap
. Este paquete configura el campotype
en el servicioistio-ingressgateway
comoNodePort
. En esta configuración,istio-ingressgateway
abre un puerto específico en la malla de servicios. Esto te permite configurar un balanceador de cargas, que enruta el tráfico enviado a tu nombre de dominio a este puerto.kpt pkg get https://github.com/GoogleCloudPlatform/anthos-service-mesh-packages.git/asm-iap@release-1.6-asm asm
Configura el ID del proyecto en el que se creó el clúster:
kpt cfg set asm gcloud.core.project PROJECT_ID
Configura el número de proyecto para el proyecto host de la flota:
kpt cfg set asm gcloud.project.environProjectNumber ${FLEET_PROJECT_NUMBER}
Configura el nombre del clúster:
kpt cfg set asm gcloud.container.cluster ${CLUSTER_NAME}
Establece la zona o región predeterminada:
kpt cfg set asm gcloud.compute.location ${CLUSTER_LOCATION}
Configura el webhook de validación para usar una etiqueta de revisión:
kpt cfg set asm anthos.servicemesh.rev asm-1614-2
Establece el perfil de configuración. Para la integración de IAP, configura el perfil
asm-gcp
:kpt cfg set asm anthos.servicemesh.profile asm-gcp
Configura los puertos de estado y HTTP para el balanceador de cargas. El puerto de estado predeterminado es 31223, y el puerto HTTP predeterminado es 31224.
Si actualizas un balanceador de cargas HTTP existente de Cloud, ejecuta lo siguiente para conservar los puertos HTTP y de estado existentes:
kpt cfg set asm gcloud.container.cluster.ingress.httpPort $(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
kpt cfg set asm gcloud.container.cluster.ingress.statusPort $(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="status-port")].nodePort}')
Si es necesario, puedes usar los métodos set
kpt
anteriores a fin de establecer otros valores para los puertos.Muestra los valores de los métodos set de
kpt
:kpt cfg list-setters asm
En el resultado del comando, verifica que los valores de los siguientes métodos set sean correctos:
- anthos.servicemesh.rev
- gcloud.compute.location
- gcloud.container.cluster
- gcloud.container.cluster.ingress.httpPort
- gcloud.container.cluster.ingress.statusPort
- gcloud.core.project
- gcloud.project.environProjectNumber
Continúa con la guía de actualización en la sección Actualiza Anthos Service Mesh.
Reserva una dirección IP estática y configura el DNS
Para integrar Identity-Aware Proxy en Anthos Service Mesh, debes configurar un balanceador de cargas HTTP(S) de Google Cloud, que requiere un nombre de dominio que apunte a una dirección IP estática. Puedes reservar una dirección IP externa estática, que asigna la dirección a tu proyecto de forma indefinida hasta que se libere de manera explícita.
Reserva una dirección IP externa estática:
gcloud compute addresses create example-static-ip --global
Obtén la dirección IP estática:
gcloud compute addresses describe example-static-ip --global
En tu registrador de nombres de dominio, configura un nombre de dominio completamente calificado (FQDN) con la dirección IP estática. Por lo general, agregas un registro
A
a tu configuración de DNS. Los pasos de configuración y la terminología necesarias a fin de agregar un registroA
para un FQDN varían según el registrador de nombres de dominio.La propagación de la configuración de DNS puede llevar entre 24 y 48 horas. Puedes seguir con los otros ajustes en esta guía, pero no podrás probarla hasta que se propague la configuración del DNS.
Implementa una aplicación de muestra
Antes de habilitar IAP, necesitas una aplicación que se ejecute en tu clúster de GKE para que puedas verificar que todas las solicitudes tengan una identidad. En esta guía, se usa el ejemplo de Bookinfo para demostrar cómo configurar el balanceador de cargas de HTTP(S) y habilitar IAP.
Sigue los pasos para implementar Bookinfo. Hasta que implementes el balanceador de cargas, la aplicación Bookinfo no será accesible fuera de tu clúster de GKE (por ejemplo, desde un navegador).
Solicitudes externas
El recurso de puerta de enlace de Bookinfo (definido en samples/bookinfo/networking/bookinfo-gateway.yaml
) usa istio-ingressgateway
preconfigurado.
Recuerda que cuando implementaste Anthos Service Mesh, especificaste NodePort
para istio-ingressgateway
, que abre un puerto específico en la malla de servicios.
Aunque los nodos de tu clúster tienen direcciones IP externas, las reglas de firewall de Google Cloud bloquean las solicitudes que provienen de afuera del clúster. Con IAP, la forma correcta de exponer las aplicaciones a la Internet pública es mediante un balanceador de cargas. No expongas las direcciones del nodo mediante reglas de firewall, que podrían omitir IAP.
Para enrutar solicitudes a Bookinfo, configura un balanceador de cargas HTTP(S) en tu proyecto de Google Cloud. Debido a que el balanceador de cargas está en tu proyecto, está dentro del firewall y puede acceder a los nodos en tu clúster. Después de configurar el balanceador de cargas con la dirección IP estática y tu nombre de dominio, puedes enviar solicitudes al nombre de dominio, y el balanceador de cargas reenviará las solicitudes a los nodos del clúster.
Habilita IAP
En los siguientes pasos, se describe cómo habilitar IAP.
Configura la pantalla de consentimiento
Para verificar si ya tienes una marca existente, usa el comando list. Solo puedes tener una marca por proyecto.
gcloud iap oauth-brands list
El siguiente es un ejemplo de respuesta de gcloud, si la marca existe:
name: projects/[PROJECT_NUMBER]/brands/[BRAND_ID] applicationTitle: [APPLICATION_TITLE] supportEmail: [SUPPORT_EMAIL] orgInternalOnly: true
Si no existe una marca, usa el comando create:
gcloud iap oauth-brands create --application_title=APPLICATION_TITLE --support_email=SUPPORT_EMAIL
Los campos anteriores son obligatorios cuando se llama a esta API:
supportEmail
: Es el correo electrónico de asistencia que se muestra en la pantalla de consentimiento de OAuth. Esta dirección de correo electrónico puede ser la dirección de un usuario o un alias de Grupos de Google. Si bien las cuentas de servicio también tienen una dirección de correo electrónico, no son direcciones de correo electrónico válidas reales y no se pueden usar cuando se crea una marca. Sin embargo, una cuenta de servicio puede ser propietaria de un Grupo de Google. Crea un Grupo de Google nuevo o configura un grupo existente y configura la cuenta de servicio deseada como propietaria del grupo.applicationTitle
: Es el nombre de la aplicación que se muestra en la pantalla de consentimiento de OAuth.
La respuesta contiene los siguientes campos:
name: projects/[PROJECT_NUMBER]/brands/[BRAND_ID] applicationTitle: [APPLICATION_TITLE] supportEmail: [SUPPORT_EMAIL] orgInternalOnly: true
Crea un cliente de OAuth para IAP
Usa el comando create para crear un cliente. Usa la marca
name
del paso anterior:gcloud iap oauth-clients create projects/PROJECT_NUMBER/brands/BRAND-ID --display_name=NAME
La respuesta contiene los siguientes campos:
name: projects/[PROJECT_NUMBER]/brands/[BRAND_NAME]/identityAwareProxyClients/[CLIENT_ID] secret: [CLIENT_SECRET] displayName: [NAME]
Usa el ID de cliente (
CLIENT_ID
en el paso anterior) yCLIENT_SECRET
para habilitar IAP. Crea un secreto de Kubernetes con los materiales de tu cliente de OAuth:kubectl create secret generic -n istio-system my-secret --from-literal=client_id=CLIENT_ID \ --from-literal=client_secret=CLIENT_SECRET
Implementa el balanceador de cargas
Puedes usar un recurso Ingress para crear un balanceador de cargas de HTTP(S) con certificados SSL configurados de forma automática. Los certificados SSL administrados por Google se aprovisionan, renuevan y administran para tu dominio.
Crea un recurso ManagedCertificate. Este recurso especifica el dominio para el certificado SSL. La lista
spec.domains
debe contener solo un dominio. No se admiten dominios comodines. En el siguiente YAML, reemplazaDOMAIN_NAME
por el nombre de dominio que configuraste para la dirección IP estática externa.cat <<EOF | kubectl apply -f - apiVersion: networking.gke.io/v1beta1 kind: ManagedCertificate metadata: name: example-certificate namespace: istio-system spec: domains: - DOMAIN_NAME EOF
Crea un recurso BackendConfig. Este recurso le indica a GCLB cómo realizar verificaciones de estado en la puerta de enlace de entrada y cómo configurar Identity-Aware Proxy. Primero, recopila algunos valores de la puerta de enlace de entrada sobre las verificaciones de estado:
Puerto de entrada de la verificación de estado: Este es el puerto de verificación de estado de istio-ingress.
export HC_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="status-port")].nodePort}')
Ruta de acceso de la verificación de estado de la entrada: Esta es la ruta de la verificación de estado de istio-ingress.
export HC_INGRESS_PATH=$(kubectl -n istio-system get deployments istio-ingressgateway -o jsonpath='{.spec.template.spec.containers[?(@.name=="istio-proxy")].readinessProbe.httpGet.path}')
cat <<EOF | kubectl apply -n istio-system -f - apiVersion: cloud.google.com/v1beta1 kind: BackendConfig metadata: name: http-hc-config spec: healthCheck: checkIntervalSec: 2 timeoutSec: 1 healthyThreshold: 1 unhealthyThreshold: 10 port: ${HC_INGRESS_PORT} type: HTTP requestPath: ${HC_INGRESS_PATH} iap: enabled: true oauthclientCredentials: secretName: my-secret EOF
Anota el servicio de entrada con tu BackendConfig.
kubectl annotate -n istio-system service/istio-ingressgateway --overwrite \ cloud.google.com/backend-config='{"default": "http-hc-config"}' \ cloud.google.com/neg='{"ingress":false}'
Crea el balanceador de cargas mediante la definición del recurso Ingress.
Configura la anotación
networking.gke.io/managed-certificates
con el nombre del certificado que creaste en el paso anterior,example-certificate
.Configura la anotación
kubernetes.io/ingress.global-static-ip-name
con el nombre de la dirección IP estática que reservaste,example-static-ip
.Configura
serviceName
comoistio-ingressgateway
, que se usa en el recurso Gateway para la muestra de Bookinfo.
cat <<EOF | kubectl create -f - apiVersion: extensions/v1beta1 kind: Ingress metadata: name: example-ingress namespace: istio-system annotations: kubernetes.io/ingress.global-static-ip-name: example-static-ip networking.gke.io/managed-certificates: example-certificate spec: backend: serviceName: istio-ingressgateway servicePort: 80 EOF
En la consola de Google Cloud, ve a la página Kubernetes Engine > Ingress y servicios.
Ir a la página Ingress y Service
Deberías ver el mensaje “Creando Ingress” en la columna Estado. Espera a que GKE aprovisione por completo el Ingress antes de continuar. Actualiza la página cada pocos minutos para obtener el estado más actualizado del Ingress. Después de aprovisionar el Ingress, es posible que veas el estado “Ok” o el error “Todos los servicios de backend están en EN MAL ESTADO”. Uno de los recursos que GKE aprovisiona es una verificación de estado predeterminada. Si ves el mensaje de error, significa que se aprovisiona el Ingress y que se ejecutó la verificación de estado predeterminada. Cuando veas el estado “Ok” o el error, continúa con la siguiente sección para configurar las verificaciones de estado del balanceador de cargas.
Configura la lista de acceso de IAP
Agrega un usuario a la política de acceso de IAP:
gcloud beta iap web add-iam-policy-binding \ --member=user:EMAIL_ADDRESS \ --role=roles/iap.httpsResourceAccessor
En el ejemplo anterior, EMAIL_ADDRESS
es la dirección de correo electrónico completa del usuario, como alice@example.com
.
Prueba el balanceador de cargas. Apunta el navegador con el siguiente comando:
http://DOMAIN_NAME/productpage
En el ejemplo anterior,
DOMAIN_NAME
es el nombre de dominio que configuraste con la dirección IP estática externa.Deberías ver la
productpage
de la aplicación Bookinfo. Si actualizas la página varias veces, deberías ver diferentes reseñas, en un estilo round robin: estrellas rojas, estrellas negras, sin estrellas.También debes probar el acceso de
https
a Bookinfo.
Habilita la compatibilidad con RCToken en la malla de servicios
De forma predeterminada, IAP genera un token web JSON (JWT) con alcance para el cliente de OAuth. Para Anthos Service Mesh, puedes configurar IAP a fin de generar un RequestContextToken (RCToken), que es un JWT pero con un público configurable. Los RCToken te permiten configurar el público del JWT en una string arbitraria, que se puede usar en las políticas de Anthos Service Mesh para obtener una autorización detallada.
Para configurar el RCToken, haz lo siguiente:
Crea una variable de entorno para tu número de proyecto. Este es el número que se generó y asignó de forma automática a tu proyecto cuando lo creaste (no es lo mismo que el ID del proyecto):
export PROJECT_NUMBER=YOUR_PROJECT_NUMBER
Crea una variable de entorno para el público del RCToken. Puede ser cualquier string que desees:
export RCTOKEN_AUD="your-rctoken-aud"
Recupera la configuración de IAP:
gcloud beta iap settings get --format json \ --project=${PROJECT_NUMBER} --resource-type=compute > iapSettings.json
Actualiza
IapSettings
con el público del RCToken:cat iapSettings.json | jq --arg RCTOKEN_AUD_STR $RCTOKEN_AUD \ '. + {applicationSettings: {csmSettings: {rctokenAud: $RCTOKEN_AUD_STR}}}' \ > updatedIapSettings.json
gcloud beta iap settings set updatedIapSettings.json --format json \ --project=${PROJECT_NUMBER} --resource-type=compute
Habilita la autenticación de RCToken en la puerta de enlace de entrada de Istio:
cat <<EOF | kubectl apply -f - apiVersion: "security.istio.io/v1beta1" kind: "RequestAuthentication" metadata: name: "ingressgateway-jwt-policy" namespace: "istio-system" spec: selector: matchLabels: app: istio-ingressgateway jwtRules: - issuer: "https://cloud.google.com/iap" jwksUri: "https://www.gstatic.com/iap/verify/public_key-jwk" audiences: - $RCTOKEN_AUD fromHeaders: - name: ingress-authorization prefix: "Istio " outputPayloadToHeader: "verified-jwt" forwardOriginalToken: true EOF
Asegúrate de que las solicitudes a la
productpage
de Bookinfo aún tengan éxito:http://DOMAIN_NAME/productpage
Para probar la política, haz lo siguiente:
Crea un objeto de solicitud
IapSettings
, pero establecerctokenAud
en una string diferente:echo $(cat <<EOF { "name": "projects/${PROJECT_NUMBER}/iap_web/compute", "applicationSettings": { "csmSettings": { "rctokenAud": "some-other-arbitrary-string" } } } EOF ) > request.txt
Llama a la API de
IapSettings
para configurar el público del RCToken:curl --request PATCH --header "Authorization: Bearer $(gcloud beta auth application-default print-access-token)" ${IAP_SETTINGS_API}
Realiza una solicitud a la
productpage
de Bookinfo, que debería fallar:http://DOMAIN_NAME/productpage
Realice una limpieza
Después de completar este instructivo, quita los siguientes recursos para evitar que se realicen cargos no deseados en tu cuenta:
Borra el certificado administrado:
kubectl delete managedcertificates example-certificate
Borra el Ingress, lo que quita la asignación de los recursos del balanceo de cargas:
kubectl -n istio-system delete ingress example-ingress
Borra la dirección IP estática:
gcloud compute addresses delete example-static-ip --global
Si haces esto, asegúrate de borrar la dirección IP del registrador de tu dominio.
Borra el clúster, lo que borrará los recursos que conforman el clúster, como las instancias de procesamiento, los discos y los recursos de red:
gcloud container clusters delete ${CLUSTER_NAME}