kubernetes federation 工作機制之資源物件同步
1 前言
希望通過本文最簡單的方式向熟悉k8s的人說明白其上的federation是幹什麼的,如何工作的。
關於federation,比較官方的說法是:叢集聯邦可以讓租戶/企業根據需要擴充套件或伸縮所需要的叢集;可以讓租戶/企業在跨地區甚至跨地域的多個叢集上部署、排程、監測管理應用。通過叢集聯邦,租戶/企業可以在指定叢集上部署應用,可以拉通私有云和公有云建立混合雲(hybrid cloud)。
如在design-proposal 中描述的federation提供了cross-cluster scheduling, cross-cluster service discovery, cross-cluster migration, cross-cluster**ing and auditing, cross-cluster load balancing。
簡單講就一句話。能呼叫一個api,向操作一個k8s叢集一樣操作多個k8s叢集。主要是拉通其下的k8s叢集在上部署應用,釋出服務,並且可以讓其互相訪問。
那麼是怎麼做到的呢?熟悉了kubernetes程式碼和主要的工作邏輯會發現非常簡單。簡單看下這部分程式碼會就會發現federation有如下特點:
- 複用了kubernets的機制
- 複用kubernetes的程式碼
- 擴充套件了kubernetes的物件(的定義和功能)
2. 架構
Federation 層的主要元件包括Federation-API Server,Controller-Manager和ETCD。根據Decoupled 的設計的目標和kubernetes 共用類庫,而不是共用一個緊密的結構結構。在結構上解耦可以保證,Federation層故障,其下的每個個kubernetes叢集不受影響。另外FederationAPI介面和kube-api介面完全相容,使用者可以像之前操作單個kubernetes叢集一樣操作聯邦。
和Kubernetes類似,使用者通過kubectl或者API呼叫向FederationAPI server的介面建立和維護各種物件,資料物件被持久化儲存在Federation的ETCD中。聯邦只是維護了規劃,真正幹活還是在其下的各個Cluster上(現實生活中其實也總是這樣,你見過在聯邦的川普幹過什麼正經事情)。真正關鍵的聯邦如何通過一個統一的入口來接收請求,在各個cluster上排程。具體到(程式碼)功能就是聯邦中指令如何在cluster上被落實執行。
聯邦和其下k8s 叢集的呼叫關係。呼叫細節下面描述。
3. 主要流程
關鍵就在於Federation的元件Controller-manager。和K8s其他的controller作用和工作機制類似,通過watch api-server 執行動作來維護叢集狀態。Federation的Controller-manager的處理邏輯和kubernetes略有不同,在於它一般都要連兩個API server,watch 3個API 物件
對於每種Resource物件,都對應一個Controller,在Federation的Controller-manager啟動時,啟動這些Controller。
以ConfigMap為例,ConfigMapController啟動後會watch如下三類介面:
- Federation API server的Cluster介面federation/v1beta1/cluster;
- Federation API server的ConfigMap介面v1/configmap;
- Federation 管理的 N 個kubernetes cluster的Kube-API server 的ConfigMap的介面:v1/ configmap
當ConfigMapController watch到有戶通過Federation API 建立(或者更新刪除)一個ConfigMap,則會呼叫對應的每個cluster 的kube-apiserver建立(或者更新刪除)對應的ConfigMap。
當ConfigMapController Watch到有新的Cluster加入進來時,呼叫新的Cluster的kube-api介面建立ConfigMap。Configmap、Secret等物件都是依照以上邏輯,從上向下Sync。
以ConfigMap 的controller為例,其他的都是遵從同一個模板流程。在NewConfigMapController場景controller時對watch 3個api。
Federation API server的ConfigMap介面v1/configmap;
12345678910 | configmapcontroller.configmapInformerStore,configmapcontroller.configmapInformerController=cache.NewInformer(&cache.ListWatch{ListFunc:func(options api.ListOptions)(pkg_runtime.Object,error){versionedOptions:=util.VersionizeV1ListOptions(options)returnclient.Core().ConfigMaps(api_v1.NamespaceAll).List(versionedOptions)},WatchFunc:func(options api.ListOptions)(watch.Interface,error){versionedOptions:=util.VersionizeV1ListOptions(options)returnclient.Core().ConfigMaps(api_v1.NamespaceAll).Watch(versionedOptions)}, |
Federation 管理的 N 個kubernetes cluster的Kube-API server 的ConfigMap的介面:v1/ configmap
12345678 | // Federated informer on configmaps in members of federation.&cache.ListWatch{ListFunc:func(options api.ListOptions)(pkg_runtime.Object,error){versionedOptions:=util.VersionizeV1ListOptions(options)returntargetClient.Core().ConfigMaps(api_v1.NamespaceAll).List(versionedOptions)},WatchFunc:func(options api.ListOptions)(watch.Interface,error){versionedOptions:=util.VersionizeV1ListOptions(options)returntargetClient.Core().ConfigMaps(api_v1.NamespaceAll).Watch(versionedOptions)}, |
Federation API server的Cluster介面:federation/v1beta1/cluster;
123456789 | &cache.ListWatch{ListFunc:func(options api.ListOptions)(pkg_runtime.Object,error){versionedOptions:=VersionizeV1ListOptions(options)returnfederationClient.Federation().Clusters().List(versionedOptions)},WatchFunc:func |