1. 程式人生 > >Istio技術與實踐04:最佳實踐之教你寫一個完整的Mixer Adapter

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

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,一個介面卡可以支援多個模板。而Mixeryaml配置可以看成是三種模型的模板整合到一個檔案下,分別是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

執行完以後檢查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來檢視日誌瞭解自己的介面卡工作情況。