# 多集群 ZooKeeper Operator 设计 ## MultiClusterZooKeeper 我们新增了一个 CRD MultiClusterZooKeeper,用于在多集群控制面维护 ZooKeeper 集群,它的作用如下: 1. 承担 ZooKeeper 实例配置接口 2. 协调跨集群部署的 ZooKeeper 实例的状态 3. 部署与更新跨集群部署的 ZooKeeper 实例 该 CRD 的 reconciliation 逻辑如下: > 注,简称对应关系为: > `MCZK`: MultiClusterZooKeeper > `ZK`: ZooKeeper > `PP`: PropagationPolicy > `OP`: OverridePolicy > `RB`: ResourceBinding > `SvcEx`: ServiceExport > `ES`: EndpointSlice > `RIWC`: ResourceInterpreterWebhookConfiguration  1. 获取 MCZK 实例 2. 生成 ZK 实例、ZK SvcEx 以及对应的 PP,在多集群控制面 apply 3. 在 MCZK 的 RIWC responseWithExploreReviseReplica 实现中,将 .spec.replicas 都设置为 0,即让所有集群都处于已有 ZK CR,但副本均为 0 的状态 4. 从 RB 中获取调度结果 5. 根据调度结果构建部署记录(record),record 的结构体大致如下: ```go // MultiClusterZooKeeperStatus defines the observed state of MultiClusterZooKeeper type MultiClusterZooKeeperStatus struct { // ObservedGeneration is the most recent generation observed for this cluster. // It corresponds to the metadata generation, which is updated on mutation by the API Server. // +optional ObservedGeneration int64 `json:"observedGeneration,omitempty"` // Conditions represent observations of the MultiClusterZooKeeper's state Conditions []metav1.Condition `json:"conditions,omitempty"` // Records represent the deployment history of MultiClusterZooKeeper Records []Record `json:"records,omitempty"` } type Record struct { // ObservedGenerations 用于记录 multiclusterzookeeper 的代数,以及控制面中的 zookeeper 的代数 ObservedGenerations map[string]int64 `json:"observedGenerations"` // Order 用于记录集群的部署顺序,item 是集群名称 Order []string `json:"order"` // Status 用于表示当前 Record 的状态,部署中-“Deploy”、就绪-“Ready” Status string `json:"status"` // CurrentState 用于记录当前正在部署的集群的状态,key 表示状态,如 “deploying”、“completed”、“pending”,value 表示属于当前状态的集群名称的集合 CurrentState map[string][]string `json:"currentState,omitempty"` // 记录 Record 更新的时间 LastTransitionTime metav1.Time `json:"lastTransitionTime"` } ``` 6. 按照部署规则完成子集群中 ZK 实例的部署: 1. 生成全副本的 FQDN,该部分需要同步给所有副本 2. 生成 OP 修改对应子群众 ZK 实例的 .spec.replicas 以及配置(全副本 FQDN 信息) 7. 更新状态 ## Record 部分的处理逻辑 规则如下: 1. 判断当前是否处于可部署状态 1. 判断 `.status.records` 是否为空,为空表示目前没有任何部署记录,处于可以开始新部署的状态 2. 如果 `.status.records` 不为空,则检查最后一个 item,该 item 表示最近一次部署的记录。对该 item 进行以下检查: - 检查 `item.observedGenerations["zookeeper"]` 的值是否【小于】控制面中的 ZK 实例的 generation,【小于】表示控制面中的 ZK 实例发生了变更 - 检查 `item.status` 是否处于就绪状态,即 `Ready` 以上两个条件均达成则表示当前处于可以开始新部署的状态 2. 当开始一次新的部署时: 1. 如果 `.status.records` 为空: 1. 则生成新的 record,填写 order(当前暂时使用 karmada 调度结果顺序部署) 2. 将 `record.status` 设置为 `Deploying` 2. 如果 `.status.records` 不为空: 1. 取出最后一个 record 3. 现在我们持有一个用于新部署的 deployRecord,对该 deployRecord 进行处理: 1. 如果 deployRecord 的 completed 集合的数量与 order 中的集群数量一致,则表示所有集群已经部署完毕,可以跳过本次部署 2. 如果 deployRecord 的 deploying 集合的数量为 0,而同时 pending 集合的数量大于 0,则将 pending 集合中的第一个集群移到 deploying 集合中,然后开始部署该集群 3. 如果 deployRecord 的 deploying 集合的数量大于 0,则对 deploying 集合中的集群进行检查,判断它是否就绪,如果就绪则将该集群从 deploying 集合中移到 completed 集合 3. 重复上述步骤直至完成部署,更新 `record.status = "Ready"`
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up