KubeVela 的集群是如何管理的
KubeVela 是多集群应用管理组件,所以在使用之前需要将集群纳管到 KubeVela 中,让 KubeVela 能感知并维护集群信息。在应用下发到指定集群时,KubeVela 能知道如何连接到目标集群并进行操作。
KubeVela 使用的是 Secret
来保存集群信息的,和 Cluster Gateway 共享的同一套 Secret
进行集群管理。当进行集群纳管时,KubeVela 会创建名字和集群名相同的 Secret
,用于存储集群的连接信息。
当请求从 APIServer 转发到 Cluster Gateway 时,使用路径中提供的集群名去查询 Secret 并获取到纳管集群的连接信息。
Cluster Gateway 处理流程如下:
集群信息 Secret
Secret 数据类似下面这样:
1 | apiVersion: v1 |
纳管集群实现
纳管集群时,KubeVela 有两套非常相似的处理逻辑,VelaUX 和 vela-cli:
- VelaUX 业务逻辑入口在
clusterServiceImpl.createKubeCluster
,在进行一些判断后通过joinClusterByKubeConfigString()
函数注册纳管集群,最终调用multicluster.JoinClusterByKubeConfig()
函数进行集群纳管处理; - vela-cli 处理入口在
NewClusterJoinCommand
中,直接调用multicluster.JoinClusterByKubeConfig()
函数进行集群纳管处理。
JoinClusterByKubeConfig()
函数通过 Secret
来管理集群,而在些之上 VelaUX 更进一步。
VelaUX 的 createKubeCluster()
方法还会在 Store 创建 model.Cluster{}
结构的数据,保存集群信息。Store 如果是 kubeapi
,则是存储到 ConfigMap
中,否则存储到 MongoDB。
JoinClusterByKubeConfig
multicluster.JoinClusterByKubeConfig()
函数会创建前面提到的 Secret
用于管理集群,但是在创建后会做一些判断,如果条件不满足会删除创建的数据。
1 | // JoinClusterByKubeConfig add child cluster by kubeconfig path, return cluster info and error |
JoinClusterByKubeConfig()
函数在纳管集群时需要从本地文件读取 kubeconfig
配置,所以在 VelaUX 的 joinClusterByKubeConfigString()
中会先创建临时文件再调用 JoinClusterByKubeConfig()
函数处理。
上面代码中有两个分支的处理逻辑。这里主要关注直接通过 Cluster Gateway 管理的集群,OCM 集群先跳过。ClusterGateway 纳管集群通过 clusterConfig.RegisterByVelaSecret()
方法进行:
1 | func (clusterConfig *KubeClusterConfig) RegisterByVelaSecret(ctx context.Context, cli client.Client) error { |
纳管逻辑很重要部分在后置检查这里,后置检查会保证配置的 clusterConfig.CreateNamespace
命名空间在纳管集群创建,此时会发起请求通过 Cluster Gateway 连接纳管集群进行操作。
[!warning]
这里请求会直接从本地向 APIServer 发起,而且请求 URL 是以下格式:/apis/cluster.core.oam.dev/v1alpha1/clustergateways/{clusterName}/proxy/{api}
Namespace 操作失败会回退纳管操作,删除 Secret
,返回纳管失败错误。
Cluster Gateway 获取集群信息
当代理请求通过 Cluster Gateway 时,就需要去查询集群的信息。
在 Cluster Gateway 代码中,创建代理连接时的处理方法 Connect()
里会去获取集群信息。这个方法会通过 parentStorage.Get()
调用的父资源 ClusterGateway
的 Get()
方法:
1 | func (in *ClusterGateway) Get(ctx context.Context, name string, _ *metav1.GetOptions) (runtime.Object, error) { |
这个方法内部是通过 SecretControl
获取集群同名的 Secret
,并转换成 ClusterGateway
对象,最终传给 proxyHandler
使用,具体参考之前的文章《KubeVela 代理网关 Cluster Gateway 实现》。
总结
KubeVela 这样使用 Secret
管理集群也是有好处的:
Secret
能进行权限管理,保证安全;- 支持通过
Label
设置集群元信息,用于调度时基于Label
进行应用分发。
在代码中我们可以看到,如果使用的 vela-cli 进行纳管,请求会从当前主机向 API Server 发出,而很多时候 Kubernetes 的 API Server 是不开放到外面访问的。
所以在生产环境中,更多的是使用 vela-cli in pod 的方式进行管理。
KubeVela 的集群是如何管理的
https://blog.imoe.tech/2023/05/31/kubevela-cluster-management/