一、引言
Federation (集群联邦)是 k8s 社区中重要的多云管理项目,实现了跨地区跨服务商管理多个 k8s 集群的功能。
它主要提供了如下两个模型:
- 跨集群同步资源:Federation 能够让资源在多个集群中同步。
- 跨集群发现:Federation 能够在所有集群的后端自动配置 DNS 服务和负载均衡。
二、Federation v2 架构分析
直接引用一张官方架构图:
Federation v2 采用 CRD 模式运行在 Kubernetes 集群中,扩展了 k8s 的资源管理能力。
首先,它向原有 k8s 集群注册一系列 CRD 资源,这些 CRD 定义了联邦系统所支持的 k8s 资源;
然后,它通过开启一个 ControllerManager 来管理这些 CRD 资源,实现跨集群资源调度。
CRD 资源和 ControllerManager 共同构成了 Federation v2 的 Control Plane。
目前 Federation v2 主要定义了 4 种 CRD 资源:
Cluster Configuration:主要定义了子集群注册时的配置信息。当用户执行 kubefed2 join 命令将安装好的集群加入联邦时,federation-controller-manager 会自动读取新加入集群的 context 信息,生成 Cluster Configuration 信息;
Type Configuration:主要定义了 Federation 可以处理哪些资源对象。每个 Type Configuration 包括三个子配置项:
- Template:定义了 Federation 要处理的资源对象,含有该对象的全部信息;
- Placement:定义要将资源对象运行在哪些子集群中,如不定义该对象,则资源不会运行在任一集群;
- Override:针对不同集群的特殊需求,会重写覆盖 Template 中的内容;
Schedule:主要定义应用在集群中的调度分布,该类型主要涉及 Deployment 与 Replicaset 两种。用户可以定义对象在每个集群中分布的最多、最少实例数,并且还能在集群中做到应用实例数的均衡分布。值得注意的是,如果调度结果跟用户自定义的 Override 冲突时,该调度算法享有优先权。例如用户 Override 中定义为 5 个实例,实际调度结果只有 3 个,那么自定义的Override 中 5 个实例将被改为 3 个。
MultiClusterDNS:该资源主要在做多集群间的服务发现,其下主要包含 ServiceDNSRecord、IngressDNSRecord、DNSEndpoint 这几个资源对象。
三、Federation v2 安装部署
环境:ubuntu-18.04,已安装 docker,golang
3.1 下载 Federation v2 及相关依赖
# git clone https://github.com/kubernetes-sigs/federation-v2.git
# cd federation-v2
# ./scripts/download-binaries.sh
# export PATH=$(pwd)/bin:${PATH}
3.2 安装 kind,启动多集群
# ./scripts/download-e2e-binaries.sh
# export PATH=$GOPATH/bin:${PATH}
# ./scripts/create-clusters.sh
3.3 创建 federation 并纳管两个集群
# export KUBECONFIG="/root/.kube/kind-config-1:/root/.kube/kind-config-2"
# kubectl config use-context cluster1
# ./scripts/deploy-federation-latest.sh cluster2
3.4 验证
# kubectl get federatedcluster -n federation-system
显示两个集群(cluster1、cluster2)证明 federation 安装完成!
四、Federation v2 示例验证
4.1 在 cluster1、cluster2 都创建一个名字为 test-namespace 的命名空间
# kubectl apply -f example/sample1/federatednamespace-template.yaml \
-f example/sample1/federatednamespace-placement.yaml
其中 federatednamespace-template.yaml 定义了需要创建的 namespace 的名称
apiVersion: v1
kind: Namespace
metadata:
name: test-namespace
federatednamespace-placement.yaml 定义了 namespace 对象需要被部署到的集群
apiVersion: primitives.federation.k8s.io/v1alpha1
kind: FederatedNamespacePlacement
metadata:
name: test-namespace
namespace: test-namespace
spec:
clusterNames:
- cluster1
- cluster2
首先,在 cluster1 查看是否创建了 test-namespace 对象
# kubectl config use-context cluster1
# kubectl get namespaces
然后,去 cluster2 查看
# kubectl config use-context cluster2
# kubectl get namespaces
证明,我们通过 federation 创建的 namespace 已经按照 federatednamespace-placement.yaml 的要求,
在 cluster1 和 cluster 2 分别创建了 test-namespace
4.2 在 cluster1、cluster2 都创建相同的 Deployment,但指定不同的副本数
# kubectl apply -f example/sample1/federateddeployment-template.yaml \
-f example/sample1/federateddeployment-placement.yaml \
-f example/sample1/federateddeployment-override.yaml
其中, federateddeployment-template.yaml 定义了 nginx deployment,默认 3 副本
apiVersion: primitives.federation.k8s.io/v1alpha1
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
name: nginx
federateddeployment-placement.yaml 定义了 deployment 的目标部署集群
apiVersion: primitives.federation.k8s.io/v1alpha1
kind: FederatedDeploymentPlacement
metadata:
name: test-deployment
namespace: test-namespace
spec:
clusterNames:
- cluster2
- cluster1
federateddeployment-override.yaml 针对不同集群,重写了副本数量设置
apiVersion: primitives.federation.k8s.io/v1alpha1
kind: FederatedDeploymentOverride
metadata:
name: test-deployment
namespace: test-namespace
spec:
overrides:
- clusterName: cluster2
clusterOverrides:
- path: spec.replicas
value: 5
我们先去 cluster1 验证下 deployment 的数量是否正确(预期为 3)
# kubectl config use-context cluster1
# kubectl get deployment -n test-namespace
再去 cluster2 验证(预期为 5)
# kubectl config use-context cluster2
# kubectl get deployment -n test-namespace
可见,deployment 的部署按照预期在 cluster1 和 cluster2 正确部署了!