Cloud Service Mesh mediante ejemplo: autorización


En este tutorial, aprenderás qué es la autorización y cómo habilitarla con Cloud Service Mesh en una aplicación de ejemplo para descubrir cómo habilitar políticas de autorización en tus microservicios. Crearás un AuthorizationPolicy para DENY acceder a un microservicio y, a continuación, crearás un AuthorizationPolicy para ALLOW acceder de forma específica a un microservicio.

¿Qué es la autorización?

La autenticación verifica una identidad: ¿este servicio es quien dice ser? La autorización verifica el permiso: ¿este servicio tiene permiso para hacerlo? La identidad es fundamental para esta idea. Con Cloud Service Mesh, AuthorizationPolicies permite controlar la comunicación entre cargas de trabajo de tu malla para mejorar la seguridad y el acceso.

En una arquitectura de microservicios, en la que las llamadas se realizan a través de límites de red, las reglas de cortafuegos basadas en IP no suelen ser adecuadas para proteger el acceso entre cargas de trabajo. Con Cloud Service Mesh, puedes definir reglas de autorización para lo siguiente:

  • Controlar el acceso a las cargas de trabajo de tu malla, ya sea de carga de trabajo a carga de trabajo o de usuario final a carga de trabajo
  • Define políticas de forma general o granular según tus necesidades.

Para ver una explicación detallada sobre cómo configurar políticas y las prácticas recomendadas, consulta Autorización con Cloud Service Mesh.

Costes

En este tutorial se usan los siguientes componentes facturables de Google Cloud:

Cuando termines este tutorial, puedes evitar costes continuos eliminando los recursos que hayas creado. Para obtener más información, consulta la sección Limpiar.

Antes de empezar

Desplegar una pasarela de entrada

  1. Define el contexto actual de kubectl en el clúster:

    gcloud container clusters get-credentials CLUSTER_NAME  \
    --project=PROJECT_ID \
    --zone=CLUSTER_LOCATION 
    
  2. Crea un espacio de nombres para tu pasarela de entrada:

    kubectl create namespace asm-ingress
    
  3. Habilita el espacio de nombres para la inyección. Los pasos dependen de la implementación del plano de control.

    Gestionado (TD)

    Aplica la etiqueta de inyección predeterminada al espacio de nombres:

    kubectl label namespace asm-ingress \
        istio.io/rev- istio-injection=enabled --overwrite
    

    Gestionado (Istiod)

    Recomendación: Ejecuta el siguiente comando para aplicar la etiqueta de inyección predeterminada al espacio de nombres:

      kubectl label namespace asm-ingress \
          istio.io/rev- istio-injection=enabled --overwrite
    

    Si ya eres usuario del plano de control de Istiod gestionado: Te recomendamos que utilices la inyección predeterminada, pero también se admite la inyección basada en revisiones. Sigue estas instrucciones:

    1. Ejecuta el siguiente comando para localizar los canales de lanzamiento disponibles:

      kubectl -n istio-system get controlplanerevision
      

      El resultado debería ser similar al siguiente:

      NAME                AGE
      asm-managed-rapid   6d7h
      

      En el resultado, el valor de la columna NAME es la etiqueta de revisión que corresponde al canal de lanzamiento disponible para la versión de Cloud Service Mesh.

    2. Aplica la etiqueta de revisión al espacio de nombres:

      kubectl label namespace asm-ingress \
          istio-injection- istio.io/rev=REVISION_LABEL --overwrite
      

    En el clúster

    Recomendación: Ejecuta el siguiente comando para aplicar la etiqueta de inyección predeterminada al espacio de nombres:

      kubectl label namespace asm-ingress \
          istio.io/rev- istio-injection=enabled --overwrite
    

    Te recomendamos que uses la inyección predeterminada, pero también se admite la inyección basada en revisiones: Sigue estas instrucciones:

    1. Usa el siguiente comando para localizar la etiqueta de revisión en istiod:

      kubectl get deploy -n istio-system -l app=istiod -o \
         jsonpath={.items[*].metadata.labels.'istio\.io\/rev'}'{"\n"}'
      
    2. Aplica la etiqueta de revisión al espacio de nombres. En el siguiente comando, REVISION_LABEL es el valor de la etiqueta de revisión istiod que has anotado en el paso anterior.

      kubectl label namespace asm-ingress \
          istio-injection- istio.io/rev=REVISION_LABEL --overwrite
      
  4. Despliega la pasarela de ejemplo en el repositorio anthos-service-mesh-samples:

    kubectl apply -n asm-ingress \
    -f docs/shared/asm-ingress-gateway
    

    Resultado esperado:

    serviceaccount/asm-ingressgateway configured
    service/asm-ingressgateway configured
    deployment.apps/asm-ingressgateway configured
    gateway.networking.istio.io/asm-ingressgateway configured
    

Implementar la aplicación de ejemplo Online Boutique

  1. Si no lo ha hecho, defina el contexto actual de kubectl en el clúster:

    gcloud container clusters get-credentials CLUSTER_NAME  \
    --project=PROJECT_ID \
    --zone=CLUSTER_LOCATION 
    
  2. Crea el espacio de nombres de la aplicación de ejemplo:

    kubectl create namespace onlineboutique
    
  3. Etiqueta el espacio de nombres onlineboutique para insertar automáticamente proxies de Envoy. Sigue los pasos para habilitar la inyección automática de sidecar.

  4. Implementa la aplicación de ejemplo, el VirtualService del frontend y las cuentas de servicio de las cargas de trabajo. En este tutorial, desplegarás Online Boutique, una aplicación de demostración de microservicios.

    kubectl apply \
    -n onlineboutique \
    -f docs/shared/online-boutique/virtual-service.yaml
    kubectl apply \
    -n onlineboutique \
    -f docs/shared/online-boutique/service-accounts
    

Ver tus servicios

  1. Consulta los pods del espacio de nombres onlineboutique:

    kubectl get pods -n onlineboutique
    

    Resultado esperado:

    NAME                                     READY   STATUS    RESTARTS   AGE
    adservice-85598d856b-m84m6               2/2     Running   0          2m7s
    cartservice-c77f6b866-m67vd              2/2     Running   0          2m8s
    checkoutservice-654c47f4b6-hqtqr         2/2     Running   0          2m10s
    currencyservice-59bc889674-jhk8z         2/2     Running   0          2m8s
    emailservice-5b9fff7cb8-8nqwz            2/2     Running   0          2m10s
    frontend-77b88cc7cb-mr4rp                2/2     Running   0          2m9s
    loadgenerator-6958f5bc8b-55q7w           2/2     Running   0          2m8s
    paymentservice-68dd9755bb-2jmb7          2/2     Running   0          2m9s
    productcatalogservice-84f95c95ff-c5kl6   2/2     Running   0          114s
    recommendationservice-64dc9dfbc8-xfs2t   2/2     Running   0          2m9s
    redis-cart-5b569cd47-cc2qd               2/2     Running   0          2m7s
    shippingservice-5488d5b6cb-lfhtt         2/2     Running   0          2m7s
    

    Todos los pods de tu aplicación deben estar operativos y tener un 2/2 en la columna READY. Esto indica que los pods tienen un proxy sidecar de Envoy insertado correctamente. Si no aparece 2/2 al cabo de un par de minutos, consulta la guía de solución de problemas.

  2. Obtén la IP externa y asígnala a una variable:

    kubectl get services -n asm-ingress
    export FRONTEND_IP=$(kubectl --namespace asm-ingress \
    get service --output jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}' \
    )
    

    Verá un resultado similar al siguiente:

    NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                                      AGE
    asm-ingressgateway   LoadBalancer   10.19.247.233   35.239.7.64   80:31380/TCP,443:31390/TCP,31400:31400/TCP   27m
    
    
  3. Visita la dirección EXTERNAL-IP en tu navegador web. Deberías ver la tienda Online Boutique en tu navegador.

    frontend de boutique online

Autorización DenyAll para una carga de trabajo

En esta sección se añade un AuthorizationPolicy para rechazar todo el tráfico entrante al servicio de moneda. AuthorizationPolicies transformando AuthorizationPolicies en configuraciones legibles por Envoy y aplicando las configuraciones a tus proxies sidecar. De esta forma, el proxy de Envoy puede autorizar o denegar las solicitudes entrantes a un servicio.

  1. Aplica un AuthorizationPolicy al currencyservice. Fíjate en la coincidencia de la etiqueta currencyservice en el archivo YAML.

    kubectl apply -f docs/authorization/currency-deny-all.yaml -n onlineboutique
    
    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
      name: currency-policy
    spec:
      selector:
        matchLabels:
          app: currencyservice
  2. Prueba a acceder a la EXTERNAL-IP de tu pasarela para ver Online Boutique en el navegador web. Debería ver un error de autorización (500 Internal Service Error) de currency service.

    Error 500 de RBAC de autorización

Observar los registros de tu proxy de sidecar

Para ver lo que ocurre en el proxy sidecar, puedes consultar los registros del pod.

  1. Obtener el nombre de tu currencyservice:

    CURRENCY_POD=$(kubectl get pod -n onlineboutique |grep currency|awk '{print $1}')
    
  2. Configura el proxy de Envoy para permitir los registros a nivel de traza. De forma predeterminada, las llamadas de autorización bloqueadas no se registran:

    kubectl debug --image istio/base --target istio-proxy -it $CURRENCY_POD -n onlineboutique -- curl -X POST "http://localhost:15000/logging?level=trace"
    

    Resultado esperado: none {:.devsite-disable-click-to-copy} active loggers: admin: trace alternate_protocols_cache: trace ... tracing: trace upstream: trace udp: trace wasm: trace

  3. Usa curl para enviar tráfico a tu EXTERNAL_IP y generar registros:

    for i in {0..10}; do
    curl -s -I $FRONTEND_IP ; done
    
  4. Consulta los registros relacionados con el control de acceso basado en roles (RBAC) en tu istio-proxy:

    kubectl logs -n onlineboutique $CURRENCY_POD -c istio-proxy | grep -m5 rbac
    

    Resultado esperado:

    2022-07-08T14:19:20.442920Z     debug   envoy rbac      checking request: requestedServerName: outbound_.7000_._.currencyservice.onlineboutique.svc.cluster.local, sourceIP: 10.8.8.5:34080, directRemoteIP: 10.8.8.5:34080, remoteIP: 10.8.8.5:34080,localAddress: 10.8.0.6:7000, ssl: uriSanPeerCertificate: spiffe://christineskim-tf-asm.svc.id.goog/ns/onlineboutique/sa/default, dnsSanPeerCertificate: , subjectPeerCertificate: OU=istio_v1_cloud_workload,O=Google LLC,L=Mountain View,ST=California,C=US, headers: ':method', 'POST'
    2022-07-08T14:19:20.442944Z     debug   envoy rbac      enforced denied, matched policy none
    2022-07-08T14:19:20.442965Z     debug   envoy http      [C73987][S13078781800499437460] Sending local reply with details rbac_access_denied_matched_policy[none]
      ```
    

Debería ver un mensaje enforced denied en los registros que indique que currencyservice está configurado para bloquear las solicitudes entrantes.

Permitir acceso restringido

En lugar de una política DENYALL, puedes permitir el acceso a determinadas cargas de trabajo. Esto será relevante en una arquitectura de microservicios en la que quieras asegurarte de que solo los servicios autorizados puedan comunicarse entre sí.

En esta sección, habilitarás los servicios frontend y checkout para que puedan comunicarse con el servicio currency.

  1. En el siguiente archivo, se muestra que un source.principal(cliente) específico tiene permiso para acceder a currencyservice:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: currency-policy
spec:
  selector:
    matchLabels:
      app: currencyservice
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/onlineboutique/sa/frontend"]
  - from:
    - source:
        principals: ["cluster.local/ns/onlineboutique/sa/checkoutservice"]
  1. Aplica la política:

    kubectl apply -f docs/authorization/currency-allow-frontend-checkout.yaml -n onlineboutique
    
  2. Visita EXTERNAL-IP en tu navegador web. Ahora deberías poder acceder a Boutique online.

Limpieza

Para evitar que los recursos utilizados en este tutorial se cobren en tu cuenta de Google Cloud, elimina el proyecto que contiene los recursos o conserva el proyecto y elimina los recursos.

Para evitar que se sigan aplicando cargos a tu cuenta de Google Cloud por los recursos utilizados en este tutorial, puedes eliminar el proyecto o eliminar los recursos.

Eliminar el proyecto

En Cloud Shell, elimina el proyecto:

gcloud projects delete PROJECT_ID

Eliminar los recursos

  • Si quieres conservar tu clúster y eliminar la muestra de Online Boutique, sigue estos pasos:

    1. Elimina los espacios de nombres de la aplicación:

      kubectl delete namespace onlineboutique
      

      Resultado esperado:

      namespace "onlineboutique" deleted
      
    2. Elimina el espacio de nombres de Ingress Gateway:

      kubectl delete namespace asm-ingress
      

      Resultado esperado:

      amespace "asm-ingress" deleted
      
  • Si quieres evitar cargos adicionales, elimina el clúster:

    gcloud container clusters delete  CLUSTER_NAME  \
    --project=PROJECT_ID \
    --zone=CLUSTER_LOCATION 
    

Siguientes pasos