乾式執行

此任務將說明如何使用新的實驗性註解 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 的請求是否被允許,因為該策略是以預執行模式建立的,請執行以下命令從 curlhttpbin 發送 20 個請求,該請求包含標頭 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,就是預期的)。這表示預執行策略應用於連接埠 80 上的 httpbin 工作負載,並比對到一個請求。如果該策略不是處於預執行模式,則會拒絕該請求一次。

  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。

這項資訊對您有幫助嗎?
您有任何改進建議嗎?

感謝您的意見反應!