Kubernetes Federation(聯邦) 是實現跨地區與跨服務商多個 Kubernetes 叢集的管理機制。Kubernetes Federation 的架構很是類似純 Kubenretes 叢集,Federation 會擁有本身的 API Server 與 Controller Manager 來提供一個標準的 Kubernetes API,以及管理聯邦叢集,並利用 Etcd 來儲存全部狀態,不過差異在於 Kubenretes 只管理多個節點,而 Federation 是管理全部被註冊的 Kubernetes 叢集。linux
Federation 使管理多個叢集更為簡單,這主要是透過兩個模型來實現:nginx
Federation 有如下幾個好處:git
雖然 Federation 能夠下降管理多叢集門檻,可是目前依據不建議放到生產環境。如下幾個緣由:github
- 成熟度問題,目前還處與 Alpha 階段,故不少功能都還處於實現性質,或者不太穩定。
- 提高網路頻寬與成本,由於 Federation 須要監控全部叢集以確保當前狀態符合預期,因是會增長額外效能開銷。
- 跨叢集隔離差,Federation 的子叢集git有可能因為 Bug 的引發而影響其餘叢集運行狀況。
- 個人用起來不是很穩定,例如創建的 Deployment 刪除很常會 Timeout。
- 支援的物件資源有限,如不支援 StatefulSets。可參考 API resources。
Federation 主要包含三個元件:api
本次安裝做業系統採用Ubuntu 16.04 Server
,測試環境為實體機器,共有三組叢集:ide
Federation 控制平面叢集(簡稱 F):工具
IP Address | Host | vCPU | RAM |
---|---|---|---|
172.22.132.31 | k8s-f-m1 | 4 | 16G |
172.22.132.32 | k8s-f-n1 | 4 | 16G |
叢集 A:ui
IP Address | Host | vCPU | RAM |
---|---|---|---|
172.22.132.41 | k8s-a-m1 | 8 | 16G |
172.22.132.42 | k8s-a-n1 | 8 | 16G |
叢集 B:google
IP Address | Host | vCPU | RAM |
---|---|---|---|
172.22.132.51 | k8s-b-m1 | 8 | 16G |
172.22.132.52 | k8s-b-n1 | 8 | 16G |
安裝與進行 Federation 以前,須要確保如下條件達成:spa
... ... name: k8s-a-cluster contexts: - context: cluster: k8s-a-cluster user: a-cluster-admin name: a-cluster-context current-context: a-cluster-context kind: Config preferences: {} users: - name: a-cluster-admin user: ...
這邊須要修改每個叢集 config。
$ ls a-cluster.conf b-cluster.conf f-cluster.conf $ KUBECONFIG=f-cluster.conf:a-cluster.conf:b-cluster.conf kubectl config view --flatten > ~/.kube/config $ kubectl config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE a-cluster-context k8s-a-cluster a-cluster-admin b-cluster-context k8s-b-cluster b-cluster-admin * f-cluster-context k8s-f-cluster f-cluster-admin
$ wget https://storage.googleapis.com/kubernetes-federation-release/release/v1.9.0-alpha.3/federation-client-linux-amd64.tar.gz $ tar xvf federation-client-linux-amd64.tar.gz $ cp federation/client/bin/kubefed /usr/local/bin/ $ kubefed version Client Version: version.Info{Major:"1", Minor:"9+", GitVersion:"v1.9.0-alpha.3", GitCommit:"85c06145286da663755b140efa2b65f793cce9ec", GitTreeState:"clean", BuildDate:"2018-02-14T12:54:40Z", GoVersion:"go1.9.1", Compiler:"gc", Platform:"linux/amd64"} Server Version: version.Info{Major:"1", Minor:"9", GitVersion:"v1.9.6", GitCommit:"9f8ebd171479bec0ada837d7ee641dec2f8c6dd1", GitTreeState:"clean", BuildDate:"2018-03-21T15:13:31Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"linux/amd64"}
$ wget -qO- https://kubernetes-helm.storage.googleapis.com/helm-v2.8.1-linux-amd64.tar.gz | tar -zxf $ sudo mv linux-amd64/helm /usr/local/bin/ $ kubectl -n kube-system create sa tiller $ kubectl create clusterrolebinding tiller --clusterrole cluster-admin --serviceaccount=kube-system:tiller $ helm init --service-account tiller # wait for a few minutes $ helm version Client: &version.Version{SemVer:"v2.8.1", GitCommit:"6af75a8fd72e2aa18a2b278cfe5c7a1c5feca7f2", GitTreeState:"clean"} Server: &version.Version{SemVer:"v2.8.1", GitCommit:"6af75a8fd72e2aa18a2b278cfe5c7a1c5feca7f2", GitTreeState:"clean"}
由於本篇是使用實體機器部署 Kubernetes 叢集,所以無法像是 GCP 能夠提供 DNS 服務來給 Federation 使用,故這邊要用 CoreDNS 創建自定義 DNS 服務。
首先透過 Helm 來安裝 CoreDNS 使用到的 Etcd:
$ helm install --namespace federation --name etcd-operator stable/etcd-operator $ helm upgrade --namespace federation --set cluster.enabled=true etcd-operator stable/etcd-operator $ kubectl -n federation get po NAME READY STATUS RESTARTS AGE etcd-operator-etcd-operator-etcd-backup-operator-577d56449zqkj2 1/1 Running 0 1m etcd-operator-etcd-operator-etcd-operator-56679fb56-fpgmm 1/1 Running 0 1m etcd-operator-etcd-operator-etcd-restore-operator-65b6cbccl7kzr 1/1 Running 0 1m
完成後就能夠安裝 CoreDNS 來提供自定義 DNS 服務了:
$ cat <<EOF > Values.yaml isClusterService: false serviceType: NodePort middleware: kubernetes: enabled: false etcd: enabled: true zones: - "kairen.com." endpoint: "http://etcd-cluster.federation:2379" EOF $ kubectl create clusterrolebinding federation-admin --clusterrole=cluster-admin --user=system:serviceaccount:federation:default $ helm install --namespace federation --name coredns -f Values.yaml stable/coredns # 測試 CoreDNS 能夠查詢 Domain Name $ kubectl run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools dnstools# host kubernetes kubernetes.default.svc.cluster.local has address 10.96.0.1
完成 CoreDNS 後,接著透過 kubefed 安裝控制平面元件,由於使用到 CoreDNS,所以這邊要傳入相關 conf 檔,首先創建coredns-provider.conf
檔案,加入如下內容:
$ cat <<EOF > coredns-provider.conf [Global] etcd-endpoints = http://etcd-cluster.federation:2379 zones = kairen.com. EOF
請自行修改
etcd-endpoints
與zones
。
檔案創建並確認沒問題後,透過 kubefed 工具來初始化主叢集:
$ kubefed init federation \ --host-cluster-context=f-cluster-context \ --dns-provider="coredns" \ --dns-zone-name="kairen.com." \ --apiserver-enable-basic-auth=true \ --apiserver-enable-token-auth=true \ --dns-provider-config="coredns-provider.conf" \ --apiserver-arg-overrides="--anonymous-auth=false,--v=4" \ --api-server-service-type="NodePort" \ --api-server-advertise-address="172.22.132.31" \ --etcd-persistent-storage=true $ kubectl -n federation-system get po NAME READY STATUS RESTARTS AGE apiserver-848d584b5d-cwxdh 2/2 Running 0 1m controller-manager-5846c555c6-mw2jz 1/1 Running 1 1m
這邊能夠改變
--etcd-persistent-storage
來選擇使用或不使用 PV,若使用請先創建一個 PV 來提供給 Federation Pod 的 PVC 索取使用,能夠參考 Persistent Volumes。
$ kubectl config use-context federation # 加入 k8s-a-cluster $ kubefed join f-a-cluster \ --cluster-context=a-cluster-context \ --host-cluster-context=f-cluster-context # 加入 k8s-b-cluster $ kubefed join f-b-cluster \ --cluster-context=b-cluster-context \ --host-cluster-context=f-cluster-context $ kubectl get cluster NAME AGE f-a-cluster 57s f-b-cluster 53s
這邊利用 Nginx Deployment 來進行測試,先簡單創建一個副本為 4 的 Nginx:
$ kubectl config use-context federation $ kubectl create ns default $ kubectl run nginx --image nginx --port 80 --replicas=4
查看 Cluster A:
$ kubectl --context=a-cluster-context get po NAME READY STATUS RESTARTS AGE nginx-7587c6fdb6-dpjv5 1/1 Running 0 25s nginx-7587c6fdb6-sjv8v 1/1 Running 0 25s
查看 Cluster B:
$ kubectl --context=b-cluster-context get po NAME READY STATUS RESTARTS AGE nginx-7587c6fdb6-dv45v 1/1 Running 0 1m nginx-7587c6fdb6-wxsmq 1/1 Running 0 1m
其餘可測試功能: