1. 程式人生 > >Kubernetes服務目錄的設計_Kubernetes中文社群

Kubernetes服務目錄的設計_Kubernetes中文社群

【編者的話】OpenShift 3.6新版本包括新的服務目錄和服務中介技術預演版。它們是基於Kubernetes的孵化專案Kubernetes Service Catalog project。服務目錄通過Open Service Broker API整合服務中介,由服務中介管理服務的建立和管理;這篇文章將深入介紹服務目錄的設計。

服務目錄是基於Kubernetes的Open Service Broker API實現。 它包括如下功能:

  • 服務中介註冊到Kubernetes上;
  • 服務中介指定一組服務(或這些服務的變體),提供給Kubernetes使用者;
  • Kubernetes使用者可以發現可用的服務;
  • Kubernetes使用者可以請求新的服務例項;
  • Kubernetes使用者可以連結服務例項到一組Pods上;

這種底層機制允許在Kubernetes中執行的應用程式與它們使用的服務之間鬆耦合。 服務中介是一個黑盒實體,可以執行在Kubernetes外。 服務中介允許應用專注於自己的業務邏輯,將服務的管理交給服務中介。

術語

  • 應用(Application):服務目錄中的服務與Kubernetes中的“服務”是不同的。為避免混淆,我們使用“應用”表示Kubernetes的服務例項;
  • 繫結或服務繫結(Binding):服務例項和應用之間的連結。它表示應用引用和使用特定服務例項的意圖;
  • 中介或服務中介(Broker):一個實體,用於管理一組或多個服務,可以通過網路端點訪問服務中介;
  • 憑證(Credentials):應用與服務例項通訊所需的資訊;
  • 例項或服務例項(Instance):服務的實現稱為服務例項;
  • 服務類或服務(Service Class):服務中介提供的一種服務型別;
  • 計劃或服務計劃(Plan):服務型別的變體。例如,服務可以暴露一組計劃,它們提供不同程度的服務質量(QoS);

Open Service Broker API

本文件不會詳細介紹OSB API的工作原理,相關資訊請參閱:Open Service Broker API。 本文的其餘部分假設讀者熟悉OSB API規範的基本概念。

服務目錄設計

服務目錄的設計如下圖所示:

請注意,該專案的當前狀態並不完全支援設計中所述的所有內容,但我們從目標開始,然後指出當前專案狀態,通過[DIFF]標記不同。

作為服務目錄的核心,與Kubernetes核心一樣,它是一個API伺服器和一個控制器。 API伺服器是用於儲存元件HTTP(REST)RESTful的前端。系統的使用者及系統的其他元件與API伺服器進行互動,以便在服務目錄資源模型上執行CRUD型別的操作。與Kubernetes本身一樣,kubectl命令列工具可用於與服務目錄資源模型進行互動。

服務目錄API伺服器後面的儲存元件可以是etcd第三方資源(TPRs)。 rest.storage介面抽象正在使用的特定持久儲存裝置。當使用etcd時,etcd的例項將與Kubernetes的etcd例項不同,這意味著,服務目錄將具有與Kubernetes不同的持久儲存。當使用TPRs時,這些資源將被儲存在Kubernetes中,因此不需要單獨的持久儲存。

[DIFF]到目前為止,API伺服器只能使用etcd作為其持久儲存。在不久的將來,API伺服器的rest.storage介面將新增對TPRs的支援。

服務目錄資源模型在pkg/apis/servicecatalog/types.go的檔案中定義,模型的初始(當前)版本在pkg/apis/servicecatalog/v1alpha1/中。到目前為止,只有一個版本的模型,但隨著時間的推移,將會建立其他版本,每個版本都將有自己的pkg/apis/servicecatalog /的子目錄中。

控制器是服務目錄的大腦。它監視資源模型(通過API伺服器上watches介面),並根據其檢測到的更改採取適當的操作。

要了解服務目錄資源模型,最好通過一個典型的工作流程:

服務中介註冊

在應用使用服務之前,服務中介首先向Kubernetes平臺註冊。服務中介管理服務,我們首先通過建立Broker例項來註冊服務中介:

kubectl create -f broker.yaml 

broker.yaml內容如下:

apiVersion: servicecatalog.k8s.io/v1alpha1 
kind: Broker 
metadata:   
name: BestDataBase 
spec:   
url: http://bestdatabase.com 

建立中介資源後,服務目錄控制器將收到資料儲存區新增資源的事件。然後,控制器將查詢服務中介(指定的URL)以獲取可用服務列表。然後,每個服務都將建立一個相應的服務資源:

apiVersion: servicecatalog.k8s.io/v1alpha1 
kind: ServiceClass 
metadata:   
name: smallDB   
brokerName: BestDataBase   
plans... 

請注意,每個服務可以有一個或多個與之相關聯的計劃。

使用者可以查詢可用服務列表:

kubectl get services 

建立服務例項

在使用服務之前,必須建立一個新的例項。建立一個新的Instance資源:

kubectl create -f instance.yaml

instance.yaml內容如下:

apiVersion: servicecatalog.k8s.io/v1alpha1 
kind: Instance 
metadata:   
name: johnsDB 
spec:   
serviceClassName: smallDB 

在例項資源內可以指定使用的計劃。允許使用者指定他們想使用的服務的變體 – 可能是基於QoS的服務型別變體。

一旦Instance資源被建立,控制器會與指定的服務中介協商來建立一個所需服務的新的例項。

有兩種建立方式:同步和非同步

對於同步操作,向服務中介發出請求,並且在成功完成請求(200 OK)後,服務例項可以被應用使用。

一些服務中介支援非同步方式。當控制器向服務中介發出create/update/deprovision請求時,服務中介以202 ACCEPTED響應,並提供GET請求端點:GET /v2/service_instances/<service_instance_id>/last_operation,控制器可以輪詢請求狀態。

服務中介為每個last_operation請求傳送返回一個last_operation欄位。輪詢請求的狀態為“in_progress”時,控制器將繼續輪詢。控制器會考慮輪詢請求的最大超時,並將停止輪詢並將建立標記為失敗。

雖然服務例項正在進行非同步操作,但控制器必須確保沒有其他操作(提供,取消,更新,繫結,取消繫結)。

使用服務例項

在使用服務例項之前,必須將其繫結到應用程式。這意味著應用和服務例項之間的連結或使用意圖必須建立。建立一個新的Binding資源:

kubectl create -f binding.yaml 

binding.yaml內容如下所示:

apiVersion: servicecatalog.k8s.io/v1alpha1 
kind: Binding 
metadata:   
name: johnsBinding 
spec:   
secretName: johnSecret   
...Pod selector labels... 

控制器,接到新的Binding資源通知後,將與服務中介通訊,為指定的服務例項建立一個新的繫結。從服務中介返回的Binding物件中有一組憑據。這些憑據包含應用程式與服務例項通訊所需的所有資訊。例如,它可能包括以下內容:

  • 服務例項的URL
  • 使用者ID和密碼來訪問服務例項

OSB API規範不要求在憑據中顯示什麼屬性,因此需要應用瞭解返回的指定資料以及如何正確使用它們。這通常通過閱讀服務的文件來完成。

憑證不會儲存在服務目錄的資料儲存中。相反,它們將作為祕密儲存在Kubenetes中,並且將Secret的引用儲存在Binding資源中。如果未指定Binding的Spec.SecretName,則控制器將使用Binding Name屬性作為Secret的名稱。

繫結不需要與服務例項位於相同的Kubenetes名稱空間中。允許跨應用和名稱空間共享服務例項。

除了Secret之外,控制器還將在Kubernetes中建立一個Pod注入策略(PIP)資源。有關更多資訊,請參閱PIP提案,但簡而言之,PIP定義了在建立Pod時如何修改Pod的規範以包含其他卷和環境變數。特別地,服務目錄將使用PIPs來允許應用程式所有者指示Secret應該如何提供給其Pods。例如,他們可以定義一個PIP來指示Secret安裝到Pod中。或者Secret的名稱/值應該被暴露為環境變數。

PIP將使用標籤選擇器來指示哪些Pod將被修改。例如:

kind: PodInjectionPolicy 
apiVersion: extensions/v1alpha1 
metadata:   
name: allow-database   
namespace: myns 
spec:   
selector:     
matchLabels:      
  role: frontend   
env:     
- name: DB_PORT       
  value: 6379 

定義一個PIP,新增一個名為DB_PORT的環境變數,值為6379,所有具有Role標籤的Pods都具有此前端值。

最終,OSB API規範將希望有關於憑證的額外元資料,以指出哪些欄位被認為是“Secret”,哪些不是。當該支援可用時,期望將非Secret資訊放入ConfigMap而取代Secret。

一旦Secret提供給應用Pods中,那麼應用程式碼就可以使用該資訊與服務例項進行通訊。

刪除服務例項

與Kubernetes中的資源一樣,可以通過對資源執行HTTP DELETE來刪除服務目錄資源。 但是,請注意,有相關的繫結存在時,服務例項不能被刪除。 換句話說,在刪除服務例項之前,必須先刪除其所有繫結。 刪除具有繫結的例項將失敗併產生錯誤。

刪除繫結也將自動刪除與之相關聯的Secret或ConfigMaps。

當前設計

上述各節描述了服務目錄的當前設計。 但是,有些尚未到位,程式碼不一定與之對齊。 目前的設計實際上更像是這樣:

不同的方面:

  • API伺服器只能使用etcd作為其持久儲存。
  • API伺服器沒有連線到控制器,這意味著它並沒有被實際作為執行系統的一部分。 只是通過與API伺服器通訊完成資源的建立和儲存。
  • 可以使用Kubernetes的API伺服器建立服務目錄資源的TPRs版本是當前系統的工作方式。 然後,控制器將與Kubernetes中API伺服器進行通訊,並監視服務目錄資源的TPRs版本,採取一切適當的措施。

譯者介紹:範彬,從事微服務、Docker和Kubernetes容器技術等方面的工作。可以關注譯者的微信公眾號:範範米飯。