外部授权

    在您开始之前,请执行以下操作:

    • 阅读 。

    • 根据 Istio 安装指南安装 Istio.

    • 部署测试工作负载:

      该任务使用两个工作负载,httpbinsleep,部署在一个命名空间 foo。这两个工作负载都包含 Envoy 代理边车容器。使用以下命令部署示例命名空间和工作负载:

      Zip

    • 使用以下命令校验 sleep 任务与 httpbin 的对话。

      1. $ kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl http://httpbin.foo:8000/ip -s -o /dev/null -w "%{http_code}\n"
      2. 200

    如果您在执行此任务时,没有看见到预期的输出,请您在几秒后重试。缓存和传播成本可能会导致一些延迟。

    部署外部授权器

    首先,您需要部署一个外部授权器。为此,您只需将示例外部授权器部署在网格中的独立Pod中。

    1. 运行以下命令以部署示例外部授权器:

      1. $ kubectl apply -n foo -f https://raw.githubusercontent.com/istio/istio/release-1.16/samples/extauthz/ext-authz.yaml
      2. service/ext-authz created
      3. deployment.apps/ext-authz created
      1. $ kubectl logs "$(kubectl get pod -l app=ext-authz -n foo -o jsonpath={.items..metadata.name})" -n foo -c ext-authz
      2. 2021/01/07 22:55:47 Starting HTTP server at [::]:8000
      3. 2021/01/07 22:55:47 Starting gRPC server at [::]:9000

    或者,您也可以将外部授权器与需要外部授权的应用程序部署在同一 Pod 内,甚至您也可以将其部署在网格之外。在这两种情况下,您还需要创建一个 ServiceEntry 资源来将服务注册到网格,并确保代理可以访问它。

    以下是将外部授权器部署在需要外部授权的应用程序同一 Pod 内时,您需要配置的示例 ServiceEntry。

    为了使用授权策略中的 CUSTOM 操作,您必须定义允许在网格中使用的外部授权器。这是目前在网格配置的中定义的。

    目前,唯一支持的扩展提供程序类型是 Envoy ext_authz。外部授权者必须实现对应的 Envoy ext_authz 检查接口。

    在本任务中,您将使用一个允许请求 Header 为 x-ext-authz: allow 的。

    1. 使用以下命令编辑网格配置:

      1. $ kubectl edit configmap istio -n istio-system
    2. 在编辑器中,添加如下所示的扩展提供者定义:

      以下内容定义了使用同一个 Service ext-authz.foo.svc.cluster.local 的两个外部提供程序 sample-ext-authz-grpcsample-ext-authz-http。该服务实现了由 Envoy ext_authz 过滤器定义的 HTTP 和 GRPC 检查 API。您将在接下来的步骤中部署该服务。

      1. data:
      2. # 添加以下内容以定义外部授权者。
      3. extensionProviders:
      4. - name: "sample-ext-authz-grpc"
      5. envoyExtAuthzGrpc:
      6. port: "9000"
      7. - name: "sample-ext-authz-http"
      8. envoyExtAuthzHttp:
      9. service: "ext-authz.foo.svc.cluster.local"
      10. port: "8000"
      11. includeRequestHeadersInCheck: ["x-ext-authz"]

      或者,您可以修改扩展提供程序,以控制 EXT_AUTZ 过滤器的行为,例如将哪些标头发送到外部授权器、将哪些标头发送到应用程序后端、在出错时返回的状态等。

      例如,下面定义了可以与 oauth2-proxy 一起使用的扩展提供程序:

      1. data:
      2. mesh: |-
      3. extensionProviders:
      4. - name: "oauth2-proxy"
      5. envoyExtAuthzHttp:
      6. service: "oauth2-proxy.foo.svc.cluster.local"
      7. port: "4180" # oauth2-proxy 使用的默认端口。
      8. includeRequestHeadersInCheck: ["authorization", "cookie"] # 在检查请求中发送到 oauth2-proxy 的头。
      9. headersToUpstreamOnAllow: ["authorization", "path", "x-auth-request-user", "x-auth-request-email", "x-auth-request-access-token"] # 请求被允许时发送到后端应用程序的头。
      10. headersToDownstreamOnDeny: ["content-type", "set-cookie"] # 请求被拒绝时发回客户端的头。

    启用外部授权

    1. 使用以下命令启用外部授权:

      以下命令将带有 CUSTOM 操作值的授权策略应用于 httpbin 工作负载。该策略支持使用 sample-ext-authz-grpc 定义的外部授权器对指向路径 /headers 的请求进行外部授权。

      在运行时,httpbin 工作负载的 /Headers 路径的请求会被 ext_authz 过滤器暂停,并向外部授权者发送检查请求,以决定是允许还是拒绝该请求。

    2. 验证 ext_authz 示例服务器拒绝了头部为 x-ext-authz:deny 的路径 /headers 的请求:

      1. $ kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl "http://httpbin.foo:8000/headers" -H "x-ext-authz: deny" -s
    3. 验证 ext_authz 示例服务器是否允许头部为 x-ext-authz:low 的路径 /headers 的请求:

      1. $ kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl "http://httpbin.foo:8000/headers" -H "x-ext-authz: allow" -s
      2. {
      3. "headers": {
      4. "Accept": "*/*",
      5. "Host": "httpbin:8000",
      6. "User-Agent": "curl/7.76.0-DEV",
      7. "X-B3-Parentspanid": "430f770aeb7ef215",
      8. "X-B3-Sampled": "0",
      9. "X-B3-Spanid": "60ff95c5acdf5288",
      10. "X-B3-Traceid": "fba72bb5765daf5a430f770aeb7ef215",
      11. "X-Envoy-Attempt-Count": "1",
      12. "X-Ext-Authz": "allow",
      13. "X-Ext-Authz-Check-Result": "allowed",
      14. "X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/foo/sa/httpbin;Hash=e5178ee79066bfbafb1d98044fcd0cf80db76be8714c7a4b630c7922df520bf2;Subject=\"\";URI=spiffe://cluster.local/ns/foo/sa/sleep"
      15. }
      16. }
    4. 确认允许 /ip 路径请求且不触发外部授权:

      1. $ kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl "http://httpbin.foo:8000/ip" -s -o /dev/null -w "%{http_code}\n"
      2. 200
    5. 查看 ext_authz 示例服务器的日志,确认它被调用了两次(针对这两次请求)。第一个被允许,第二个被拒绝:

      您还可以从日志中看出,ext-authz 过滤器和 ext-authz 示例服务器之间的连接启用了 mTLS,因为源主体填充了值 spirffe://cluster.local/ns/foo/sa/sleep

      现在,您可以对示例 ext-authz 服务器应用另一个授权策略,以控制允许谁访问它。

    1. 从配置中删除命名空间 foo:

    性能预期

    请参阅性能基准测试