Istio技術與實踐04:最佳實踐之教你寫一個完整的Mixer Adapter

華為雲發表於2018-09-06

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 協作執行。如下圖所示:

Istio技術與實踐04:最佳實踐之教你寫一個完整的Mixer Adapter

首先定義一個用來計數的 metric,它會根據我們定義的引數去採集相應資料,例如名稱空間等,這些都將會傳遞到 K8S 中,還會將自己的 value 屬性傳遞進 HandlerMetric 業務邏輯中,在 HandlerMetric 中我們就可以通過它的屬性“1”來進行一個請求計數,從而實現流量監控的功能。

定義完了metric,我們還需要定義一個Handler來處理這個metric,如下所示:

Istio技術與實踐04:最佳實踐之教你寫一個完整的Mixer Adapter

在這個 handler 中我們將去處理 COUTER 型別的 metric 並獲取其上報上來的引數,然後上報到指定的 ip 地址(自己根據需要設定)、叢集等等。最後我們還需要在 yaml 中定義一個規則去排程使用你的 handler,如下所示:

Istio技術與實踐04:最佳實踐之教你寫一個完整的Mixer Adapter

通過以上我們可以很清晰的看到。Mixer 與 K8S 直接是通過上述 yaml 檔案定義的引數來實現無縫銜接的整合部署。定義完 yaml,我們還需要將其部署到 heml 資料夾下,如下圖所示的目錄中:

Istio技術與實踐04:最佳實踐之教你寫一個完整的Mixer Adapter

並且將上述 yaml 中的內容配置到該資料夾下的 config.yaml 中,這樣當在介面上安裝 Istio 控制面的時候,介面卡上報過來的環境變數就會自動注入 K8S 的環境中。進而可以實現 Mixer 在 K8S 環境中的整合部署。接下來我們就可以將 Mixer 下的檔案編譯成二進位制檔案,然後製作成映象,將映象輸出為 tar 包。通過遠端登入命令 ssh 到自己的叢集節點上,然後將映象拷貝到環境上。到這裡,如果你在 pod 列表中看到我們剛剛自己建立的映象名,那麼就表示我們的介面卡已經成功部署到 K8S 環境中了。然後可以通過 kubectl 來檢視日誌瞭解自己的介面卡工作情況。

相關文章