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

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐