Exemplo de Cloud Service Mesh: autorização


Neste tutorial, você vai aprender o que é autorização e como ativá-la com o Cloud Service Mesh em um aplicativo de amostra para saber como ativar políticas de autorização nos microsserviços. Você vai criar um acesso AuthorizationPolicy a DENY para um microsserviço e depois um acesso específico de AuthorizationPolicy a ALLOW para um microsserviço.

O que é autorização?

A autenticação verifica uma identidade: este é o serviço que afirmam ser? A autorização verifica a permissão: este serviço tem permissão para fazer isso? A identidade é fundamental para essa ideia. Com o Cloud Service Mesh, AuthorizationPolicies permite que a comunicação entre cargas de trabalho na malha seja controlada para melhorar a segurança e o acesso.

Em uma arquitetura de microsserviço, em que as chamadas são feitas entre os limites da rede, as regras de firewall baseadas em IP geralmente não são adequadas para proteger o acesso entre cargas de trabalho. Com o Cloud Service Mesh, é possível definir regras de autorização para:

  • Controle o acesso a cargas de trabalho na malha, seja de carga de trabalho para carga de trabalho ou de usuário final para carga de trabalho.
  • Defina políticas de maneira ampla ou granular, dependendo das suas necessidades.

Para uma explicação detalhada sobre a configuração de políticas e práticas recomendadas, consulte Autorização com o Cloud Service Mesh.

Custos

Neste tutorial, usamos o seguinte componente faturável do Google Cloud:

Ao concluir este tutorial, exclua os recursos criados para evitar custos contínuos. Para mais informações, consulte Limpeza.

Antes de começar

Implantar um gateway de entrada

  1. Defina o contexto atual de kubectl para o cluster:

    gcloud container clusters get-credentials CLUSTER_NAME  \
    --project=PROJECT_ID \
    --zone=CLUSTER_LOCATION 
    
  2. Crie um namespace para seu gateway de entrada:

    kubectl create namespace asm-ingress
    
  3. Ativar o namespace para injeção. As etapas dependem da implementação do plano de controle.

    Gerenciado (TD)

    Aplique o rótulo de injeção padrão ao namespace:

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

    Gerenciado (Istiod)

    Recomendado:execute o comando a seguir para aplicar o rótulo de injeção padrão ao namespace:

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

    Se você já for usuário do plano de controle do Istiod gerenciado:recomendamos que você use a injeção padrão, mas a injeção baseada em revisão é compatível. Siga estas instruções:

    1. Execute o seguinte comando para localizar os canais de lançamento disponíveis:

      kubectl -n istio-system get controlplanerevision
      

      O resultado será assim:

      NAME                AGE
      asm-managed-rapid   6d7h
      

      Na saída, o valor na coluna NAME é o rótulo de revisão que corresponde ao canal de lançamento disponível para a versão do Cloud Service Mesh.

    2. Aplique o rótulo de revisão ao namespace:

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

    No cluster

    Recomendado:execute o comando a seguir para aplicar o rótulo de injeção padrão ao namespace:

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

    Recomendamos que você use a injeção padrão, mas a injeção baseada em revisão tem suporte: Siga estas instruções:

    1. Use o seguinte comando para localizar o rótulo de revisão em istiod:

      kubectl get deploy -n istio-system -l app=istiod -o \
         jsonpath={.items[*].metadata.labels.'istio\.io\/rev'}'{"\n"}'
      
    2. Aplique o rótulo de revisão ao namespace. No comando a seguir, REVISION_LABEL é o valor do rótulo de revisão istiod que você anotou na etapa anterior.

      kubectl label namespace asm-ingress \
          istio-injection- istio.io/rev=REVISION_LABEL --overwrite
      
  4. Implante o gateway de exemplo no repositório anthos-service-mesh-samples:

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

    Saída esperada:

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

Implantar o aplicativo de amostra Online Boutique

  1. Caso contrário, defina o contexto atual de kubectl para o cluster:

    gcloud container clusters get-credentials CLUSTER_NAME  \
    --project=PROJECT_ID \
    --zone=CLUSTER_LOCATION 
    
  2. Crie o namespace do aplicativo de amostra:

    kubectl create namespace onlineboutique
    
  3. Rotule o namespace onlineboutique para injetar automaticamente proxies do Envoy. Siga as etapas para ativar a injeção automática de arquivo secundário.

  4. Implante o aplicativo de amostra, o VirtualService para o front-end e as contas de serviço para as cargas de trabalho. Neste tutorial, você vai implantar o Online Boutique, um app de demonstração de microsserviços.

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

Ver seus serviços

  1. Veja os pods no namespace onlineboutique:

    kubectl get pods -n onlineboutique
    

    Saída esperada:

    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 os pods do aplicativo devem estar em execução, com um 2/2 na coluna READY. Isso indica que os pods têm um proxy sidecar do Envoy injetado com sucesso. Se ele não mostrar 2/2 após alguns minutos, acesse o Guia de solução de problemas.

  2. Defina o IP externo e uma variável:

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

    Você verá uma saída semelhante a esta:

    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. Acesse o endereço EXTERNAL-IP no navegador da Web. Você vai encontrar a loja Online Boutique no seu navegador.

    front-end do online boutique

Negar a autorização de uma carga de trabalho

Esta seção adiciona um AuthorizationPolicy para negar todo o tráfego de entrada ao serviço de moeda. O AuthorizationPolicies funciona transformando AuthorizationPolicies em configurações legíveis por Envoy e aplicando as configurações aos seus proxies sidecar. Isso permite que o proxy Envoy autorize ou negue solicitações recebidas para um serviço.

  1. Aplique um AuthorizationPolicy ao currencyservice. Observe a correspondência no identificador currencyservice no arquivo 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. Acesse o EXTERNAL-IP do seu gateway para conferir o Online Boutique no navegador da Web. Você vai encontrar um erro de autorização (500 Internal Service Error) de currency service.

    erro do authz rbac 500

Observar os registros do proxy sidecar

Para saber o que está acontecendo no proxy sidecar, é possível analisar os registros no pod.

  1. Consiga o nome do seu pod currencyservice:

    CURRENCY_POD=$(kubectl get pod -n onlineboutique |grep currency|awk '{print $1}')
    
  2. Defina o proxy Envoy para permitir registros no nível do trace. Por padrão, as chamadas de autorização bloqueadas não são registradas:

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

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

  3. Use o curl para enviar tráfego ao EXTERNAL_IP para gerar registros:

    for i in {0..10}; do
    curl -s -I $FRONTEND_IP ; done
    
  4. Veja os registros relacionados ao controle de acesso baseado em papéis (RBAC) no seu istio-proxy:

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

    Saída esperada:

    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]
      ```
    

Você verá uma mensagem enforced denied nos registros, mostrando que currencyservice está definido para bloquear solicitações de entrada.

Permitir acesso restrito

Em vez de uma política DENYALL, é possível definir o acesso permitido para determinadas cargas de trabalho. Isso será relevante em uma arquitetura de microsserviço em que você quer garantir que somente serviços autorizados possam se comunicar entre si.

Nesta seção, você vai ativar a capacidade de comunicação do serviço frontend e checkout com o serviço currency.

  1. No arquivo abaixo, confira que um source.principal(cliente) específico tem permissão para acessar 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. Aplique a política:

    kubectl apply -f docs/authorization/currency-allow-frontend-checkout.yaml -n onlineboutique
    
  2. Acesse EXTERNAL-IP no navegador da Web. Agora você deve poder acessar o Online Boutique.

Limpar

Para evitar cobranças na sua conta do Google Cloud pelos recursos usados no tutorial, exclua o projeto que os contém ou mantenha o projeto e exclua os recursos individuais.

Para evitar cobranças recorrentes na conta do Google Cloud pelos recursos usados neste tutorial, é possível excluir o projeto ou excluir os recursos individuais.

Exclua o projeto

No Cloud Shell, exclua o projeto:

gcloud projects delete PROJECT_ID

Excluir os recursos

  • Se quiser manter o cluster e remover o aplicativo de amostra do Online Boutique:

    1. Exclua os namespaces do aplicativo:

      kubectl delete namespace onlineboutique
      

      Saída esperada:

      namespace "onlineboutique" deleted
      
    2. Exclua o namespace do gateway de entrada:

      kubectl delete namespace asm-ingress
      

      Saída esperada:

      amespace "asm-ingress" deleted
      
  • Se quiser evitar cobranças adicionais, exclua o cluster:

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

A seguir