Federation

    每个 Federation 有自己的分布式存储、API Server 和 Controller Manager。用户可以通过 Federation 的 API Server 注册该 Federation 的成员 K8s Cluster。当用户通过 Federation 的 API Server 创建、更改 API 对象时,Federation API Server 会在自己所有注册的子 K8s Cluster 都创建一份对应的 API 对象。在提供业务请求服务时,K8s Federation 会先在自己的各个子 Cluster 之间做负载均衡,而对于发送到某个具体 K8s Cluster 的业务请求,会依照这个 K8s Cluster 独立提供服务时一样的调度模式去做 K8s Cluster 内部的负载均衡。而 Cluster 之间的负载均衡是通过域名服务的负载均衡来实现的。

    所有的设计都尽量不影响 K8s Cluster 现有的工作机制,这样对于每个子 K8s 集群来说,并不需要更外层的有一个 K8s Federation,也就是意味着所有现有的 K8s 代码和机制不需要因为 Federation 功能有任何变化。

    Federation - 图2

    Federation 主要包括三个组件

    • federation-apiserver:类似 kube-apiserver,但提供的是跨集群的 REST API
    • federation-controller-manager:类似 kube-controller-manager,但提供多集群状态的同步机制
    • kubefed:Federation 管理命令行工具

    Federation 的代码维护在 https://github.com/kubernetes/federation

    kubefed 下载

    kubectl 的下载可以参考 。

    选择一个已部署好的 Kubernetes 集群作为主集群,作为集群联邦的控制平面,并配置好本地的 kubeconfig。然后运行 命令来初始化主集群:

    1. $ kubefed init fellowship \
    2. --host-cluster-context=rivendell \ # 部署集群的 kubeconfig 配置名称
    3. --dns-provider="google-clouddns" \ # DNS 服务提供商,还支持 aws-route53 或 coredns
    4. --dns-zone-name="example.com." \ # 域名后缀,必须以. 结束
    5. --apiserver-enable-basic-auth=true \ # 开启 basic 认证
    6. --apiserver-enable-token-auth=true \ # 开启 token 认证
    7. --apiserver-arg-overrides="--anonymous-auth=false,--v=4" # federation API server 自定义参数
    8. $ kubectl config use-context fellowship

    coredns 需要先部署一套 etcd 集群,可以用 helm 来部署:

    1. $ helm install --namespace my-namespace --name etcd-operator stable/etcd-operator
    2. $ helm upgrade --namespace my-namespace --set cluster.enabled=true etcd-operator stable/etcd-operator
    1. $ cat Values.yaml
    2. isClusterService: false
    3. serviceType: "LoadBalancer"
    4. middleware:
    5. kubernetes:
    6. enabled: false
    7. etcd:
    8. enabled: true
    9. zones:
    10. - "example.com."
    11. endpoint: "http://etcd-cluster.my-namespace:2379"
    12. $ helm install --namespace my-namespace --name coredns -f Values.yaml stable/coredns

    使用 coredns 时,还需要传入 coredns 的配置

    1. $ cat $HOME/coredns-provider.conf
    2. [Global]
    3. etcd-endpoints = http://etcd-cluster.my-namespace:2379
    4. $ kubefed init fellowship \
    5. --host-cluster-context=rivendell \ # 部署集群的 kubeconfig 配置名称
    6. --dns-provider="coredns" \ # DNS 服务提供商,还支持 aws-route53 或 google-clouddns
    7. --dns-zone-name="example.com." \ # 域名后缀,必须以. 结束
    8. --apiserver-enable-basic-auth=true \ # 开启 basic 认证
    9. --apiserver-enable-token-auth=true \ # 开启 token 认证
    10. --dns-provider-config="$HOME/coredns-provider.conf" \ # coredns 配置

    默认情况下,kubefed init 会创建一个 LoadBalancer 类型的 federation API server 服务,这需要 Cloud Provider 的支持。在物理机部署时,可以通过 --api-server-service-type 选项将其改成 NodePort:

    1. $ kubefed init fellowship \
    2. --host-cluster-context=rivendell \ # 部署集群的 kubeconfig 配置名称
    3. --dns-provider="coredns" \ # DNS 服务提供商,还支持 aws-route53 或 google-clouddns
    4. --dns-zone-name="example.com." \ # 域名后缀,必须以. 结束
    5. --apiserver-enable-basic-auth=true \ # 开启 basic 认证
    6. --apiserver-enable-token-auth=true \ # 开启 token 认证
    7. --dns-provider-config="$HOME/coredns-provider.conf" \ # coredns 配置
    8. --apiserver-arg-overrides="--anonymous-auth=false,--v=4" \ # federation API server 自定义参数
    9. --api-server-service-type="NodePort" \
    10. --api-server-advertise-address="10.0.10.20"

    默认情况下,kubefed init 通过动态创建 PV 的方式为 etcd 创建持久化存储。如果 kubernetes 集群不支持动态创建 PV,则可以预先创建 PV,注意 PV 要匹配 kubefed 的 PVC:

    1. apiVersion: v1
    2. kind: PersistentVolumeClaim
    3. metadata:
    4. annotations:
    5. volume.alpha.kubernetes.io/storage-class: "yes"
    6. labels:
    7. app: federated-cluster
    8. name: fellowship-federation-apiserver-etcd-claim
    9. namespace: federation-system
    10. spec:
    11. accessModes:
    12. - ReadWriteOnce
    13. resources:
    14. requests:
    15. storage: 10Gi

    注册集群

    除主集群外,其他 kubernetes 集群可以通过 kubefed join 命令加入集群联邦:

    集群查询

    查询注册到 Federation 的 kubernetes 集群列表

    1. $ kubectl --context=federation get clusters

    v1.7 + 支持使用 annotation federation.alpha.kubernetes.io/cluster-selector 为新对象选择 kubernetes 集群。该 annotation 的值是一个 json 数组,比如

    1. metadata:
    2. annotations:
    3. federation.alpha.kubernetes.io/cluster-selector: '[{"key":"pci","operator":
    4. ["test"]}]'

    每条记录包含三个键值

    • key:集群的 label 名字
    • operator:包括 In, NotIn, Exists, DoesNotExist, Gt, Lt
    • values:集群的 label 值

    策略调度

    开启策略调度的方法

    (1)创建 ConfigMap

      1. kubectl -n federation-system edit deployment federation-apiserver

      增加选项:

      1. --admission-control=SchedulingPolicy
      2. --admission-control-config-file=/etc/kubernetes/admission/config.yml

      增加 volume:

      1. - name: admission-config
      2. configMap:
      3. name: admission

      增加 volumeMounts:

      (3)部署外部策略引擎,如

      1. kubectl create -f https://raw.githubusercontent.com/kubernetes/kubernetes.github.io/master/docs/tutorials/federation/policy-engine-service.yaml
      2. kubectl create -f https://raw.githubusercontent.com/kubernetes/kubernetes.github.io/master/docs/tutorials/federation/policy-engine-deployment.yaml

      (4)创建 namespace kube-federation-scheduling-policy 以供外部策略引擎使用

      1. kubectl --context=federation create namespace kube-federation-scheduling-policy

      (5)创建策略

      1. wget https://raw.githubusercontent.com/kubernetes/kubernetes.github.io/master/docs/tutorials/federation/policy.rego
      2. kubectl --context=federation -n kube-federation-scheduling-policy create configmap scheduling-policy --from-file=policy.rego

      (6)验证策略

      1. kubectl --context=federation annotate clusters cluster-name-1 pci-certified=true
      2. kubectl --context=federation create -f https://raw.githubusercontent.com/kubernetes/kubernetes.github.io/master/docs/tutorials/federation/replicaset-example-policy.yaml
      3. kubectl --context=federation get rs nginx-pci -o jsonpath='{.metadata.annotations}'

      集群联邦使用

      集群联邦支持以下联邦资源,这些资源会自动在所有注册的 kubernetes 集群中创建:

      • Federated ConfigMap
      • Federated Service
      • Federated DaemonSet
      • Federated Deployment
      • Federated Ingress
      • Federated Namespaces
      • Federated ReplicaSets
      • Federated Secrets
      • Federated Events(仅存在 federation 控制平面)
      • Federated Jobs(v1.8+)
      • Federated Horizontal Pod Autoscaling (HPA,v1.8+)

      比如使用 Federated Service 的方法如下:

      1. # 这会在所有注册到联邦的 kubernetes 集群中创建服务
      2. $ kubectl --context=federation-cluster create -f services/nginx.yaml
      3. # 添加后端 Pod
      4. $ for CLUSTER in asia-east1-c asia-east1-a asia-east1-b \
      5. europe-west1-d europe-west1-c europe-west1-b \
      6. us-central1-f us-central1-a us-central1-b us-central1-c \
      7. us-east1-d us-east1-c us-east1-b
      8. do
      9. kubectl --context=$CLUSTER run nginx --image=nginx:1.11.1-alpine --port=80
      10. done
      11. # 查看服务状态
      12. $ kubectl --context=federation-cluster describe services nginx

      可以通过 DNS 来访问联邦服务,访问格式包括以下几种

      • nginx.mynamespace.myfederation.
      • nginx.mynamespace.myfederation.svc.example.com.
      • nginx.mynamespace.myfederation.svc.us-central1.example.com.
      1. $ kubefed unjoin gondor --host-cluster-context=rivendell

      删除集群联邦

      参考文档