多集群管理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