摘要
使用 Istio 可以很方便地實現微服務間的訪問控制。本文演示了使用 Denier 適配器實現拒絕訪問,和 Listchecker 適配器實現黑白名單兩種方法。
使用場景
有時需要對微服務間的相互訪問進行控制,比如使滿足某些條件(比如版本)的微服務能夠(或不能)調用特定的微服務。
訪問控制屬於策略範疇,在 Istio 中由 Mixer 組件實現。
Mixer拓撲圖,來源官方文檔
如上圖所示,服務的外部請求會被 Envoy 攔截,每個經過 Envoy 的請求都會調用 Mixer,爲 Mixer 提供一組描述請求和請求周圍環境的屬性。Mixer 進行前置條件檢查和配額檢查,調用相應的 adapter 做處理,並返回相應結果。Envoy分析結果,決定是否執行請求或拒絕請求。從而實現了策略控制。
環境準備
在 Kubernetes 集羣上部署 Istio
部署 Bookinfo 示例應用
配置 Bookinfo 應用各個微服務的 destinationrule 和 virtualservice。其中 reviews 服務的 destinationrule 和 virtualservice 配置如下:
按上圖配置後,對於 reviews 服務的請求,來自用戶 “kokokobe” 的請求會被路由到v2 版本,其他用戶的請求會被路由到 v3 版本。
使用 Denier 適配器實現簡單的訪問控制
使用 Istio 對微服務進行訪問控制時,可以使用 Mixer 中的任何屬性。這是一種簡單的訪問控制,實現基礎是通過 Mixer 選擇器拒絕某些條件下的請求。
比如,上文所述的 Bookinfo 應用中的 ratings 服務會被多個版本的 reviews 服務訪問。下面的示例中我們將會切斷來自 v3 版本的 reviews 服務對 ratings 服務的調用。
- 用瀏覽器打開 Bookinfo 的 productpage(http://$GATEWAY_URL/productpage)
如上圖所示,如果用 “kokokobe” 的用戶登錄,能看到每條 review 下面的黑色星星,說明此時 ratings 服務被 v2 版本的 reviews 服務調用。
從上面兩張圖可以看出,如果使用其他用戶登錄(或未登錄),能看到每條 review 下面的紅色星星,說明此時 ratings 服務被 v3 版本的 reviews 服務調用。
- 創建 denier 適配器,拒絕來自 v3 版本的 reviews 服務對 ratings 服務的調用
編輯 mixer-rule-deny-label.yaml 內容如下:
這也是Mixer的adapter的標準配置格式,一般需要配置三種類型的資源:
-
配置一組 handler。Handler是配置好的 adapter 的實例,adapter 封裝了 Mixer 和特定基礎設施後端之間的接口。
-
基於 template 配置一組 instance。Instance 定義瞭如何將 Envoy 提供的請求屬性映射到 adapter 的輸入。
- 配置一組規則。這些規則描述了何時調用特定的 handler 及 instance。
在這裏其中定義了一條名爲 denyreviewsv3 的規則,一個 denier 類型的 handler,一個checknothing 類型的模板的實例。
在 denyreviewsv3 規則中,方框內的條件表達式匹配的條件是:來自 reviews 服務,version 爲 v3 ,目標爲 ratings 服務的請求。這條規則使用 denier 適配器拒絕來自 v3 版本的 reviews 服務的請求。
這個 denier 適配器會拒絕符合上述規則的請求。可以預先指定 denier 適配器的狀態碼和消息,如方框中所示。
然後執行如下命令創建上述規則的 denier 適配器:
- 在瀏覽器中刷新 productpage 頁面
如果已經登出或者使用不是 “kokokobe” 的用戶身份登錄,不再看到紅色星星,因爲v3版本的 reviews 服務對 ratings 服務的訪問已經被拒絕了。
相反,如果使用 “kokokobe” 用戶登錄,仍然能夠看到黑色星星。因爲該用戶使用的是 v2 版本的 reviews 服務,不符合拒絕的條件。
通過listchecker適配器實現黑白名單
Istio 也支持基於屬性的黑名單和白名單。下面的白名單配置和上一節的 denier 配置是等價的,拒絕來自 v3 版本的 reviews 服務的請求。
- 刪除上一節配置的 denier 規則
- 在登出狀態下瀏覽 Bookinfo 的 productpage(http://$GATEWAY_URL/productpage)
此時能看到紅星圖標。在完成下述步驟之後,只有在使用 “kokokobe” 的身份登錄之後才能看到星形圖標。
- 創建包含 v2 版本白名單的 listchecker 適配器
編輯 whitelist-handler.yaml 內容如下:
通常會在外部維護黑白名單的列表,然後指定 providerUrl 參數進行異步獲取。在這個例子中,我們使用 overrides 字段提供一個靜態的黑白名單列表。
然後運行如下命令創建 listchecker 適配器:
- 創建一個 listentry 模板的實例
Listentry 模板可以用來判別一個字符串是否存在於一個列表中,本例中我們使用它來判別版本標籤是否存在於白名單中。
編輯 appversion-instance.yaml 內容如下:
然後運行如下命令:
- 爲 ratings 服務啓用 whitelist 檢查功能
編輯 checkversion-rule.yaml 內容如下:
然後運行如下命令:
- 在瀏覽器中刷新 productpage 頁面
如果已經登出或者使用不是 “kokokobe” 的用戶身份登錄,看不到星形圖標;如果使用 “kokokobe” 用戶登錄,仍然能夠看到黑色星星。
總結
通過上述示例,可以發現使用 Istio 實現微服務間的訪問控制非常方便。既可以使用denier 適配器實現簡單的訪問控制,也可以通過listchecker 適配器實現較複雜的黑白名單。
相關服務請訪問https://support.huaweicloud.com/cce/index.html?cce_helpcenter_2019