Cloud Service Mesh a través de ejemplos: Autorización


En este instructivo, aprenderás qué es la autorización y cómo habilitarla con Cloud Service Mesh en una aplicación de ejemplo para aprender a habilitar políticas de autorización en tus microservicios. Crearás un acceso de AuthorizationPolicy a DENY a un microservicio y, luego, un acceso específico de AuthorizationPolicy a ALLOW 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 permitido hacerlo? La identidad es fundamental para esta idea. Con Cloud Service Mesh, AuthorizationPolicies permite controlar la comunicación de carga de trabajo a carga de trabajo en tu malla para mejorar la seguridad y el acceso.

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

  • Controla el acceso a las cargas de trabajo dentro de tu malla, ya sea de carga de trabajo a carga de trabajo o de usuario final a carga de trabajo.
  • Define las políticas de forma general o detallada según tus necesidades. Para ver una explicación detallada sobre la configuración de políticas y prácticas recomendadas, consulta Autorización con Cloud Service Mesh.

Costos

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

Cuando completes el instructivo puedes borrar los recursos que hayas creado para evitar que se te sigan cobrando. Para obtener más información, consulta Cómo realizar una limpieza.

Antes de comenzar

  • Clone el repositorio:

    git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-samples
    cd anthos-service-mesh-samples
    

Implementa una puerta de enlace de entrada

  1. Establece el contexto actual para 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 puerta de enlace de entrada:

    kubectl create namespace asm-ingress
    
  3. Habilita el espacio de nombres para la inserción. Los pasos dependen del tipo de Cloud Service Mesh (administrado o en el clúster):

    Administrado

    Aplica la etiqueta de revisión asm-managed al espacio de nombres:

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

    Esta etiqueta corresponde al canal de versiones administrado de Cloud Service Mesh correspondiente a la versión de Cloud Service Mesh.

    En el clúster

    1. Usa el siguiente comando para encontrar 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 a los espacios de nombres. En el siguiente comando, REVISION es el valor de la etiqueta de revisión istiod que anotaste en el paso anterior.

      kubectl label namespace asm-ingress \
        istio-injection- istio.io/rev=REVISION --overwrite
      
  4. Implementa la puerta de enlace 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
    

Implementa la aplicación de muestra de Online Boutique.

  1. Si aún no lo hiciste, establece 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 para la aplicación de ejemplo:

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

  4. Implementa la app de ejemplo, el VirtualService para el frontend y las cuentas de servicio para las cargas de trabajo. En este instructivo, implementarás Online Boutique, una app de demo 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
    

Cómo ver tus servicios

  1. Visualiza los pods en el 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 en funcionamiento, con un 2/2 en la columna READY. Esto indica que los Pods tienen un proxy de sidecar de Envoy insertado de forma correcta. Si no aparece 2/2 después de un par de minutos, consulta la guía de solución de problemas.

  2. Obtén la IP externa y configúrala en 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ás 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 de Online Boutique en tu navegador.

    frontend de la boutique en línea

Autorización DenyAll para una carga de trabajo

En esta sección, se agrega un AuthorizationPolicy para denegar todo el tráfico entrante al servicio de moneda. AuthorizationPolicies funciona transformando AuthorizationPolicies en configuraciones que Envoy puede leer y aplicando las configuraciones a tus proxies de sidecar. Esto permite que el proxy de Envoy autorice o rechace las solicitudes entrantes a un servicio.

  1. Aplica un AuthorizationPolicy a la currencyservice. Observa la coincidencia en la etiqueta currencyservice del 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. Intenta acceder a EXTERNAL-IP de la puerta de enlace para ver Online Boutique en el navegador web. Deberías ver un error de autorización (error de servicio interno 500) de currency service.

    Error 500 de authz rbac

Observa los registros de tu proxy de sidecar

Para ver qué sucede en el proxy de sidecar, puedes revisar los registros del pod.

  1. Obtén el nombre de tu pod currencyservice:

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

    kubectl exec -it $CURRENCY_POD -n onlineboutique -c istio-proxy -- curl -X POST "http://localhost:15000/logging?level=trace"
    

    Resultado esperado: 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ías ver un mensaje enforced denied en los registros, que muestra que currencyservice está configurado para bloquear las solicitudes entrantes.

Permitir acceso restringido

En lugar de una política DENYALL, puedes establecer el acceso para que se permita en ciertas cargas de trabajo. Esto será relevante en una arquitectura de microservicios en la que deseas asegurarte de que solo los servicios autorizados puedan comunicarse entre sí.

En esta sección, habilitarás el servicio frontend y checkout para que se pueda comunicar con el servicio currency.

  1. En el siguiente archivo, observa que un source.principal(cliente) específico está en la lista de entidades permitidas 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"]

Aplica la política:

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

Limpia

Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos usados en este instructivo, borra el proyecto que contiene los recursos o conserva el proyecto y borra los recursos individuales.

Para evitar que se apliquen cargos continuos a tu cuenta de Google Cloud por los recursos que se usaron en este instructivo, puedes borrar el proyecto o borrar los recursos individuales.

Borra el proyecto

En Cloud Shell, borra el proyecto:

gcloud projects delete PROJECT_ID

Borra los recursos

  • Si deseas conservar el clúster y quitar la muestra de Online Retail, realiza la siguiente acción:

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

      kubectl delete namespace onlineboutique
      

      Resultado esperado:

      namespace "onlineboutique" deleted
      
    2. Borra el espacio de nombres de la puerta de enlace de entrada:

      kubectl delete namespace asm-ingress
      

      Resultado esperado:

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

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

¿Qué sigue?