kubernetes federation-v2 架構分析、安裝部署與示例驗證
一、引言
Federation (叢集聯邦)是 k8s 社群中重要的多雲管理專案,實現了跨地區跨服務商管理多個 k8s 叢集的功能。
它主要提供瞭如下兩個模型:
- 跨叢集同步資源:Federation 能夠讓資源在多個叢集中同步。
- 跨叢集發現:Federation 能夠在所有叢集的後端自動配置 DNS 服務和負載均衡。
二、Federation v2 架構分析
直接引用一張官方架構圖:
Federation v2 採用 CRD 模式執行在 Kubernetes 叢集中,擴充套件了 k8s 的資源管理能力。
首先,它向原有 k8s 叢集註冊一系列 CRD 資源,這些 CRD 定義了聯邦系統所支援的 k8s 資源;
然後,它通過開啟一個 ControllerManager 來管理這些 CRD 資源,實現跨叢集資源排程。
CRD 資源和 ControllerManager 共同構成了 Federation v2 的 Control Plane
目前 Federation v2 主要定義了 4 種 CRD 資源:
Cluster Configuration:主要定義了子叢集註冊時的配置資訊。當用戶執行 kubefed2 join 命令將安裝好的叢集加入聯邦時,federation-controller-manager 會自動讀取新加入叢集的 context 資訊,生成 Cluster Configuration 資訊;
Type Configuration:主要定義了 Federation 可以處理哪些資源物件。每個 Type Configuration 包括三個子配置項:
- Template:定義了 Federation 要處理的資源物件,含有該物件的全部資訊;
- Placement:定義要將資源物件執行在哪些子叢集中,如不定義該物件,則資源不會執行在任一叢集;
- Override:針對不同叢集的特殊需求,會重寫覆蓋 Template 中的內容;
Schedule:主要定義應用在叢集中的排程分佈,該型別主要涉及 Deployment 與 Replicaset 兩種。使用者可以定義物件在每個叢集中分佈的最多、最少例項數,並且還能在叢集中做到應用例項數的均衡分佈。值得注意的是,如果排程結果跟使用者自定義的 Override 衝突時,該排程演算法享有優先權。例如使用者 Override 中定義為 5 個例項,實際排程結果只有 3 個,那麼自定義的Override 中 5 個例項將被改為 3 個。
MultiClusterDNS:該資源主要在做多叢集間的服務發現,其下主要包含 ServiceDNSRecord、IngressDNSRecord、DNSEndpoint 這幾個資源物件。
三、Federation v2 安裝部署
環境:ubuntu-18.04,已安裝 docker,golang
3.1 下載 Federation v2 及相關依賴
# git clone https://github.com/kubernetes-sigs/federation-v2.git
# cd federation-v2
# ./scripts/download-binaries.sh
# export PATH=$(pwd)/bin:${PATH}
3.2 安裝 kind,啟動多叢集
# go get sigs.k8s.io/kind
# export PATH=$GOPATH/bin:${PATH}
# ./scripts/create-clusters.sh
3.3 建立 federation 並納管兩個叢集
# export KUBECONFIG="/root/.kube/kind-config-1:/root/.kube/kind-config-2"
# kubectl config use-context cluster1
# ./scripts/deploy-federation-latest.sh cluster2
3.4 驗證
# kubectl get federatedcluster -n federation-system
顯示兩個叢集(cluster1、cluster2)證明 federation 安裝完成!
四、Federation v2 示例驗證
4.1 在 cluster1、cluster2 都建立一個名字為 test-namespace 的名稱空間
# kubectl apply -f example/sample1/federatednamespace-template.yaml \
-f example/sample1/federatednamespace-placement.yaml
其中 federatednamespace-template.yaml 定義了需要建立的 namespace 的名稱
apiVersion: v1
kind: Namespace
metadata:
name: test-namespace
federatednamespace-placement.yaml 定義了 namespace 物件需要被部署到的叢集
apiVersion: primitives.federation.k8s.io/v1alpha1
kind: FederatedNamespacePlacement
metadata:
name: test-namespace
namespace: test-namespace
spec:
clusterNames:
- cluster1
- cluster2
首先,在 cluster1 檢視是否建立了 test-namespace 物件
# kubectl config use-context cluster1
# kubectl get namespaces
然後,去 cluster2 檢視
# kubectl config use-context cluster2
# kubectl get namespaces
證明,我們通過 federation 建立的 namespace 已經按照 federatednamespace-placement.yaml 的要求,
在 cluster1 和 cluster 2 分別建立了 test-namespace
4.2 在 cluster1、cluster2 都建立相同的 Deployment,但指定不同的副本數
# kubectl apply -f example/sample1/federateddeployment-template.yaml \
-f example/sample1/federateddeployment-placement.yaml \
-f example/sample1/federateddeployment-override.yaml
其中, federateddeployment-template.yaml 定義了 nginx deployment,預設 3 副本
apiVersion: primitives.federation.k8s.io/v1alpha1
kind: FederatedDeployment
metadata:
name: test-deployment
namespace: test-namespace
spec:
template:
metadata:
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
federateddeployment-placement.yaml 定義了 deployment 的目標部署叢集
apiVersion: primitives.federation.k8s.io/v1alpha1
kind: FederatedDeploymentPlacement
metadata:
name: test-deployment
namespace: test-namespace
spec:
clusterNames:
- cluster2
- cluster1
federateddeployment-override.yaml 針對不同叢集,重寫了副本數量設定
apiVersion: primitives.federation.k8s.io/v1alpha1
kind: FederatedDeploymentOverride
metadata:
name: test-deployment
namespace: test-namespace
spec:
overrides:
- clusterName: cluster2
clusterOverrides:
- path: spec.replicas
value: 5
我們先去 cluster1 驗證下 deployment 的數量是否正確(預期為 3)
# kubectl config use-context cluster1
# kubectl get deployment -n test-namespace
再去 cluster2 驗證(預期為 5)
# kubectl config use-context cluster2
# kubectl get deployment -n test-namespace
可見,deployment 的部署按照預期在 cluster1 和 cluster2 正確部署了!