现网有好几个 Luminous 的集群,因为指导 Rook 可以用来管理外部集群,所以想尝试一下。外部集群的概念是指,通过部署 Rook,来管理部署在其他集群或者物理机的 Ceph 集群,也就是 Rook 里 External Cluster 的概念。
// pkg/operator/ceph/cluster/cluster_external.go
// 先是判断 CephCluster 自定义资源的 Spec 字段有没有 CephVersion 和 DataDirHostPath 字段
func validateExternalClusterSpec(cluster *cluster) error {
if cluster.Spec.CephVersion.Image != "" {
if cluster.Spec.DataDirHostPath == "" {
return errors.New("dataDirHostPath must be specified")
}
}
return nil
}
// 然后输出连接外部集群的初始状态,当然就是连接中 connecting
config.ConditionExport(c.context, c.namespacedName, cephv1.ConditionConnecting, v1.ConditionTrue, "ClusterConnecting", "Cluster is connecting")
// 这里需要将外部集群的 ceph.conf 往 operator pod 里面写
cluster.ClusterInfo = mon.PopulateExternalClusterInfo(c.context, c.namespacedName.Namespace, cluster.ownerRef)
上面的代码主要是初始化用的,目的是创建连接外部集群的上下文,下面是具体创建 Ceph External Cluster 的流程。PopulateExternalClusterInfo
方法就是把 mon 的配置输出。层层深入可以发现,这方法真正执行的是一个公共方法,也就是不管是内部还是外部集群,都会用到的一个方法。CreateOrLoadClusterInfo
这个方法大概会把 ceph.conf 写到对应的 operator 的目录里。而真正把配置信息写到磁盘的是 generateConfigFile
这个方法。
PopulateMonHostMembers
这个方法是写 mon host 的方法,但这个方法似乎是按照 v1/v2 的方式来写的,这会不会意味着 operator 无法直接连接外部集群 v12.2.13 的集群?
// PopulateMonHostMembers extracts a list of just the monitor names, which will populate the "mon initial members"
// and "mon hosts" global config field
func PopulateMonHostMembers(monitors map[string]*MonInfo) ([]string, []string) {
monMembers := make([]string, len(monitors))
monHosts := make([]string, len(monitors))
i := 0
for _, monitor := range monitors {
monMembers[i] = monitor.Name
monIP := cephutil.GetIPFromEndpoint(monitor.Endpoint)
// This tries to detect the current port if the mon already exists
// This basically handles the transition between monitors running on 6790 to msgr2
// So whatever the previous monitor port was we keep it
currentMonPort := cephutil.GetPortFromEndpoint(monitor.Endpoint)
monPorts := [2]string{strconv.Itoa(int(Msgr2port)), strconv.Itoa(int(currentMonPort))}
msgr2Endpoint := net.JoinHostPort(monIP, monPorts[0])
msgr1Endpoint := net.JoinHostPort(monIP, monPorts[1])
monHosts[i] = "[v2:" + msgr2Endpoint + ",v1:" + msgr1Endpoint + "]"
i++
}
return monMembers, monHosts
}
所以看起来并没有办法让 Rook Operator 去连接 Nautilus 版本之前的 Ceph Cluster 了?当然了,看代码嫌浪费时间的话,可以直接一点,把源码改成你想要的样子,现在问题出在 mon host 的配置上,那我们就把这个地方改一下就好了吧,这里主要判断一下 external ceph cluster 的 cephVersion 参数就好了。
关于这一 part,可以参考一下 Ceph 的文档。反正按照 Rook 的方法,mon host 肯定要被写成 [v2:xxx, v1:xxx] 这种格式的。这个要看 rook operator 里 ceph 命令的版本。
https://docs.ceph.com/docs/master/rados/configuration/msgr2/
# cat rook-ceph-external.config
[global]
fsid = bcc8be6a-4497-4a42-8fe9-091258077a8b
mon initial members = arthub-node2
mon host = [v2:100.xxx.yy.43:3300,v1:100.xxx.yy.43:6789]
[client.admin]
keyring = /var/lib/rook/rook-ceph-external/client.admin.keyring
# cat ceph.conf
[global]
fsid = bcc8be6a-4497-4a42-8fe9-091258077a8b
mon initial members = arthub-node2
mon host = 100.xxx.yy.43
然而等我改好代码之后发现,这里已经表示只支持 Nautilus 之后的版本了…再搞下去也没意义了,就算搞出来也可能会有各种各样的问题。
https://github.com/rook/rook/blob/2052d5e657b748697a04e936409611daf2fbc909/pkg/operator/ceph/version/version.go#L273
最后到 Slack 问了一下,目前外部集群的最低版本是 Luminous 还是 Nautilus,反正也提了个 issue,猜测应该是文档更新不够及时了,因为上面那行代码通过 git blame
看是 2019/10/08 写的,而文档的那一行是 2019/10/02 修改的。总之想用 Rook 来管理 Luminous 的几个集群的想法不 work 了。