idou老師教你學Istio 16:如何用 Istio 實現微服務間的訪問控制
摘要
使用 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 介面卡實現較複雜的黑白名單。