多集羣管理kubefed
kubefed概念
1、Federate: 一系列k8s集羣組成的聯邦,可以部署應用到所有的k8s集羣中。
2、KubeFed: 可以跨k8s集羣實現服務發現,服務部署,高可用。
3、Host Cluster: 運行kubefed控制面板的k8s集羣,並且暴露kubefed api服務。
4、Cluster Registration: k8s集羣通過kubefedctl工具加入Host Cluster。
5、Member Cluster: 註冊到kubefed的k8s集羣,Host Cluster也可以是Member Cluster。
6、ServiceDNSRecord:一個或多個k8s集羣中service,通過構建DNS Record進行記錄。
7、IngressDNSRecord:一個或多個k8s集羣中ingress,通過構建DNS Record進行記錄。
8、Endpoint: 代表DNS Record。
9、DNSEndpoint: 自定義資源用於封裝Endpoint。
kubefed部署
通過helm chart部署
部署kubefed後會生成crd資源FederatedTypeConfig。該資源將k8s中原生對象啓動聯邦資源。
kubectl get FederatedTypeConfig
NAME AGE
clusterroles.rbac.authorization.k8s.io 3h27m
configmaps 3h27m
deployments.apps 3h27m
ingresses.extensions 3h27m
jobs.batch 3h27m
namespaces 3h27m
replicasets.apps 3h27m
secrets 3h27m
serviceaccounts 3h27m
services 3h27m
kubefed卸載
首先,清理Unjoin clusters
kubefedctl unjoin cluster1 --host-cluster-context cluster --v=2 --kubefed-namespace default
kubefedctl unjoin cluster --host-cluster-context cluster --v=2 --kubefed-namespace default
然後,清理crd
kubectl --ignore-not-found=true delete FederatedTypeConfig --all
kubectl --ignore-not-found=true delete crd $(kubectl get crd | grep -E 'kubefed.io' | awk '{print $1}')
最後,執行helm delete --purge kubefed
刪除helm部署的kubefed。
kubefed使用
1、Cluster Registration
把k8s集羣通過kubefedctl工具加入Host Cluster中,執行命令
kubefedctl join cluster1 --cluster-context cluster1 --host-cluster-context cluster --v=2 --kubeconfig=config --kubefed-namespace default
kubefedctl join cluster --cluster-context cluster --host-cluster-context cluster --v=2 --kubeconfig=config --kubefed-namespace default
2、創建聯邦名字空間(federatedNamespace)
kubectl create ns test-namespace
cat > federatednamespace.yml <<EOF
> apiVersion: types.kubefed.io/v1beta1
> kind: FederatedNamespace
> metadata:
> name: test-namespace
> namespace: test-namespace
> spec:
> placement:
> clusters:
> - name: cluster
> - name: cluster1
> EOF
kubectl create -f federatednamespace.yml
會在k8s集羣cluster,cluster1中都創建namespace test-namespace。
3、創建聯邦資源
configmap
secret
deployment
service
serviceaccount
例如,deployment
apiVersion: types.kubefed.io/v1beta1
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:1.17
name: nginx
placement:
clusters:
- name: cluster
- name: cluster1
overrides:
- clusterName: cluster
clusterOverrides:
- path: "/spec/replicas"
value: 5
- path: "/spec/template/spec/containers/0/image"
value: "nginx:1.14.0-alpine"
- path: "/metadata/annotations"
op: "add"
value:
foo: bar
- path: "/metadata/annotations/foo"
op: "remove"
會在cluster的k8s集羣上以nginx:1.14.0-alpine作爲鏡像創建5個pod,在cluster1的k8s集羣上以nginx:1.17爲鏡像創建3個pod。
KubeFed DNS for Ingress and Service
kubefed使用ExternalDNS,CoreDNS,metallb,ingress controller對聯邦集羣的聯邦服進行務統一管理和訪問。以下1-3步驟只在聯邦集羣的host-cluster上操作,4和5步在聯邦集羣下所有集羣上操作,示例只在聯邦集羣任一個集羣操作即可。
1、安裝etcd集羣(採用ectdoperator進行安裝),安裝後獲取etcd的訪問urlhttp://10.233.62.126
.
$ kubectl get svc -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
etcd-cluster ClusterIP None <none> 2379/TCP,2380/TCP 85m
etcd-cluster-client ClusterIP 10.233.62.126 <none> 2379/TCP 85m
etcd-restore-operator ClusterIP 10.233.17.87 <none> 19999/TCP 85m
2、安裝coredns,配置自定義域名和存儲etcd訪問url
在coredns的helm chart文件values.yaml加入以下配置
diff --git a/values.yaml b/values.yaml
index 964e72b..e2fa934 100644
--- a/values.yaml
+++ b/values.yaml
servers:
- zones:
@@ -51,6 +51,12 @@ servers:
parameters: 0.0.0.0:9153
- name: proxy
parameters: . /etc/resolv.conf
+ - name: etcd
+ parameters: example.org
+ configBlock: |-
+ stubzones
+ path /skydns
+ endpoint http://10.105.68.165:2379
# Complete example with all the options:
# - zones: # the `zones` block can be left out entirely, defaults to "."
3、安裝externaldns,使用coredns作爲provider,kubefed作爲crd-source。yaml文件內容如下
$ kubectl get svc example-etcd-cluster-client -o jsonpath={.spec.clusterIP} && echo
10.102.147.224
$ cat <<EOF | kubectl create -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: external-dns
namespace: kube-system
spec:
strategy:
type: Recreate
selector:
matchLabels:
app: external-dns
template:
metadata:
labels:
app: external-dns
spec:
containers:
- name: external-dns
image: registry.opensource.zalan.do/teapot/external-dns:latest
args:
- --source=crd
- --crd-source-apiversion=multiclusterdns.kubefed.io/v1alpha1
- --crd-source-kind=DNSEndpoint
- --registry=txt
- --provider=coredns
- --log-level=debug # debug only
env:
- name: ETCD_URLS
value: http://10.102.147.224:2379
EOF
4、在聯邦集羣下的所有集羣上部署metallb,並配置。
$ helm --kube-context cluster1 install --name metallb stable/metallb
$ helm --kube-context cluster2 install --name metallb stable/metallb
示例配置如下,根據自己環境調整。(如果不配置bgp,可以不用配置peers內容,只需要address-pools)
$ cat <<EOF | kubectl create --context cluster1 -f -
apiVersion: v1
kind: ConfigMap
metadata:
name: metallb-config
data:
config: |
peers:
- peer-address: 10.0.0.1
peer-asn: 64501
my-asn: 64500
address-pools:
- name: default
protocol: bgp
addresses:
- 192.168.20.0/24
EOF
$ cat <<EOF | kubectl create --context cluster2 -f -
apiVersion: v1
kind: ConfigMap
metadata:
name: metallb-config
data:
config: |
peers:
- peer-address: 10.0.0.2
peer-asn: 64500
my-asn: 64501
address-pools:
- name: default
protocol: bgp
addresses:
- 172.168.20.0/24
EOF
5、在聯邦集羣下的所有集羣上部署nginx-ingress controller。
注意配置修改nginx-ingress controller helm chart的values.yaml文件中.Values.controller.publishService.enabled
爲true。
部署完成,運行示例進行驗證。
首先,在所有集羣創建test-namespace測試名字空間,不然會報錯名字空間不存在。
然後在hostcluster上創建示例federatednamespace、federateddeployment、federatedservice、federateingress。
最後創建domain、serviceDnsRecord、ingressDnsRecord。集羣會自動創建dnsendpoint對象(serviceDnsRecord對應一個dnsendpoint,ingressDnsRecord對應一個dnsendpoint)
檢查自動創建的dnsendpoint對象是否包含dns信息。
測試發現ingressDNScontroller運行正常,ingressDnsRecord對應的dnsendpoint包含dns配置信息,並且成功記錄到externaldns使用的etcd中。
serviceDNScontroller運行不成功,serviceDnsRecord對應的dnsendpoint只有空信息。
github有相同問題https://github.com/kubernetes-sigs/kubefed/issues/872和https://github.com/kubernetes-sigs/kubefed/issues/834。
https://github.com/kubernetes-sigs/kubefed/issues/464