Ceph 对象存储多站点复制系列。第四部分

Daniel Parkes, Anthony D'Atri (IBM)

IBM Storage Ceph 对象存储多站点复制系列

在系列之前的文章中,我们讨论了为客户端和复制请求配置专用 RGW 服务。 此外,我们还探讨了同步公平性功能提供的性能增强。 在本系列第四篇文章中,我们将讨论如何通过在各个 RGW 服务之间分配请求来负载均衡我们新部署的 RGW S3 端点,从而提供高可用性和提高性能。

负载均衡 RGW S3 端点

简介

在上一期中,我们配置了四个 RGW 实例:两个专用于客户端 S3 API 请求,其余用于多站点复制请求。 借助此配置,客户端可以单独连接到每个 RGW 端点以使用 HTTP restful S3 API。 例如,他们可以使用其中一个运行 RGW 服务的节点的 IP/FQDN 作为端点来发出 S3 调用,例如 LIST。

这是一个使用 AWS s3 客户端的示例:$ aws –endpoint https://ceph-node02 s3 ls。 他们将能够访问他们的存储桶和数据。

问题是,如果 ceph-node02 宕机了会发生什么? 即使其余 RGW 服务在幸存的节点上正常运行,用户也会开始收到错误消息和失败的请求。 为了避免这种行为,提供高可用性和提高性能,我们需要在 RGW 服务前面配置负载均衡器。 由于 RGW 端点使用 HTTP 协议,因此我们有多种众所周知的解决方案来负载均衡 HTTP 请求。 这些包括基于硬件的商业解决方案以及开源软件负载均衡器。 我们需要找到一种能够满足我们的性能需求的解决方案,具体取决于我们部署的大小和特定要求。 Kyle Bader 在这个 github 仓库 中提供了一些关于不同 RadosGW 负载均衡机制的优秀示例。

站点间复制网络

每个站点的网络基础设施必须提供充足的带宽以支持复制对象或纠删编码对象分片的读取和写入。 我们建议每个站点的网络结构具有零 (1:1) 或最小的超订阅率(例如,2:1)。 叶脊拓扑是 Ceph 集群部署中最常用的网络拓扑之一,因为它能够提供所需的可扩展性。

参与同一区域组的区域之间的网络将用于异步复制流量。 站点间带宽必须等于或大于引入吞吐量,以防止同步滞后增加并增加数据丢失的风险。 站点间网络不会用于读取流量或对象的重构,因为所有对象在本地都是持久的。 建议站点间网络具有路径多样性,因为我们通常谈论的是广域网连接。 站点间网络应使用路由 (L3) 而不是交换 (L2 扩展 VLAN) 以便在每个站点提供独立的网络堆栈。 最后,即使我们在实验室示例中没有这样做,Ceph 对象网关同步也应配置为使用 HTTPS 端点通过 SSL/TLS 加密复制流量,以用于生产环境。

Ingress 服务概述

从 Pacific 版本开始,Ceph 提供了一个名为 ingress 的 cephadm 服务,它提供了一个易于部署的 HA 和负载均衡堆栈,基于 Keepalived 和 HAproxy。

Ingress 服务允许您为 RGW 创建一个高可用性端点,只需最少的配置选项。 编排器将部署和管理 HAproxy 和 Keepalived 的组合,以平衡配置的浮动虚拟 IP 上的负载。

有多个主机部署了 Ingress 服务。 每个主机都有一个 HAproxy 守护程序和一个 keepalived 守护程序。

默认情况下,Keepalived 会在其中一个主机上自动配置单个虚拟 IP 地址。 拥有单个 VIP 意味着负载均衡器的所有流量都将通过单个主机流动。 这对于配置服务大量客户端请求并保持高吞吐量的配置来说不太理想。 我们建议为每个 Ingress 节点配置一个 VIP 地址。 然后,例如,我们可以配置跨所有部署的 VIP 的轮询 DNS,以在所有 VIP 上负载均衡请求。 这提供了实现更高吞吐量的可能性,因为我们正在使用多个主机来在配置的 RGW 服务之间负载均衡客户端 HTTP 请求。 根据部署的大小和要求,Ingress 服务可能不够充分,可以使用其他更具可扩展性的解决方案来平衡请求,例如 BGP + ECMP。

部署 Ingress 服务

在本篇文章中,我们将配置 Ingress 负载均衡服务,以便在 zone1 中运行在节点 ceph-node-02ceph-node-03 上,以及在 zone2 中运行在节点 ceph-node-06ceph-node-07 上的公共面向 RGW 服务上负载均衡 S3 客户端 HTTP 请求。

在下图中,我们以高级别描绘了我们添加到先前部署的架构中的新的负载均衡器组件。 这样,我们将为 S3 客户端请求提供 HA 和负载均衡。

第一步是像往常一样创建一个 cephadm 服务规范文件。 在这种情况下,服务类型将是 ingress。 我们指定现有的公共 RGW 服务名称 rgw.client-traffic 以及 service_idbackend_service 参数。 我们可以使用 cephadm orch ls 命令获取 cephadm 服务的名称。

我们将为每个 Ingress 服务守护程序配置一个 VIP,并使用每个 Ceph 集群的 VIP 来管理两个节点。 我们将为客户端连接在 Ingress 服务处启用 SSL/HTTPS。

[root@ceph-node-00 ~]# ceph orch ls | grep rgw
rgw.client-traffic         ?:8000           2/2  4m ago     3d   count-per-host:1;label:rgw
rgw.multisite.zone1        ?:8000           2/2  9m ago     3d   count-per-host:1;label:rgwsync

[root@ceph-node-00 ~]# cat << EOF >  rgw-ingress.yaml
service_type: ingress
service_id: rgw.client-traffic
placement:
  hosts:
    - ceph-node-02.cephlab.com
    - ceph-node-03.cephlab.com
spec:
  backend_service: rgw.client-traffic
  virtual_ips_list:
  - 192.168.122.150/24
  - 192.168.122.151/24
  frontend_port: 443
  monitor_port:  1967
  ssl_cert: |
    -----BEGIN CERTIFICATE-----
    -----END CERTIFICATE-----

    -----BEGIN CERTIFICATE-----
    -----END CERTIFICATE-----
    -----BEGIN PRIVATE KEY-----
    -----END PRIVATE KEY-----
EOF


[root@ceph-node-00 ~]# ceph orch apply -i rgw-ingress.yaml
Scheduled ingress.rgw.client update...

注意:Ingress 服务从我们添加到 ssl_cert 列表中的所有证书构建一个名为 HAproxy.pem 的单个证书文件。 为了使证书正常工作,HAproxy 需要您按以下顺序添加证书:首先是 cert.pem,然后是链式证书,最后是私钥。

很快我们就可以在 ceph-node-[02/03] 上看到我们正在运行的 HAproxy 和 Keepalived 服务

[root@ceph-node-00 ~]# ceph orch ps | grep -i client
haproxy.rgw.client.ceph-node-02.icdlxn     ceph-node-02.cephlab.com  *:443,1967             running (3d)     9m ago   3d    8904k        -  2.4.22-f8e3218    0d25561e922f  9e3bc0e21b4b
haproxy.rgw.client.ceph-node-03.rupwfe     ceph-node-03.cephlab.com  *:443,1967             running (3d)     9m ago   3d    9042k        -  2.4.22-f8e3218    0d25561e922f  63cf75019c35
keepalived.rgw.client.ceph-node-02.wvtzsr  ceph-node-02.cephlab.com                        running (3d)     9m ago   3d    1774k        -  2.2.8             6926947c161f  031802fc4bcd
keepalived.rgw.client.ceph-node-03.rxqqio  ceph-node-03.cephlab.com                        running (3d)     9m ago   3d    1778k        -  2.2.8             6926947c161f  3d7539b1ab0f

您可以从容器内部检查 HAproxy 的配置:它正在使用静态轮询负载均衡在两个配置为后端的客户端面向 RGW 之间进行负载均衡。 前端监听端口 443,我们的证书位于路径 /var/lib/haproxy/haproxy.pem

[root@ceph-node-02 ~]# podman exec -it ceph-haproxy-rgw-client-ceph-node-02-jpnuri cat /var/lib/haproxy/haproxy.cfg | grep -A 15 "frontend frontend"
frontend frontend
    bind *:443 ssl crt /var/lib/haproxy/haproxy.pem
    default_backend backend

backend backend
    option forwardfor
    balance static-rr
    option httpchk HEAD / HTTP/1.0
    server rgw.client-traffic.ceph-node-02.yntfqb 192.168.122.94:8000 check weight 100
    server rgw.client-traffic.ceph-node-03.enzkpy 192.168.122.180:8000 check weight 100

对于本示例,我们使用 CoreDNS 插件配置了基本的 DNS 轮询。 我们正在解析 s3.zone1.cephlab.com 到所有配置的 Ingress VIP。 正如以下示例所示,对 s3.zone1.cephlab.com 的每个请求都会解析为不同的 Ingress VIP。

[root@ceph-node-00 ~]# ping -c 1 s3.zone1.cephlab.com
PING s3.cephlab.com (192.168.122.150) 56(84) bytes of data.
[root@ceph-node-00 ~]# ping -c 1 s3.zone1.cephlab.com
PING s3.cephlab.com (192.168.122.151) 56(84) bytes of data.

现在您可以将 S3 客户端指向 s3.zone1.cephlab.com 以访问 RGW S3 API 端点。

[root@ceph-node-00 ~]# aws --endpoint https://s3.zone1.cephlab.com:443 s3 ls
2024-01-04 13:44:00 firstbucket

此时,我们已经为 zone1 配置了高可用性和负载均衡。 如果我们失去一个运行 RGW 服务的服务器,客户端请求将被重定向到剩余的 RGW 服务。

我们需要对托管 zone2 的第二个 Ceph 集群执行相同的步骤,最终每个区域都有一个负载均衡的端点

s3.zone1.cephlab.com
s3.zone2.cephlab.com

作为最后一步,我们可以部署一个全局负载均衡器 (GLB)。 这不是 Ceph 解决方案的一部分,应由第三方提供;有许多可用的 DNS 全局负载均衡器,它们实现了各种负载均衡策略。

由于我们在站点负载均衡器中使用 SSL/TLS,如果我们要配置 GLB,我们需要实施 TLS 直通或重新加密客户端连接,以便连接将从客户端加密到站点负载均衡器。 使用 GLB 具有显著的优势

  • 利用 Ceph 对象存储复制的活动/活动特性,您可以为用户提供单个 S3 端点 FQDN,然后在负载均衡器上应用策略,将用户请求发送到站点之一或另一个站点。 例如,负载均衡器可以将客户端重定向到离他们位置最近的 S3 端点。

  • 如果您需要主动/被动灾难恢复方法,GLB 可以增强故障转移。 用户将拥有一个要使用的单个 S3 端点 FQDN。 在正常操作期间,他们将始终被重定向到主站点。 如果站点发生故障,GLB 将检测主站点的故障,并透明地将用户重定向到辅助站点,从而增强用户体验并缩短故障转移时间。

在下图中,我们提供了一个示例,其中添加了一个具有 FQDN s3.cephlab.com 的 GLB。 客户端连接到 s3.cephlab.com,并将根据 GLB 级别的应用策略重定向到站点之一或另一个站点

我们是否应该为 RGW 复制端点使用负载均衡器?

在共享的负载均衡 Ingress 服务示例中,我们配置了 S3 客户端端点的负载均衡,因此客户端 HTTP 请求在可用的 RGW 服务之间分配。 我们尚未讨论为多站点同步请求提供服务的 RGW。 在我们之前的文章中,我们配置了两个 RGW 专用于多站点同步操作。 如果我们没有配置 Ingress 服务或外部负载均衡器,我们如何跨这两个 RGW 负载均衡同步请求?

RGW 在区域组和区域端点级别实施轮询。 我们可以配置逗号分隔的 RGW 服务 IP 地址或主机名列表。 RGW 服务代码将在列表中的条目之间负载均衡请求。

我们 multizg 区域组的复制端点

[root@ceph-node-00 ~]# radosgw-admin zonegroup get | jq .endpoints
[
  "http://ceph-node-04.cephlab.com:8000",
  "http://ceph-node-05.cephlab.com:8000"
]

我们 zone1 和 zone2 区域的复制端点。

[root@ceph-node-00 ~]# radosgw-admin zonegroup get | jq .zones[].endpoints
[
  "http://ceph-node-00.cephlab.com:8000",
  "http://ceph-node-01.cephlab.com:8000"
]
[
  "http://ceph-node-04.cephlab.com:8000",
  "http://ceph-node-05.cephlab.com:8000"
]

我们可以采用另一种方法,使用多站点同步端点的负载均衡器。 例如,一个专用的 Ingress 服务或任何其他 HTTP 负载均衡器。 如果我们采取这种方法,我们只需要在区域组和区域端点列表中有一个 FQDN。

哪种解决方案更好,专用负载均衡器还是 RGW 在提供的端点列表中进行轮询?

这取决于……如果负载均衡器能够提供至少与配置的专用 RGW 服务的轮询相同的吞吐量,则外部负载均衡器可能会更好。 例如,如果我们的外部负载均衡器是运行在单个 VM 上的 HAproxy,具有单个 VIP 和有限的网络吞吐量,那么我们最好使用 RGW 轮询复制端点列表选项。 对于 2024 年初合并的 PR 之后的版本,我会说这两种选择都可以。 您需要在仅设置端点列表的简单性之间进行权衡,RGW 管理器模块会自动完成此操作,以及全功能负载均衡器可以提供的更高级功能。

总结与下一步

在本系列的第四部分中,我们讨论了与负载均衡我们的 RGW S3 端点相关的一切。 我们涵盖了多种负载均衡技术,包括捆绑的 Ceph0提供的负载均衡器,Ingress 服务。 在第五部分中,我们将详细介绍新的同步策略功能,该功能使用粒度和灵活的同步策略方案提供对象多站点复制。

脚注

作者谨此感谢 IBM 对社区的支持,通过促使我们有时间创建这些帖子。