DaoCloud 開源 Clusterpedia:支援 Kubernetes 多叢集資源檢索
本文介紹的是由 DaoCloud 開源的雲原生專案 Clusterpedia,全稱 The Encyclopedia of Kubernetes clusters,原始碼檢視地址:https://github.com/clusterpedia-io/clusterpedia。
在多叢集時代,我們可以通過 cluster-api 來批量建立管理叢集,使用 Karmada/Clusternet 來分發部署應用。不過我們貌似還是缺少了什麼功能,我們要如何去統一的檢視多個叢集中的資源呢?
對於單個叢集的資源,我們可以使用 kubectl 來檢視搜尋資源,但是在想要檢索多叢集的資源時,貌似沒有什麼趁手的產品可以使用。這個問題不會再困擾你,因為在 DaoCloud 雲原生開源專案 Clusterpedia 的加持下,你手上的 kubectl 已經可以用來檢索多叢集資源啦!
例如,使用 kubectl 來獲取多個叢集下 kube-system 名稱空間內的 deployments。
$ kubectl get deployments -n kube-system
CLUSTER NAME READY UP-TO-DATE AVAILABLE AGE
cluster-1 calico-kube-controllers 1/1 1 1 63d
cluster-1 coredns 2/2 2 2 63d
cluster-2 calico-kube-controllers 1/1 1 1 109d
cluster-2 coredns-coredns 2/2 2 2 109d
cluster-2 dce-chart-manager 1/1 1 1 109d
cluster-2 dce-clair 1/1 1 1 109d
01 Clusterpedia 介紹
Clusterpedia,名字借鑑自 Wikipedia,同樣也展現了 Clusterpedia 的核心理念 —— 多叢集的百科全書。
通過聚合多叢集資源,在相容 Kubernetes OpenAPI 的基礎上額外提供了更加強大的檢索功能,讓使用者更快更方便的在多叢集中獲取到想要的任何資源。
當然 Clusterpedia 的能力並不僅僅只是檢索檢視,未來還會支援對資源的簡單控制,就像 wiki 同樣支援編輯詞條一樣。
架構設計

Clusterpedia 在架構上分為四個部分:
• Clusterpedia APIServer:以 Aggregated API 的方式註冊到 Kube APIServer,通過統一的入口來提供服務。 • ClusterSynchro Manager:管理用於同步叢集資源的 Cluster Synchro。 • Storage Layer (儲存層):用來連線操作具體的儲存元件,然後通過儲存層介面註冊到 Clusterpedia APIServer 和 ClusterSynchro Manager 中。 • 儲存元件:具體的儲存設施,例如 mysql, postgres,redis 或者其他圖資料庫。
另外,Clusterpedia 會使用 PediaCluster 這個自定義資源來實現叢集認證和資源收集配置
Clusterpedia 還提供了可以接入 mysql 和 postgres 的預設儲存層。
Clusterpedia 並不關心使用者所使用的具體儲存設定是什麼,使用者可以根據自己的需求來選擇或者實現儲存層,然後將儲存層以外掛的形式註冊到 Clusterpedia 中來使用。
特性和功能
• 支援複雜的檢索條件,過濾條件,排序,分頁等等 • 支援查詢資源時請求附帶關係資源 • 統一主叢集和多叢集資源檢索入口 • 相容 kubernetes OpenAPI, 可以直接使用 kubectl 進行多叢集檢索,而無需第三方外掛或者工具 • 相容收集不同版本的叢集資源,不受主叢集版本約束, • 資源收集高效能,低記憶體 • 根據叢集當前的健康狀態,自動啟停資源收集 • 外掛化儲存層,使用者可以根據自己需求使用其他儲存元件來自定義儲存層 • 高可用
02 部署 Clusterpedia
關於部署的詳細流程,可以檢視 README,這裡著重介紹瞭如何使用 clusterpedia。 https://github.com/clusterpedia-io/clusterpedia#%E9%83%A8%E7%BD%B2 [1]
03 叢集資源收集
clusterpedia 部署完成後,我們可以通過 kubectl 來操作 PediaCluster 資源。
$ kubectl get pediaclusters
在 examples 目錄下,可以看到 PediaCluster 的示例
apiVersion: clusters.clusterpedia.io/v1alpha1
kind: PediaCluster
metadata:
name: cluster-example
spec:
apiserverURL: "https://172.30.43.41:6443"
caData: ""
tokenData: ""
certData: ""
keyData: ""
resources:
- group: apps
resources:
- deployments
- group: ""
resources:
- pods
PediaCluster 在配置上可以分成兩部分
• 叢集認證 • 指定資源收集 .spec.resources
叢集認證
caData , tokenData , certData , keyData 欄位用於叢集的驗證。
當前暫時不支援從 ConfigMap 或者 Secret 中獲取驗證相關的資訊,不過已經在 Roadmap 中了。
在設定驗證欄位時,注意要使用 base64 後的字串
在 examples 目錄下提供了生成用於訪問子叢集的 rbac yam clusterpedia_synchro_rbac.yaml ,來方便的獲取子叢集的許可權 token。
在子叢集中部署該 yaml,然後獲取對應的 token 和 ca 證書。
$ # 當前 kubectl 連線到子叢集中
$ kubectl apply -f examples/clusterpedia_synchro_rbac.yaml
clusterrole.rbac.authorization.k8s.io/clusterpedia-synchro created
serviceaccount/clusterpedia-synchro created
clusterrolebinding.rbac.authorization.k8s.io/clusterpedia-synchro created
$ SYNCHRO_TOKEN=$(kubectl get secret $(kubectl get serviceaccount clusterpedia-synchro -o jsonpath='{.secrets[0].name}') -o jsonpath='{.data.token}')
$ SYNCHRO_CA=$(kubectl get secret $(kubectl get serviceaccount clusterpedia-synchro -o jsonpath='{.secrets[0].name}') -o jsonpath='{.data.ca\.crt}')
複製 ./examples/pediacluster.yaml
並修改 .spec.apiserverURL
和 .metadata.name
欄位,並且將 $SYNCHRO_TOKEN
和 $SYNCHRO_CA
填寫到 tokenData 和 caData 中。
使用 kubectl apply 建立。
$ kubectl apply -f cluster-1.yaml
pediacluster.clusters.clusterpedia.io/cluster-1 created
為了方便後續使用,建議再建立一個 cluster-2
資源收集
可以通過設定 spec.resources 欄位的 group 和 group 下的 resources 來進行指定收集的資源。
在 status 中我們也可以看到資源的收集狀態。
status:
conditions:
- lastTransitionTime: "2021-12-02T04:00:45Z"
message: ""
reason: Healthy
status: "True"
type: Ready
resources:
- group: ""
resources:
- kind: Pod
namespaced: true
resource: pods
syncConditions:
- lastTransitionTime: "2021-12-02T04:00:45Z"
status: Syncing
storageVersion: v1
version: v1
- group: apps
resources:
- kind: Deployment
namespaced: true
resource: deployments
syncConditions:
- lastTransitionTime: "2021-12-02T04:00:45Z"
status: Syncing
storageVersion: v1
version: v1
version: v1.22.2
04 資源檢索
配置好我們需要收集的資源後,我們就可以進行重頭戲了 —— 叢集檢索
clusterpedia 支援兩種資源檢索:
• 相容 Kubernetes OpenAPI 的資源檢索 • 集合資源 (Collection Resource) 的檢索
$ kubectl api-resources | grep pedia.clusterpedia.io
collectionresources pedia.clusterpedia.io/v1alpha1 false CollectionResource
resources pedia.clusterpedia.io/v1alpha1 false Resources
為了方便我們更好的使用 kubectl 來進行檢索,我們可以先通過 make gen-clusterconfig 來為子叢集建立用於檢索的 ‘快捷方式’。
$ make gen-clusterconfigs
./hack/gen-clusterconfigs.sh
Current Context: kubernetes-[email protected]
Current Cluster: kubernetes
Server: https://10.9.11.11:6443
TLS Server Name:
Insecure Skip TLS Verify:
Certificate Authority:
Certificate Authority Data: *
Cluster "clusterpedia" set.
Cluster "cluster-1" set.
使用 kubectl config get-clusters 可以檢視當前支援的叢集。
其中 clusterpedia 是一個特殊的 cluster,用於多叢集檢索,以 kubectl –cluster clusterpedia 的方式來檢索多個叢集的資源。
多叢集資源檢索
我們先看一下我們都收集了哪些資源,只有被收集的資源才可以進行檢索。
$ kubectl --cluster clusterpedia api-resources
NAME SHORTNAMES APIVERSION NAMESPACED KIND
pods po v1 true Pod
deployments deploy apps/v1 true Deployment
可以看到當前收集並支援 pods 和 deployments.apps 兩種資源
檢視所有叢集的 kube-system 名稱空間下的 deployments
$ kubectl --cluster clusterpedia get deployments -n kube-system
CLUSTER NAME READY UP-TO-DATE AVAILABLE AGE
cluster-1 calico-kube-controllers 1/1 1 1 63d
cluster-1 coredns 2/2 2 2 63d
cluster-2 calico-kube-controllers 1/1 1 1 109d
cluster-2 coredns-coredns 2/2 2 2 109d
cluster-2 dce-chart-manager 1/1 1 1 109d
cluster-2 dce-clair 1/1 1 1 109d
檢視所有叢集的 kube-system、default 名稱空間下的 deployments
$ kubectl --cluster clusterpedia get deployments -A -l "search.clusterpedia.io/namespaces in (kube-system, default)"
檢視 cluster-1, cluster-2 兩個叢集下的 kube-system, default 名稱空間下中的 deployments
$ kubectl --cluster clusterpedia get deployments -A -l "search.clusterpedia.io/clusters in (cluster-1, cluster-2),\
search.clusterpedia.io/namespaces in (kube-system,default)"
NAMESPACE CLUSTER NAME READY UP-TO-DATE AVAILABLE AGE
kube-system cluster-1 calico-kube-controllers 1/1 1 1 63d
kube-system cluster-1 coredns 2/2 2 2 63d
default cluster-1 dao-2048-2048 1/1 1 1 20d
default cluster-1 hello-world-server 1/1 1 1 26d
default cluster-1 my-nginx 1/1 1 1 39d
default cluster-1 phpldapadmin 1/1 1 1 40d
kube-system cluster-2 calico-kube-controllers 1/1 1 1 109d
kube-system cluster-2 coredns-coredns 2/2 2 2 109d
kube-system cluster-2 dce-chart-manager 1/1 1 1 109d
kube-system cluster-2 dce-clair 1/1 1 1 109d
顯示資料有刪減,略過
檢視 cluster-1, cluster-2 兩個叢集下的 kube-system, default 名稱空間下中的 deployments,並根據資源的名字排序
$ kubectl --cluster clusterpedia get deployments -A -l "search.clusterpedia.io/clusters in (cluster-1, cluster-2),\
search.clusterpedia.io/namespaces in (kube-system,default),\
search.clusterpedia.io/orderby=name"
kube-system cluster-1 calico-kube-controllers 1/1 1 1 63d
kube-system cluster-2 calico-kube-controllers 1/1 1 1 109d
kube-system cluster-1 coredns 2/2 2 2 63d
kube-system cluster-2 coredns-coredns 2/2 2 2 109d
default cluster-1 dao-2048-2048 1/1 1 1 20d
kube-system cluster-2 dce-chart-manager 1/1 1 1 109d
kube-system cluster-2 dce-clair 1/1 1 1 109d
kube-system cluster-2 dce-registry 1/1 1 1 109d
kube-system cluster-2 dce-uds-storage-server 1/1 1 1 109d
default cluster-1 dd-airflow-scheduler 0/1 1 0 53d
default cluster-1 dd-airflow-web 0/1 1 0 53d
kube-system cluster-2 metrics-server 1/1 1 1 109d
default cluster-1 my-nginx 1/1 1 1 39d
default cluster-1 nginx-dev 1/1 1 1 14d
default cluster-1 openldap 1/1 1 1 40d
default cluster-1 phpldapadmin 1/1 1 1 40d
顯示資料有刪減,略過
指定叢集檢索
我們如果想要檢索指定叢集的資源的話,我們可以使用 –cluster 來指定具體的叢集名稱
$ kubectl --cluster cluster-1 get deployments -A
NAMESPACE CLUSTER NAME READY UP-TO-DATE AVAILABLE AGE
kubeapps-oidc cluster-1 apach2-apache 1/1 1 1 35d
kube-system cluster-1 calico-kube-controllers 1/1 1 1 63d
cert-manager cluster-1 cert-manager 1/1 1 1 42d
cert-manager cluster-1 cert-manager-cainjector 1/1 1 1 42d
cert-manager cluster-1 cert-manager-webhook 1/1 1 1 42d
kube-system cluster-1 coredns 2/2 2 2 63d
default cluster-1 dao-2048-2048 1/1 1 1 20d
kubernetes-dashboard cluster-1 dashboard-metrics-scraper 1/1 1 1 54d
default cluster-1 dd-airflow-scheduler 0/1 1 0 53d
default cluster-1 dd-airflow-web 0/1 1 0 53d
顯示資料有刪減,略過
除了 search.clusterpedia.io/clusters 外其餘的複雜查詢的支援和多叢集檢索相同。
如果我們要獲取一個資源的詳情,那麼也是需要指定叢集才可以。
$ kubectl --cluster cluster-1 -n kube-system get deployments coredns
CLUSTER NAME READY UP-TO-DATE AVAILABLE AGE
cluster-1 apach2-apache 1/1 1 1 35d
複雜檢索
clusterpedia 支援以下複雜檢索:
• 指定一個或者多個叢集名稱 • 指定一個或者多個名稱空間 • 指定一個或者多個資源名稱 • 指定多個欄位的排序 • 分頁功能,可以指定 size 和 offset • labels 過濾
對於欄位的排序,實際的效果是根據儲存層來決定的,預設儲存層支援根據 cluster , name , namespace , created_at , resource_version 進行正序或者倒序的排序。
檢索條件的傳遞方式
上面例項中,演示了使用 kubectl 來進行檢索,而這些複雜的檢索條件通過 label 來傳遞的。實際上 clusterpedia 還支援直接通過 url query 的傳遞這些檢索條件。

label key 的操作符支援 ==, =, !=, in, not in 對於 size 這個條件,實際上 kubectl 可以通過 –chunk-size 來指定,而不需要通過 label key。
集合資源 (Collection Resource)
在 clusterpedia 還有對資源更加高階的聚合,使用 Collection Resource 可以一次性獲取到一組不同型別的資源。
可以先檢視一下當前 clusterpedia 支援哪些 Collection Resource。
$ kubectl get collectionresources
NAME RESOURCES
workloads deployments.apps,daemonsets.apps,statefulsets.apps
通過獲取 workloads 便可獲取到一組 deployment, daemonset, statefulset 聚合在一起的資源 而且 Collection Resource 同樣支援所有的複雜查詢。
kubectl get collectionresources workloads 會預設獲取所有叢集下所有名稱空間的相應資源。
$ kubectl get collectionresources workloads
CLUSTER GROUP VERSION KIND NAMESPACE NAME AGE
cluster-1 apps v1 DaemonSet kube-system vsphere-cloud-controller-manager 63d
cluster-2 apps v1 Deployment kube-system calico-kube-controllers 109d
cluster-2 apps v1 Deployment kube-system coredns-coredns 109d
cluster-2 apps v1 Deployment dce-acm-agent dce-acm-agent 84d
在 cluster-1 中增加收集 Daemonset, 輸出有刪減,太多
由於 kubectl 的限制所以無法在 kubectl 來使用複雜查詢,只能通過 url query 的方式來查詢。
自定義 Collection Resource
Collection Resource 支援哪些資源是由儲存層來提供,而預設儲存層未來會支援自定義組合 Collection Resource。
05 對資源進行更復雜的操作
clusterpedia 不僅僅只是用來做資源檢索,和 wiki 一樣,它也應該具有對資源簡單的控制能力,例如 watch, create, delete, update 等操作。
對於寫操作,實際會採用雙寫 + 響應 warning 的方式來完成。
感興趣的話可以在 issue 中一起討論。
06 叢集的自動發現與收集
clusterpedia 中用來表示叢集的資源叫做 PediaCluster, 而不是簡單的 Cluster,最主要的原因便是 clusterpedia 設計初衷便是讓 clusterpedia 可以建立在已有的多叢集管理平臺之上。
為了遵循初衷,第一個問題便是不能和已有的多叢集平臺中的資源衝突, Cluster 便是一個最通用的代表叢集的資源名稱。
另外為了更好的去接入到已有的多叢集平臺上,讓已經接入的叢集可以自動的完成資源收集,我們需要另外的一個叢集發現機制。這個發現機制需要解決以下問題:
• 能夠獲取到訪問叢集的認證資訊 • 可以配置觸發 PediaCluster 生命週期的 Condition 條件 • 設定預設的資源收集策略,以及名稱字首等
這個功能會在 Q1 或者 Q2 中開始詳細討論實現。
07 當前進展
clusterpedia 當前處於比較早期的階段 (v0.0.9-alpha) ,核心功能剛剛完成,還有很多可以優化的地方,對於這些優化點也都提了對應的 issues,歡迎大家一起討論
這裡簡單說一些進入 v0.1.0 版本前的優化點:
• 從具有 Server-Side Apply 特性的叢集中收集到的資源會帶有很臃腫的 managedFields 欄位, clustersynchro manager 模組會增加相應 feature gate,來允許使用者在收集時裁減掉這個欄位 • 同樣的臃腫欄位 annotations 中的 kubectl.kubernetes.io/last-applied-configuration,也要允許裁剪這個欄位 • 在指定叢集獲取資源時,如果叢集處於異常狀態時,應該在響應中新增 warning 來提醒使用者 • 對 PediaCluster 的狀態資訊有更準確的更新 • 弱網環境下,資源收集的優化
更多的優化項,大家可以在 issue 中提出新的想法。
08 Roadmap
當前只是暫定的 Roadmap,具體的排期還要看社群的需求程度
2021 Q4
在 2021 的 Q4 階段會完成上述的優化項,並且完成對自定義資源的收集
• 詳細化資源收集狀態 • 自定義資源的收集
Q1
• 支援外掛化儲存層 • 實現叢集的自動發現和收集
Q2
• 支援對叢集資源更多的控制,例如 watch/create/update/delete 等操作 • 預設儲存層支援自定義 Collection Resource • 支援請求附帶關係資源
09 使用注意
多叢集網路連通性
clusterpedia 實際並不會解決多叢集環境下的網路連通問題,使用者可以使用 tower 等工具來連線訪問子叢集,也可以藉助 submariner 或者 skupper 來解決跨叢集網路問題。
引用連結
[1]
https://github.com/clusterpedia-io/clusterpedia#%E9%83%A8%E7%BD%B2: https://github.com/clusterpedia-io/clusterpedia# 部署
- Envoy 有狀態會話保持機制設計與實現
- CSI 驅動開發指南
- Istio網格中訪問外部服務方法
- 混沌工程和視覺隱喻的可觀測性
- 一鍵開啟 Kubernetes 可觀察性 —— 如何自動生成和儲存 OpenTelemetry 追蹤
- 網易數帆對 Istio 推送的效能優化經驗分享 | IstioCon 2022
- 【直播回看】MetaFlow:開源的高度自動化可觀測性平臺
- 利用eBPF技術帶來的可觀測性的上帝視角:Kindling開源專案介紹
- Slack 將數百萬個併發的 Websockets 遷移到 Envoy 上經驗分享
- 利用服務網格為基於微服務的應用程式實施 DevSecOps|電子書
- 利用服務網格和智慧應用感知網路增強應用彈性
- 機器學習全生命週期研究(三)
- 在 Istio 中引入 Wasm 意味著什麼?
- 網易開源 Envoy 企業級自定義擴充套件框架 Hango Rider 簡介
- 機器學習全生命週期研究(一)
- 如何在產品中引入 eBPF 以增加可觀察性
- SkyWalking 針對 gRPC 的負載均衡和自動擴容實踐
- DaoCloud 開源 Clusterpedia:支援 Kubernetes 多叢集資源檢索
- 零信任網路的微服務基本要素概述
- 雲端 IDE 是軟體工程的未來嗎?