federation
weight: 70
title: 集群联邦(Cluster Federation)
date: “2023-01-17T10:40:00+08:00”
type: book
注意
为什么要使用集群联邦
- 跨集群同步资源:
Federation 提供了在多个集群中保持资源同步的能力。例如,可以保证同一个deployment 在多个集群中存在。 - 跨集群服务发现:
Federation 提供了自动配置DNS 服务以及在所有集群后端上进行负载均衡的能力。例如,可以提供一个全局VIP 或者DNS 记录,通过它可以访问多个集群后端。
- 高可用:通过在集群间分布负载并自动配置
DNS 服务和负载均衡,federation 最大限度地减少集群故障的影响。 - 避免厂商锁定:通过更简单的跨集群应用迁移方式,
federation 可以防止集群厂商锁定。
- 低延迟:通过在多个区域部署集群可以最大限度减少区域近端用户的延迟。
- 故障隔离:拥有多个小集群可能比单个大集群更利于故障隔离(例如:在云服务提供商的不同可用区中的多个集群
) 。 - 可伸缩性:单个集群有可伸缩性限制(对于大多数用户这不是典型场景。更多细节请参考
Kubernetes 弹性伸缩与性能目标) 。 - 混合云:你可以在不同的云服务提供商或本地数据中心中拥有多个集群。
警告
虽然
- 增加网络带宽和成本:
federation 控制平面监控所有集群以确保当前状态符合预期。如果集群在云服务提供商的不同区域或者不同的云服务提供商上运行时,这将导致明显的网络成本增加。 - 减少跨集群隔离:
federation 控制平面中的bug 可能影响所有集群。通过在federation 中实现最少的逻辑可以缓解这种情况。只要有可能,它就将尽力把工作委托给kubernetes 集群中的控制平面。这种设计和实现在安全性及避免多集群停止运行上也是错误的。 - 成熟度:
federation 项目相对比较新,还不是很成熟。并不是所有资源都可用,许多仍然处于alpha 状态。Issue 88 列举了团队目前正忙于解决的与系统相关的已知问题。
混合云能力
此后,你的
单个集群范围
在诸如
- 与拥有单个全局
Kubernetes 集群相比,单点故障更少。 - 与跨可用区集群相比,推测单区域集群的可用性属性更容易。
- 当
Kubernetes 开发人员设计系统时(例如对延迟,带宽或相关故障进行假设) ,它们假设所有的机器都在一个单一的数据中心,或以其它方式紧密连接。
在每个可用区域同时拥有多个集群也是可以的,但总体而言,我们认为少一点更好。选择较少集群的理由是:
- 某些情况下,在一个集群中拥有更多的节点可以改进
Pod 的装箱打包(较少资源碎片) 。 - 减少运维开销(尽管随着运维工具和流程的成熟,优势已经减少
) 。 - 减少每个集群固定资源成本的开销,例如
apiserver 虚拟机(但对于大中型集群的整体集群成本来说百分比很小) 。
拥有多个集群的原因包括:
- 严格的安全策略要求将一类工作与另一类工作隔离开来(但是,请参见下面的分区集群(Partitioning Clusters
) ) 。 - 对新的
Kubernetes 发行版或其它集群软件进行灰度测试。
选择正确的集群数量
要选择集群的数量,首先要确定使用哪些区域,以便为所有终端用户提供足够低的延迟,以在R
。
其次,决定在整体仍然可用的前提下,可以同时有多少集群不可用。将不可用集群的数量称为 U
。如果你不能确定,那么
如果在集群故障的情形下允许负载均衡将流量引导到任何区域,则至少需要有比 R
或 U + 1
数量更大的集群。如果不行的话(例如希望在集群发生故障时对所有用户确保低延迟R * (U + 1)
的集群(R
个区域,每个中有 U + 1
个集群
最后,如果你的任何集群需要比
Kubernetes 集群联邦的演进
- 在集群层面重新实施
Kubernetes API 的困难,因为Federation 的特定扩展存储在注释中。 - 由于
Kubernetes API 的1:1 仿真,Federation 类型、放置(placement)和调节(reconciliation)的灵活性有限。 - 没有固定的
GA 路径,API 成熟度普遍混乱;例如,Deployment 在Kubernetes 中是GA ,但在Federation v1 中甚至不是Beta 。
随着
下面将带你了解
将任意资源联合起来
联邦的主要目标之一是能够定义
规范的
在定义Template
资源、一个 Placement
资源和一个 Override
资源,一个 TypeConfig
来指定给定资源的同步或不同步,以及执行同步的相关控制器。更多细节将在后文中介绍。进一步的章节还将谈到能够遵循分层行为,更高级别的
能够 “轻松地联合任意
联邦服务与跨集群服务发现
注意:联邦服务必须是
Pod 如何发现联邦服务
默认情况下,myservice.mynamespace
或 some-other-service.other-namespace
等
随着联邦服务和跨集群服务发现的引入,这个概念被扩展到全局覆盖在你的集群联邦中所有集群中运行的myservice.mynamespace.myfederation
)来解析联邦服务。使用不同的
让我们看一个例子,使用一个名为
在 us-central1-a
可用区的集群中的一个nginx.mynamespace.myfederation
,而不是使用服务的传统集群本地nginx.mynamespace
自动扩展为 nginx.mynamespace.svc.cluster.local
如果服务在本地集群中不存在(或者存在但没有健康的后端nginx.mynamespace.myfederation.svc.us-central1-a.example.com
。在幕后,这可以找到离我们的可用区最近的一个
也可以通过明确指定适当的nginx.mynamespace.myfederation.svc.europe-west1.example.com
将解析到欧洲所有当前健康的服务
从联邦集群之外的其他客户端发现联邦服务
对于外部客户端,目前还不能实现所述自动
短名称 | CNAME |
---|---|
eu.nginx.acme.com | nginx.mynamespace.myfederation.svc.europe-west1.example.com |
us.nginx.acme.com | nginx.mynamespace.myfederation.svc.us-central1.example.com |
nginx.acme.com | nginx.mynamespace.myfederation.svc.example.com |
这样一来,你的客户就可以始终使用左边的短名称,并始终自动路由到离他们位置最近的健康
架构概览
由于
上图中展示了集群联邦的过程:
- 配置需要联邦的集群
- 配置需要在集群中传播的
API 资源 - 配置
API 资源如何分配到不同的集群 - 对集群中
DNS 记录注册
相较于
目前
API Group | 用途 |
---|---|
core.kubefed.k8s.io | 集群组态、联邦资源组态、 |
types.kubefed.k8s.io | 被联邦的 |
scheduling.kubefed.k8s.io | 副本编排策略。 |
multiclusterdns.kubefed.k8s.io | 跨集群服务发现设定。 |
在这些核心功能中,我们必须先了解一些
Cluster Configuration
用来定义哪些
在
Host : 用于提供KubeFed API 与控制平面的集群。Member : 通过KubeFed API 注册的集群,并提供相关身份凭证来让KubeFed Controller 能够存取集群。Host 集群也可以作为Member 被加入。
Type Configuration
定义了哪些
apiVersion: core.kubefed.k8s.io/v1beta1
kind: FederatedTypeConfig
metadata:
name: configmaps
namespace: kube-federation-system
spec:
federatedType:
group: types.kubefed.k8s.io
kind: FederatedConfigMap
pluralName: federatedconfigmaps
scope: Namespaced
version: v1beta1
propagation: Enabled
targetType:
kind: ConfigMap
pluralName: configmaps
scope: Namespaced
version: v1
若想新增kubefedctl enable <res>
指令来建立,如下
$ kubefedctl enable etcdclusters
$ kubectl api-resources | grep etcd
etcdclusters etcd etcd.database.coreos.com true EtcdCluster
federatedetcdclusters fetcd types.kubefed.k8s.io true FederatedEtcdCluster
$ kubectl -n kube-federation-system get federatedtypeconfigs | grep etcd
etcdclusters.etcd.database.coreos.com 3m16s
而一个
apiVersion: types.kubefed.k8s.io/v1beta1
kind: FederatedDeployment
metadata:
name: test-deployment
namespace: test-namespace
spec:
template: # 定义 Deployment 的所有內容,可理解成 Deployment 与 Pod 之间的关联。
metadata:
labels:
app: nginx
spec: ...
placement:
clusters:
- name: cluster2
- name: cluster1
overrides:
- clusterName: cluster2
clusterOverrides:
- path: spec.replicas
value: 5
- Placement:定义
Federated 资源要分散到哪些集群上,若没有该文件,则不会分散到任何集群中。如FederatedDeployment 中的spec.placement
定义了两个集群时,这些集群将被同步建立相同的Deployment 。另外也支持用spec.placement.clusterSelector
的方式来选择要放置的集群。 - Override:定义修改指定集群的
Federated 资源中的spec.template
内容。如部署FederatedDeployment 到不同公有云上的集群时,就能通过spec.overrides
来调整Volume 或副本数。
注意:目前spec.template.spec.containers [0].image
。
Scheduling
ReplicaSchedulingPreference
(RSP)文件,再由ReplicaSchedulingPreferences
的用户指南中找到。
以下为一个
apiVersion: scheduling.kubefed.k8s.io/v1alpha1
kind: ReplicaSchedulingPreference
metadata:
name: test-deployment
namespace: test-ns
spec:
targetKind: FederatedDeployment
totalReplicas: 15
clusters:
"*":
weight: 2
maxReplicas: 12
ap-northeast:
minReplicas: 1
maxReplicas: 3
weight: 1
该配置示意图如下所示。
当该范例建立后,spec.overrides
内容以修改每个集群的副本数,最后再由
注意:
- 若
spec.clusters
未定义的话,则预设为{“*”:{Weight: 1}}
。 - 若有定义
spec.replicas
的overrides 时,副本会以RSP 为优先考量。 - 分配的计算机制可以参考
kubefed/pkg/controller/util/planner/planner.go
。
Multi-cluster DNS
apiVersion: multiclusterdns.kubefed.k8s.io/v1alpha1
kind: Domain
metadata:
name: test
namespace: kube-federation-system
domain: k8s.example.com
---
apiVersion: multiclusterdns.kubefed.k8s.io/v1alpha1
kind: ServiceDNSRecord
metadata:
name: nginx
namespace: development
spec:
domainRef: test
recordTTL: 300
首先假设已建立一个名称为
若是