演练运行

此任务演示如何使用新的 实验性注释 istio.io/dry-run 设置 Istio 授权策略,以在不实际执行策略的情况下对其进行演练运行。

演练运行注释允许您在将授权策略应用于生产流量之前更好地了解其影响。这有助于降低由错误的授权策略导致的生产流量中断的风险。

开始之前

在开始此任务之前,请执行以下操作

  • 阅读 Istio 授权概念

  • 按照 Istio 安装指南 安装 Istio。

  • 部署 Zipkin 以检查演练运行跟踪结果。按照 Zipkin 任务 在集群中安装 Zipkin。

  • 部署 Prometheus 以检查演练运行指标结果。按照 Prometheus 任务 在集群中安装 Prometheus。

  • 部署测试工作负载

    此任务使用两个工作负载 httpbincurl,两者都部署在命名空间 foo 中。这两个工作负载都运行带有 Envoy 代理 sidecar。使用以下命令创建 foo 命名空间并部署工作负载

    ZipZip
    $ kubectl create ns foo
    $ kubectl label ns foo istio-injection=enabled
    $ kubectl apply -f @samples/httpbin/httpbin.yaml@ -n foo
    $ kubectl apply -f @samples/curl/curl.yaml@ -n foo
    
  • 启用代理调试级别日志以检查干运行日志记录结果

    $ istioctl proxy-config log deploy/httpbin.foo --level "rbac:debug" | grep rbac
    rbac: debug
    
  • 使用以下命令验证 curl 是否可以访问 httpbin

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

创建演练运行策略

  1. 使用以下命令创建带有干运行注释 "istio.io/dry-run": "true" 的授权策略

    $ kubectl apply -n foo -f - <<EOF
    apiVersion: security.istio.io/v1
    kind: AuthorizationPolicy
    metadata:
      name: deny-path-headers
      annotations:
        "istio.io/dry-run": "true"
    spec:
      selector:
        matchLabels:
          app: httpbin
      action: DENY
      rules:
      - to:
        - operation:
            paths: ["/headers"]
    EOF
    

    您还可以使用以下命令快速将现有的授权策略更改为干运行模式

    $ kubectl annotate --overwrite authorizationpolicies deny-path-headers -n foo istio.io/dry-run='true'
    
  2. 验证对路径 /headers 的请求是否允许,因为策略是在干运行模式下创建的,运行以下命令从 curl 发送 20 个请求到 httpbin,请求包含标头 X-B3-Sampled: 1 以始终触发 Zipkin 追踪

    $ for i in {1..20}; do kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" -c curl -n foo -- curl http://httpbin.foo:8000/headers -H "X-B3-Sampled: 1" -s -o /dev/null -w "%{http_code}\n"; done
    200
    200
    200
    ...
    

在代理日志中检查演练运行结果

干运行结果可以在代理调试日志中找到,格式为 shadow denied, matched policy ns[foo]-policy[deny-path-headers]-rule[0]。运行以下命令检查日志

$ kubectl logs "$(kubectl -n foo -l app=httpbin get pods -o jsonpath={.items..metadata.name})" -c istio-proxy -n foo | grep "shadow denied"
2021-11-19T20:20:48.733099Z debug envoy rbac shadow denied, matched policy ns[foo]-policy[deny-path-headers]-rule[0]
2021-11-19T20:21:45.502199Z debug envoy rbac shadow denied, matched policy ns[foo]-policy[deny-path-headers]-rule[0]
2021-11-19T20:22:33.065348Z debug envoy rbac shadow denied, matched policy ns[foo]-policy[deny-path-headers]-rule[0]
...

另请参阅 故障排除指南 以获取有关日志记录的更多详细信息。

使用 Prometheus 检查指标中的演练运行结果

  1. 使用以下命令打开 Prometheus 仪表板

    $ istioctl dashboard prometheus
    
  2. 在 Prometheus 仪表板中,搜索以下指标

    envoy_http_inbound_0_0_0_0_80_rbac{authz_dry_run_action="deny",authz_dry_run_result="denied"}
    
  3. 验证查询到的指标结果如下

    envoy_http_inbound_0_0_0_0_80_rbac{app="httpbin",authz_dry_run_action="deny",authz_dry_run_result="denied",instance="10.44.1.11:15020",istio_io_rev="default",job="kubernetes-pods",kubernetes_namespace="foo",kubernetes_pod_name="httpbin-74fb669cc6-95qm8",pod_template_hash="74fb669cc6",security_istio_io_tlsMode="istio",service_istio_io_canonical_name="httpbin",service_istio_io_canonical_revision="v1",version="v1"}  20
    
  4. 查询到的指标值为 20(您可能会根据发送的请求数量找到不同的值。只要值大于 0,这都是预期的)。这意味着应用于端口 80httpbin 工作负载的干运行策略匹配了一个请求。如果策略不是处于干运行模式,则会拒绝该请求。

  5. 以下是 Prometheus 仪表板的屏幕截图

    Prometheus dashboard
    Prometheus 仪表板

使用 Zipkin 检查跟踪中的演练运行结果

  1. 使用以下命令打开 Zipkin 仪表板

    $ istioctl dashboard zipkin
    
  2. 查找从 curlhttpbin 的请求的跟踪结果。如果由于 Zipkin 中的延迟而没有看到跟踪结果,请尝试发送更多请求。

  3. 在跟踪结果中,您应该找到以下自定义标签,指示请求被命名空间 foo 中的干运行策略 deny-path-headers 拒绝

    istio.authorization.dry_run.deny_policy.name: ns[foo]-policy[deny-path-headers]-rule[0]
    istio.authorization.dry_run.deny_policy.result: denied
    
  4. 以下是 Zipkin 仪表板的屏幕截图

    Zipkin dashboard
    Zipkin 仪表板

总结

代理调试日志、Prometheus 指标和 Zipkin 跟踪结果表明干运行策略将拒绝请求。如果干运行结果不符合预期,您可以进一步更改策略。

建议保留干运行策略一段时间,以便可以使用更多生产流量对其进行测试。

当您对干运行结果有信心时,您可以禁用干运行模式,以便策略开始实际拒绝请求。这可以通过以下任一方法实现

  • 完全删除干运行注释;或

  • 将干运行注释的值更改为 false

限制

干运行注释目前处于实验阶段,存在以下限制

  • 干运行注释目前仅支持 ALLOW 和 DENY 策略;

  • 由于 ALLOW 和 DENY 策略在代理中分别执行,因此 ALLOW 和 DENY 策略将有两个单独的干运行结果(即日志、指标和跟踪标签)。您应该考虑所有两个干运行结果,因为请求可能会被 ALLOW 策略允许,但仍会被另一个 DENY 策略拒绝;

  • 代理日志、指标和跟踪中的干运行结果用于手动故障排除,不应作为 API 使用,因为它可能会随时更改,恕不另行通知。

清理

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

    $ kubectl delete namespace foo
    
  2. 如果不再需要,请删除 Prometheus 和 Zipkin。

此信息是否有用?
您是否有任何改进建议?

感谢您的反馈!