global 集群灾难恢复

灾难恢复路径

本页记录运行在 传统操作系统 上的 global 集群的灾难恢复。如果 global 集群使用 Alauda OS,请改为参阅 不可变基础设施上的 global 集群灾难恢复

概述

本方案面向 global 集群的灾难恢复场景设计。global 集群作为平台的控制平面,负责管理其他集群。为确保当 global 集群发生故障时平台服务持续可用,本方案部署两个 global 集群:主集群和备用集群。

灾难恢复机制基于从主集群到备用集群的 etcd 数据实时同步。如果主集群因故障不可用,服务可以快速切换到备用集群。

支持的灾难场景

  • 主集群发生无法恢复的系统级故障,导致其无法运行;
  • 托管主集群的物理机或虚拟机故障,导致其无法访问;
  • 主集群所在位置发生网络故障,导致服务中断;

不支持的灾难场景

  • global 集群内已部署应用发生故障;
  • 由存储系统故障导致的数据丢失(不在 etcd 同步范围内);

主集群备用集群 的角色是相对的:当前为平台提供服务的集群是主集群(DNS 指向它),而待命集群是备用集群。发生故障切换后,这两个角色会互换。

注意事项

  • 本方案仅同步 global 集群的 etcd 数据,不包括 registry、chartmuseum 或其他组件的数据;

  • 为便于故障排查和管理,建议使用类似 standby-global-m1 的方式为节点命名,以指示该节点属于哪个集群(主集群或备用集群)。

  • 不支持集群内应用数据的灾难恢复;

  • 两个集群之间需要稳定的网络连接,以确保可靠的 etcd 同步;

  • 如果集群基于异构架构(例如 x86 和 ARM),请使用双架构安装包;

  • 以下 namespace 不参与 etcd 同步。如果在这些 namespace 中创建资源,用户必须手动备份:

    cpaas-system
    cert-manager
    default
    global-credentials
    cpaas-system-global-credentials
    kube-ovn
    kube-public
    kube-system
    nsx-system
    cpaas-solution
    kube-node-lease
    kubevirt
    nativestor-system
    operators
  • 如果两个集群都配置为使用内置镜像仓库,则容器镜像必须分别上传到两个集群;

  • 如果主集群部署了 DevOps Eventing v3(knative-operator)及其实例,则备用集群中必须预先部署相同组件。

流程概览

  1. 准备一个统一的平台访问域名;
  2. 将域名指向 主集群 的 VIP,并安装 主集群
  3. 临时将 DNS 解析切换到备用 VIP,以安装备用集群;
  4. 主集群 的 ETCD 加密密钥复制到后续将作为备用集群控制平面节点的节点上;
  5. 安装并启用 etcd Synchronizer
  6. 验证同步状态并进行例行检查;
  7. 发生故障时,将 DNS 切换到备用集群以完成灾难恢复。

所需资源

  • 一个统一域名,作为 Platform Access Address,以及用于在该域名上提供 HTTPS 服务的 TLS 证书和私钥;
  • 每个集群各自一个专用虚拟 IP 地址——主集群一个,备用集群一个;

网络要求

统一域名是灾难恢复的前提。在正常运行期间,该域名仅解析到 主集群 的 VIP。备用集群使用该域名访问主集群上的平台服务。

在安装任一集群之前,请完成以下两项网络准备:

  • 配置每个集群的负载均衡器,将其 VIP 上所需的 TCP 端口转发到该 VIP 后面的控制平面节点。仅在用户通过 HTTP 访问平台时才配置端口 80
  • 在主集群和备用集群网络之间的 双向 放行所需 TCP 端口。请将规则应用到防火墙、安全组、路由器 ACL 以及任何其他站点间网络控制策略。
TCP 端口服务为何需要
443 平台 HTTPS备用集群使用平台访问地址连接到活动平台。 etcd Synchronizer 使用此地址,日志和监控组件也会向其发送告警回调。
80 平台 HTTP仅在用户通过 HTTP 访问平台时需要。其余情况下的连接要求与端口 443 相同。
6443Kubernetes API server在安装或重新安装 etcd Synchronizer 期间,备用集群会连接活动集群的 API server,以获取同步所需的 etcd CA 材料。
11443内置镜像仓库备用集群通过平台访问地址配置的仓库拉取平台和插件镜像。
2379etcd备用集群上的 etcd Synchronizer 从主集群读取 etcd 数据并将其写入本地备用 etcd。

之所以要求网络策略为双向,是因为故障切换后集群角色会反转。在故障切换前,实际生效的服务流量通常从备用集群流向主集群。故障切换后,原主集群会成为新的备用集群,并且必须通过相同端口访问新的主集群。此要求并不意味着 etcd 复制是双向的: etcd Synchronizer 仅运行在当前备用集群上,并将同步数据写入其本地 etcd。

操作步骤

步骤 1:安装主集群

安装 DR(Disaster Recovery Environment)时的注意事项

在安装 DR 环境的主集群时,

  • 首先,记录在安装 Web UI 指引过程中设置的所有参数。安装备用集群时,需要保持其中一些选项一致。
  • 必须预先配置 User-provisioned 负载均衡器,以便将流量路由到虚拟 IP。Self-built VIP 选项不可用。
  • Platform Access Address 字段必须填写域名,而 Cluster Endpoint 必须填写虚拟 IP 地址。
  • 两个集群都必须配置为使用 An Existing Certificate(且必须是同一个证书);如有必要,请申请合法证书。Self-signed Certificate 选项不可用。
  • Image Repository 设置为 Platform Deployment 时,UsernamePassword 字段都不能为空;IP/Domain 字段必须设置为用作 Platform Access Address 的域名。
  • Platform Access AddressHTTP PortHTTPS Port 字段必须分别为 80 和 443。
  • 在安装指南第二页(步骤:Advanced)中,Other Platform Access Addresses 字段必须包含当前集群的虚拟 IP。

请参阅以下文档完成安装:

步骤 2:安装备用集群

  1. 临时将域名指向备用集群的 VIP;

  2. 登录 主集群 的第一个控制平面节点,并将 etcd 加密配置复制到所有备用集群控制平面节点:

    # Assume the primary cluster control plane nodes are 1.1.1.1, 2.2.2.2 & 3.3.3.3
    # and the standby cluster control plane nodes are 4.4.4.4, 5.5.5.5 & 6.6.6.6
    for i in 4.4.4.4 5.5.5.5 6.6.6.6  # Replace with standby cluster control plane node IPs
    do
      ssh "<user>@$i" "sudo mkdir -p /etc/kubernetes/"
      scp /etc/kubernetes/encryption-provider.conf "<user>@$i:/tmp/encryption-provider.conf"
      ssh "<user>@$i" "sudo install -o root -g root -m 600 /tmp/encryption-provider.conf /etc/kubernetes/encryption-provider.conf && rm -f /tmp/encryption-provider.conf"
    done
  3. 以与主集群相同的方式安装备用集群

安装备用集群时的注意事项

在安装 DR 环境的备用集群时, 以下选项必须与 主集群 保持一致:

  • Platform Access Address 字段。
  • Certificate 的所有字段。
  • Image Repository 的所有字段。
  • 重要:请确保镜像仓库以及 管理员用户的凭据与 主集群 上设置的一致。

并且务必确保你已遵循步骤 1 中的 安装 DR(Disaster Recovery Environment)时的注意事项

请参阅以下文档完成安装:

步骤 3:启用 etcd 同步

  1. 在安装插件之前,从活动 global 集群获取用于访问活动 global 集群 API server 的 bearer token。复制命令输出,并在备用 global 集群的 cpaas-system namespace 下创建 etcd-sync-active-cluster-token Secret 时使用。该 Secret 会将令牌存储在数据键 token 中。

    # Run this command on the active cluster.
    kubectl -n cpaas-system get secret k8sadmin -o jsonpath='{.data.token}' | base64 -d

    复制输出值,然后在备用集群上运行此命令:

    ACTIVE_CLUSTER_TOKEN='<paste-the-token-from-the-active-cluster>'
    kubectl -n cpaas-system create secret generic etcd-sync-active-cluster-token \
      --from-literal=token="${ACTIVE_CLUSTER_TOKEN}" \
      --dry-run=client -o yaml | kubectl apply -f -
  2. 如适用,配置负载均衡器将端口 2379 转发到对应集群的控制平面节点。仅支持 TCP 模式;不支持 L7 转发。

    INFO

    不要求通过负载均衡器进行端口转发。 如果备用集群可以直接访问活动 global 集群,请通过 Active Global Cluster ETCD Endpoints 指定 etcd 地址。

  3. 使用备用集群的 VIP 访问 备用 global 集群 Web Console,并切换到 管理员 视图。

  4. 导航到 Marketplace > Cluster Plugins,选择 global 集群。

  5. 找到 etcd Synchronizer,点击 Install,并配置以下参数:

    • Active Global Cluster VIP 设置为活动 global 集群的 VIP。
    • 当未通过负载均衡器转发端口 2379 时,请正确配置 Active Global Cluster ETCD Endpoints
    • Standby Cluster ETCD Endpoints 设置为备用集群的 etcd 地址。除非本地 etcd 服务通过不同端点暴露,否则请使用默认值。
    • Active Global Cluster Token Secret 设置为 etcd-sync-active-cluster-token
    • 使用 Data Check Interval 的默认值。
    • 除非需要排障,否则保持禁用 Print detail logs

在安装过程中,系统会在 etcd-sync Deployment 启动之前先运行 etcd-sync-bootstrap Job。只有当该 Job 准备好 remote-etcd-caremote-etcd-issuerremote-etcd-client 后,插件安装才会继续。

验证 bootstrap Job 和运行时资源:

kubectl get job -n cpaas-system etcd-sync-bootstrap
kubectl logs -n cpaas-system job/etcd-sync-bootstrap
kubectl get secret -n cpaas-system remote-etcd-ca
kubectl get issuer -n cpaas-system remote-etcd-issuer
kubectl get certificate -n cpaas-system remote-etcd-client
kubectl get secret -n cpaas-system remote-etcd-client

验证同步 Pod 是否已在备用集群上运行,并确认当前 leader:

kubectl get po -n cpaas-system -l app=etcd-sync
kubectl get lease -n cpaas-system etcd-sync-mirror
leader_pod=$(kubectl get lease -n cpaas-system etcd-sync-mirror -o jsonpath='{.spec.holderIdentity}')
kubectl logs -n cpaas-system "$leader_pod" | grep -E "Acquired leader lease|Start Sync update"

如果需要重新同步依赖 ownerReference 的资源,请在出现 Start Sync update 后重新创建当前 leader Pod:

leader_pod=$(kubectl get lease -n cpaas-system etcd-sync-mirror -o jsonpath='{.spec.holderIdentity}')
kubectl delete po -n cpaas-system "$leader_pod"

检查同步状态:

mirror_svc=$(kubectl get svc -n cpaas-system etcd-sync-monitor -o jsonpath='{.spec.clusterIP}')
ipv6_regex="^[0-9a-fA-F:]+$"
if [[ $mirror_svc =~ $ipv6_regex ]]; then
  mirror_host="[$mirror_svc]"
else
  mirror_host="$mirror_svc"
fi
curl -g "http://${mirror_host}/check"

输出说明:

  • LOCAL ETCD missed keys:这些键存在于主集群中,但在备用集群中缺失。通常由同步期间资源顺序导致的 GC 引起。重启当前 etcd-sync leader Pod 即可修复;
  • LOCAL ETCD surplus keys:这些多余键仅存在于备用集群中。请在从备用集群删除这些键之前先与运维团队确认。

如果安装了以下组件,请重启其服务:

  • Log Storage for Elasticsearch:

    kubectl delete po -n cpaas-system -l service_name=cpaas-elasticsearch
  • Monitoring for VictoriaMetrics:

    kubectl delete po -n cpaas-system -l 'service_name in (alertmanager,vmselect,vminsert)'

灾难恢复过程

卸载 Alauda Container Platform etcd Synchronizer 之前验证主/备用一致性

本操作会卸载 etcd Synchronizer。在卸载之前,请确认备用集群数据与主集群一致。如果在备用集群缺少主集群拥有的数据时卸载插件,可能会导致 owner reference 解析错误,并且业务集群节点 Machine 对象——包括不可变操作系统集群在内,在这些场景下其背后的虚拟机将被销毁——可能会被删除。如果一致性检查报告存在缺失键或多余键,请不要卸载插件;应先解决不一致问题,或联系技术支持。

  1. 如有必要,先在备用集群上重启 Elasticsearch:

    # Copy installer/res/packaged-scripts/for-upgrade/ensure-asm-template.sh to /root:
    # DO NOT skip this step
    
    # switch to the root user if necessary
    sudo -i
    
    # check whether the Log Storage for Elasticsearch is installed on global cluster
    _es_pods=$(kubectl get po -n cpaas-system | grep cpaas-elasticsearch | awk '{print $1}')
    if [[ -n "${_es_pods}" ]]; then
        # In case the script returned the 401 error, restart Elasticsearch
        # then execute the script to check the cluster again
        bash /root/ensure-asm-template.sh
    
        # Restart Elasticsearch
        xargs -r -t -- kubectl delete po -n cpaas-system <<< "${_es_pods}"
    fi
  2. 验证备用集群中的数据一致性(与 步骤 3 中的检查相同)。如果检查报告存在缺失键或多余键,说明备用集群与主集群不一致:不要继续下一步。应先解决不一致问题,或联系技术支持。在 两个 集群上,还要确认没有任何 Machine 节点处于非运行状态;继续之前先处理所有异常节点:

    kubectl get machines.platform.tkestack.io
  3. 卸载 etcd Synchronizer

  4. 移除两个 VIP 上的端口转发 2379

  5. 将平台域名的 DNS 切换到备用 VIP,此时该 VIP 将成为主集群;

  6. 验证 DNS 解析:

    kubectl exec -it -n cpaas-system deployments/sentry -- nslookup <platform access domain>
    # If not resolved correctly, restart coredns Pods and retry until success
  7. 清除浏览器缓存并访问平台页面,确认其显示的是原备用集群;

  8. 重启以下服务(如果已安装):

    • Log Storage for Elasticsearch:

      kubectl delete po -n cpaas-system -l service_name=cpaas-elasticsearch
    • Monitoring for VictoriaMetrics:

      kubectl delete po -n cpaas-system -l 'service_name in (alertmanager,vmselect,vminsert)'
    • cluster-transformer:

      kubectl delete po -n cpaas-system -l service_name=cluster-transformer
  9. 如果业务集群向主集群发送监控数据,请在业务集群中重启 warlock:

    kubectl delete po -n cpaas-system -l service_name=warlock
  10. 在原主集群上,重复 启用 etcd 同步 中的步骤,将其转换为新的备用集群。

例行检查

定期检查备用集群上的同步状态:

mirror_svc=$(kubectl get svc -n cpaas-system etcd-sync-monitor -o jsonpath='{.spec.clusterIP}')
ipv6_regex="^[0-9a-fA-F:]+$"
if [[ $mirror_svc =~ $ipv6_regex ]]; then
  mirror_host="[$mirror_svc]"
else
  mirror_host="$mirror_svc"
fi
curl -g "http://${mirror_host}/check"

如果存在缺失键或多余键,请根据输出中的说明进行处理。

上架软件包

有关 violet push 子命令的详细信息,请参阅 上架软件包