Istio 的功能與作用在之前的文章中已經向大家展示了,基於 Istio 的微服務治理也必將登上廣大雲服務供應商的舞臺。本文中,我們將會為您重點介紹一下 Istio 的核心元件 Mixer 與 adapter 介面卡的關係,並且從程式碼層面向您展示如何去開發配置 Mixer 中的 adapter 介面卡。在文章最後還將介紹Mixer是怎樣整合部署到當今主流的 K8S 環境中工作。
Istio 內建的部分介面卡以及相應功能舉例如下:
- circonus:微服務監控分析平臺。
- cloudwatch:針對AWS雲資源監控的工具。
- fluentd:開源的日誌採集工具。
- prometheus:開源的時序資料庫,非常適合用來儲存監控指標資料。
- statsd:採集彙總應用指標的工具。
- stdio:使Istio能將日誌和 metrics 輸出到本地,結合內建的ES、Grafana就可以檢視相應的日誌或指標了。
現在我們將**逐步向您介紹如何在 Mixer 中開發、測試和整合一個簡單的介面卡。該介面卡可以支援 Mixer 附帶的 metric 模板,**並且對於每一個請求,在請求時將從 Mixer 接收的資料列印到檔案中去。
完成本次例項的開發部署與編譯執行總共只需要幾步,大約需時30分鐘。所以通過本例項,您只需要短短半個小時就可以掌握一個 adpater 介面卡的開發執行過程,是不是很 easy?那我們現在就開始吧!
因篇幅有限,只擷取關鍵程式碼(後續程式碼模組皆為關鍵程式碼)如下所示,它定義了介面卡Builder和Handler型別以及處理metric的業務邏輯介面。雖然還沒有實現業務處理,但我們不妨通過下圖先了解一下adapter的程式碼結構。
var _ metric.HandlerBuilder = &builder{}
var _ metric.Handler = &handler{}
func (b *builder) Build(ctx context.Context, env adapter.Env) (adapter.Handler, error) {
return &handler{}, nil
}
func (h *handler) HandleMetric(ctx context.Context, insts []*metric.Instance) error {
return nil
}
複製程式碼
但是二者必不可少。Builder 的功能類似於構造器,可以通過載入相關引數(比如從配置檔案中直接讀取)生成一個 Handler,而 Handler 是配置好的 Adapter 的例項。後者可以參與處理metric業務。
如上所示現在我們有了一個介面卡的基本框架,其中包含 HandleMetric 介面的空實現。HandlerMetric 是介面卡中處理業務邏輯的實現方法也是核心方法,在該方法中我們可以將收集到的 metric進行資料處理然後上報出去,後臺的程式接收到這些處理後的 metric 資料就可以進行相應資料監控和分析了。在後面的步驟中將新增此介面卡的核心程式碼。
介面卡配置
介面卡要發揮特定的作用,必須要對其做相應的配置處理。由於在本次實踐中我們只是將通過將從 Mixer 接收的資料列印到檔案中來演示一下 adapter 的功能。因此介面卡需要將檔案的路徑作為配置欄位,在 config 目錄下建立配置 proto 檔案。
config.proto 檔案是一個專門用來配置介面卡引數的檔案,在該檔案中我們可以設定testAdapter.go
中需要用到的所有配置資訊比如快取大小、發生計時器大小等,但是一定要注意 proto 中每行程式碼都需要註釋,後面的 yaml 檔案也可以從該檔案中讀取引數。編寫完成後,用go generate ./ …
指令可以進行編譯並生成相應go檔案。現在讓我們將 config.proto 檔案生成相應的 go 檔案。然後我們可以輸入如下指令來編譯除錯 proto 檔案。
go generate ./...
go build ./...
複製程式碼
配置完 proto 檔案,我們們還需要配置 yaml 檔案。不同的 adapter 具有不同的 attributes,yaml 用模板的形式定義了 attributes 到 adapter 輸入資料對映的 schema,一個介面卡可以支援多個模板。而 Mixer 的 yaml 配置可以看成是三種模型的模板整合到一個檔案下,分別是 Handler、Instance 和 Rule。
這三種模型分別具有什麼樣的功能呢?
Handler 是配置好的 Adpater 的例項,它從 yaml 配置檔案中取出 adapter 需要的配置資料。
Instance 定義了 attributes 到 adapter 輸入的對映。
Rule 定義了一個特定的 Instance 何時呼叫一個特定的 Handler。
三種模型通過 yaml 中的 kind 進行區分。要讓介面卡工作起來,我們必然需要配置 yaml 來將 attributes 對映到 adapter 裡面。所以,讓我們給 Mixer 編寫一個簡單的 yaml 配置,以便將資料傳送到您的介面卡。我們需要將例項,處理程式和規則配置傳遞給 Mixer 伺服器。當然我們本次實踐主要是為了進行一個 adapter 端到端的演示,所以一個完整的輸出到檔案中的 metric 應該還需要指定它的輸出路徑。
通過配置檔案在對應的檔案中列印例項和關聯的型別資訊,這需要在配置時儲存metric標準型別資訊並在請求時使用它。要新增此功能,需要在檔案testAdapter.go中加入相應業務邏輯處理的程式碼。如下所示:
func (h *handler) HandleMetric(ctx context.Context, insts []*metric.Instance) error {
for _, inst := range insts {
if _, ok := h.metricTypes[inst.Name]; !ok {
h.env.Logger().Errorf("Cannot find type %s",inst.Name)
continue
}
h.f.WriteString(fmt.Sprintf(`HandleMetric invoke for :
Instance Name :`%s`
Instance Value : %v,
Type : %v`, inst.Name, *inst, *h.metricTypes[inst.Name]))
}
return nil
}
複製程式碼
然後編譯就可以了,這樣就完成了介面卡程式碼的實現部分。那麼介面卡是如何在 Mixer 中進行工作以及我們如何驗證所編寫的程式碼做了哪些事呢?下面的步驟將告訴你答案。
將介面卡插入 Mixer 中
介面卡開發完以後,我們還需要將介面卡插入進 Mixer 中,首先要更新inventory.yaml
檔案並且將新的介面卡新增到 Mixer 的介面卡註冊列表中。通過 go generate 命令在/adapter
目錄中執行來重新生成庫存程式碼。到這裡您的介面卡已經插入到 Mixer 中並已經準備好接收資料。
本地驗證介面卡
以上工作做完以後,我們就可以在本地進行端到端的驗證了。啟動 Mixer 終端將會輸出相應資訊,並處於等待服務請求狀態。
現在讓我們使用 Mixer 客戶端呼叫 report 請求。在這裡我們需要 Mixer 伺服器使用 yaml 構造的例項物件呼叫樣例 adapter。並啟動一個新的終端視窗。在新視窗中呼叫命令:
tail $ ISTIO /istio/cloud.txttail $ ISTIO /istio/cloud.txt
如何將Mixer整合到K8S環境中執行除錯
在上面我們僅向大家演示瞭如何在本地測試自己開發的 adapter。我想大家對於 Istio 充滿熱情的很大原因都是因為其可以部署整合到 Kubernates(K8S)環境中執行。那麼今天正好可以向您介紹如何將 Mixer 打包成映象在 K8S 叢集節點上執行除錯。
在這裡我們需要再回顧一下 yaml 檔案,yaml 檔案可以完美的將我們需要上報的引數傳遞給 k8s,在這裡我們以一個流量監控的案例來簡單描述一下 adapter 怎樣與 K8S 協作執行。如下圖所示:
首先定義一個用來計數的 metric,它會根據我們定義的引數去採集相應資料,例如名稱空間等,這些都將會傳遞到 K8S 中,還會將自己的 value 屬性傳遞進 HandlerMetric 業務邏輯中,在 HandlerMetric 中我們就可以通過它的屬性“1”來進行一個請求計數,從而實現流量監控的功能。
定義完了metric,我們還需要定義一個Handler來處理這個metric,如下所示:
在這個 handler 中我們將去處理 COUTER 型別的 metric 並獲取其上報上來的引數,然後上報到指定的 ip 地址(自己根據需要設定)、叢集等等。最後我們還需要在 yaml 中定義一個規則去排程使用你的 handler,如下所示:
通過以上我們可以很清晰的看到。Mixer 與 K8S 直接是通過上述 yaml 檔案定義的引數來實現無縫銜接的整合部署。定義完 yaml,我們還需要將其部署到 heml 資料夾下,如下圖所示的目錄中:
並且將上述 yaml 中的內容配置到該資料夾下的 config.yaml
中,這樣當在介面上安裝 Istio 控制面的時候,介面卡上報過來的環境變數就會自動注入 K8S 的環境中。進而可以實現 Mixer 在 K8S 環境中的整合部署。接下來我們就可以將 Mixer 下的檔案編譯成二進位制檔案,然後製作成映象,將映象輸出為 tar 包。通過遠端登入命令 ssh 到自己的叢集節點上,然後將映象拷貝到環境上。到這裡,如果你在 pod 列表中看到我們剛剛自己建立的映象名,那麼就表示我們的介面卡已經成功部署到 K8S 環境中了。然後可以通過 kubectl 來檢視日誌瞭解自己的介面卡工作情況。