Cloud Service Mesh 示例:授权


在本教程中,您将了解什么是授权以及如何启用授权 在示例应用中使用 Cloud Service Mesh 来了解如何启用 授权政策您将创建一个 AuthorizationPolicyDENY 对微服务的访问权限,然后创建一个 对微服务的 AuthorizationPolicyALLOW 特定访问权限。

什么是授权?

身份验证旨在验证身份,即此服务是否是他们声称的身份? 授权流程则用于验证权限,即确定此服务是否有权执行某项操作。身份是这一概念的基础。借助 Cloud Service Mesh AuthorizationPolicies 允许在 Google Cloud 控制台中 受到控制,以提高安全性和访问性。

在跨网络边界进行调用的微服务架构中, 基于 IP 的防火墙规则通常不足以保证各组织之间的安全访问 工作负载借助 Cloud Service Mesh,您可以将授权规则设置为:

  • 控制对网格中工作负载的访问,既可以是工作负载到工作负载, end-user-to-workload
  • 根据您的需求广泛或精细地定义政策。

如需深入了解配置策略和最佳实践的说明,请参阅 使用 Cloud Service Mesh 进行授权

费用

本教程使用 Google Cloud 的以下收费组件:

完成本教程后,您可以删除所创建的资源以避免持续产生费用。如需了解详情,请参阅清理

准备工作

部署入站流量网关

  1. kubectl 的当前上下文设置为相应集群:

    gcloud container clusters get-credentials CLUSTER_NAME  \
    --project=PROJECT_ID \
    --zone=CLUSTER_LOCATION 
    
  2. 为入站流量网关创建命名空间:

    kubectl create namespace asm-ingress
    
  3. 启用用于注入的命名空间。相关步骤取决于您的控制平面实现

    受管 (TD)

    将默认注入标签应用于命名空间:

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

    代管式 (Istiod)

    建议:运行以下命令,将默认注入标签应用于命名空间:

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

    如果您是使用 Managed Istiod 控制平面的现有用户: 我们建议您使用默认注入,但基于修订版本的注入 支持。请按照以下说明操作:

    1. 运行以下命令查找可用的发布渠道:

      kubectl -n istio-system get controlplanerevision
      

      输出类似于以下内容:

      NAME                AGE
      asm-managed-rapid   6d7h
      

      在输出中,NAME 列下的值是与 Cloud Service Mesh 版本的可用发布版本对应的修订版本标签。

    2. 将修订版本标签应用于命名空间:

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

    集群内

    建议:运行以下命令,将默认注入标签应用于命名空间:

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

    我们建议您使用默认注入,但支持基于修订版本的注入: 请按照以下说明操作:

    1. 使用以下命令查找 istiod 的修订版本标签:

      kubectl get deploy -n istio-system -l app=istiod -o \
         jsonpath={.items[*].metadata.labels.'istio\.io\/rev'}'{"\n"}'
      
    2. 将修订版本标签应用于命名空间。在以下命令中,REVISION_LABEL 是您在上一步中记下的 istiod 修订版本标签的值。

      kubectl label namespace asm-ingress \
          istio-injection- istio.io/rev=REVISION_LABEL --overwrite
      
  4. anthos-service-mesh-samples 代码库中部署示例网关:

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

    预期输出:

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

部署 Online Boutique 示例应用

  1. kubectl 的当前上下文设置为相应集群(如果尚未设置):

    gcloud container clusters get-credentials CLUSTER_NAME  \
    --project=PROJECT_ID \
    --zone=CLUSTER_LOCATION 
    
  2. 为示例应用创建命名空间:

    kubectl create namespace onlineboutique
    
  3. onlineboutique 命名空间添加标签以自动注入 Envoy 代理。按照相关步骤启用自动边车注入

  4. 部署示例应用、前端的 VirtualService 以及工作负载的服务账号。在本教程中,您将部署 Online Boutique,这是一个微服务演示版应用。

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

查看服务

  1. 查看 onlineboutique 命名空间中的 Pod:

    kubectl get pods -n onlineboutique
    

    预期输出:

    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
    

    应用的所有 Pod 都应启动并运行,READY 列中应显示 2/2。这表示 Pod 已成功注入 Envoy 边车代理。 如果几分钟后没有显示 2/2,请查看问题排查指南

  2. 获取外部 IP 并将其设置为变量:

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

    您将看到类似如下所示的输出:

    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. 在网络浏览器中访问 EXTERNAL-IP 地址。您应该会看到 在浏览器中打开 Online Boutique 商店。

    Online Boutique 前端

工作负载的 DenyAll 授权

此部分会添加一个 AuthorizationPolicy,以拒绝 货币服务。AuthorizationPolicies 通过转换工作 AuthorizationPolicies 到 Envoy 可读配置中,并将配置应用于 您的 Sidecar 代理。这使 Envoy 代理能够授权或拒绝传入 向服务发出请求

  1. 将一个 AuthorizationPolicy 应用于 currencyservice。请注意匹配 针对 YAML 文件中的 currencyservice 标签。

    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. 请尝试访问您网关的EXTERNAL-IP,以在网页上查看 Online Boutique 。您应该会看到授权错误(500 内部服务错误) currency service起。

    authz rbac 500 错误

查看边车代理日志

如需了解边车代理中发生了什么,您可以在 Pod。

  1. 获取 currencyservice Pod 的名称:

    CURRENCY_POD=$(kubectl get pod -n onlineboutique |grep currency|awk '{print $1}')
    
  2. 将 Envoy 代理设置为启用跟踪记录级别的日志。默认情况下,日志中不会记录被阻止的授权调用:

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

    预期输出:none {:.devsite-disable-click-to-copy} active loggers: admin: trace alternate_protocols_cache: trace ... tracing: trace upstream: trace udp: trace wasm: trace

  3. 使用 curl 将流量发送到您的 EXTERNAL_IP,以生成日志:

    for i in {0..10}; do
    curl -s -I $FRONTEND_IP ; done
    
  4. 查看 istio-proxy 中基于角色的访问权限控制 (RBAC) 相关的日志:

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

    预期输出:

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

您应该会在日志中看到一条 enforced denied 消息,显示 currencyservice 已设置为屏蔽入站请求。

允许受限访问

您可以不设置 DENYALL 政策,而是将特定的访问权限设置为允许访问 工作负载这与您希望使用的微服务架构相关 以确保只有获得授权的服务才能相互通信。

在本部分中,您将启用 frontendcheckout 服务, 与 currency 服务通信的功能。

  1. 在以下文件中,您可以看到特定的 source.principal(客户端) 被允许访问“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. 应用政策:

    kubectl apply -f docs/authorization/currency-allow-frontend-checkout.yaml -n onlineboutique
    
  2. 在网络浏览器中访问 EXTERNAL-IP,您现在应该能够访问 Online Boutique。

清理

为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。

为避免系统持续向您的 Google Cloud 账号收取 本教程中使用的资源,您可以 删除项目或删除 各个资源

删除项目

在 Cloud Shell 中,删除项目:

gcloud projects delete PROJECT_ID

删除资源

  • 如果您希望保留集群并移除 Online Boutique 示例,请执行以下操作:

    1. 删除应用命名空间:

      kubectl delete namespace onlineboutique
      

      预期输出:

      namespace "onlineboutique" deleted
      
    2. 删除入站流量网关命名空间:

      kubectl delete namespace asm-ingress
      

      预期输出:

      amespace "asm-ingress" deleted
      
  • 如果您想防止产生额外费用,请删除集群:

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

后续步骤