第二部分:使用 CoreDNS 和虚拟主机风格的 Bucket 访问实现无缝 DNS 路由


第 2 部分:使用 CoreDNS 和虚拟主机风格的存储桶访问实现无缝 DNS 路由 ¶
注意:本文档描述的功能预计将在即将发布的 Tentacle 版本中提供。
在 第 1 部分 中,我们为动态、感知健康的 S3 入站流量奠定了基础,方法是在 Ceph 集群内部署每个节点的 Ingress HAProxy 集中器,并将其与 Consul 集成,以进行实时服务注册和健康监控。每个节点现在都充当独立的入站点,Consul 会持续跟踪它们的可用性。
什么是 CoreDNS? ¶
CoreDNS 是一个灵活且可扩展的 DNS 服务器,用 Go 编写,并在云原生环境中被广泛采用。它是 Kubernetes(包括 OpenShift)中的默认 DNS 服务,它基于 Pod 和服务元数据处理动态服务解析。
CoreDNS 可以提供传统的 DNS 区域文件,充当转发器,执行 DNS 重写,甚至可以与外部源集成,包括 etcd、Consul 和 Vault。
在我们的例子中,CoreDNS 是标准 DNS 客户端和 Consul 的感知服务的 DNS 后端之间的桥梁。

CoreDNS 解决的问题 ¶
如果没有 CoreDNS,尝试解析 s3.cephlab.com 的客户端需要
- 知道
.consul作为 DNS 顶级域名 (TLD) - 通过端口 8600 与 Consul 通信(许多库和解析器不支持)
- 接受与他们请求的主机名不匹配的 DNS 响应(破坏 S3 风格的虚拟主机访问)
CoreDNS 可以干净地解决这个问题,方法是
- 监听 53 端口,因此客户端无需更改其 DNS 设置
- 将特定域名(如
s3.cephlab.com)转发到 Consul 的 TCP 端口8600 - 重写查询和响应,使其与 S3 SDK 的期望兼容
例如,查询 mybucket.s3.cephlab.com 的客户端将被透明地定向到 Consul 服务 ingress-rgw-s3.service.consul,并且响应将被重写回 mybucket.s3.cephlab.com,从而保留 DNS 验证,包括 AWS CLI 或 SDK 等工具。
启用虚拟主机风格的存储桶访问 ¶
许多 S3 兼容的工具和 SDK 使用 虚拟主机风格的寻址,其中存储桶名称出现在主机名中
GET https://mybucket.s3.cephlab.com
而不是
GET https://s3.cephlab.com/mybucket
这对于 S3 V4 签名尤其重要,这些签名包括签名计算中的主机名。如果 DNS 响应与请求的名称不完全匹配,则身份验证可能会失败。
我们的 CoreDNS 配置通过 DNS 重写规则处理此问题,将 *.s3.cephlab.com 映射到 Consul 服务 ingress-rgw-s3.service.consul,反之亦然,用于响应。这可以在所有健康的节点上启用虚拟主机风格的访问,而无需在客户端进行额外的配置。
使用每节点 CoreDNS 容器实现高可用性 ¶
正如我们对 Consul 所做的那样,我们将 CoreDNS 运行在相同的三个 Ceph 节点上
ceph-node-00→192.168.122.12ceph-node-01→192.168.122.179ceph-node-02→192.168.122.94
每个节点通过 cephadm 运行一个 CoreDNS 容器。这些服务
- 监听 53 端口(标准 DNS)
- 从区域文件提供
cephlab.com区域 - 将
*.s3.cephlab.com查询转发到 Consul 的 TCP 端口 8600 - 透明地处理 DNS 重写
有了这个设置,DNS 解析仍然是分布式和高度可用的。任何 Ceph 节点都可以本地解析 S3 存储桶名称并将客户端路由到 Consul 中注册的健康的入站端点。
通过存根区域与企业 DNS 集成 ¶
在企业环境中,s3.cephlab.com 不太可能是根 DNS 域名。更有可能的是,Active Directory、BIND、Infoblox 或云 DNS 提供商管理您的主 DNS。
为了使 CoreDNS 成为该生态系统的一部分,我们配置企业 DNS 将 s3.cephlab.com 子域委托给我们的 CoreDNS 节点。这通常使用存根区域或条件转发来完成。
例如
负责 cephlab.com 的权威 DNS 服务器将 s3.cephlab.com 委托给
192.168.122.12192.168.122.179192.168.122.94
一旦完成此委托,所有对 *.s3.cephlab.com 的客户端查询都将由 CoreDNS 处理,CoreDNS 会将其透明地映射到 Consul 中注册的健康的入站节点。
这允许企业客户端受益于动态、感知健康的 DNS 负载平衡,而无需在每个客户端上运行 Consul 或修改他们的 DNS 解析器。
CoreDNS 文件结构 ¶
在 CoreDNS 将要运行的每个节点上,我们将有两个文件:用于配置的 Corefile 和用于静态区域的 cephlab.com
/etc/coredns/Corefile
/etc/coredns/cephlab.com
CoreDNS 配置位于 /etc/coredns/Corefile。例如,我们正在转发到公共解析器 8.8.8.8,但您可以将您的上游企业 DNS 配置在此处进行内部解析。
.:53 {
log
errors
forward . 8.8.8.8
}
cephlab.com {
file /etc/coredns/cephlab.com
prometheus
errors
log
debug
}
consul {
forward . 192.168.122.12:8600 192.168.122.179:8600 192.168.122.94:8600
log
errors
}
s3.cephlab.com {
rewrite stop {
name exact s3.cephlab.com ingress-rgw-s3.service.consul.
answer name ingress-rgw-s3.service.consul. s3.cephlab.com.
}
rewrite stop {
name regex (.*)\.s3\.cephlab\.com ingress-rgw-s3.service.consul.
answer auto
}
forward . 192.168.122.12:8600 192.168.122.179:8600 192.168.122.94:8600
log
errors
debug
}
与此示例无关,但这里还有一个静态文件用于管理 ``cephlab.com` 区域
$ORIGIN cephlab.com.
@ 3600 IN SOA ns.cephlab.com. admin.cephlab.com. (
2017042745 ; serial
7200 ; refresh
3600 ; retry
1209600 ; expire
3600 ; minimum
)
3600 IN NS ns.example.com.
ns.cephlab.com IN A 127.0.0.1
ceph-node-00 IN A 192.168.122.12
ceph-node-01 IN A 192.168.122.179
ceph-node-02 IN A 192.168.122.94
将文件复制到其他节点,因为我们希望运行三个 CoreDNS 实例以实现 HA
for i in 00 01 02 ; do scp -pr /etc/coredns/* ceph-node-$i:/etc/coredns ; done
通过 cephadm 自定义容器功能部署 CoreDNS。这是 Coredns 容器的示例规范
# core-dns.yaml
service_type: container
service_id: coredns
placement:
hosts:
- ceph-node-00
- ceph-node-01
- ceph-node-02
spec:
image: docker.io/coredns/coredns:latest
entrypoint: '["/coredns", "-conf", "/etc/coredns/Corefile"]'
args:
- "--net=host"
ports:
- 53
bind_mounts:
- ['type=bind','source=/etc/coredns/Corefile','destination=/etc/coredns/Corefile', 'ro=false']
应用 cephadm 规范并检查服务是否已成功启动
$ ceph orch apply -i core-dns.yaml
$ ceph orch ps --daemon_type container | grep core
container.coredns.ceph-node-00 ceph-node-00 *:53,53 running (25h) 7m ago 25h 13.8M - <unknown> 0392ee038903 feaa8305273a
container.coredns.ceph-node-01 ceph-node-01 *:53,53 running (24h) 10m ago 24h 12.0M - <unknown> 0392ee038903 c86ee93dab60
container.coredns.ceph-node-02 ceph-node-02 *:53,53 running (24h) 10m ago 24h 12.1M - <unknown> 0392ee038903 06b73ad257ca
验证基于 DNS 的负载平衡 ¶
有了 CoreDNS 和 Consul,您的 DNS 查询对于 s3.cephlab.com(或任何存储桶风格的子域,如 bucket1.s3.cephlab.com)现在应该动态解析为仅健康的 Ceph 节点。这些节点中的每一个都运行本地 HAProxy 集中器,该集中器将流量路由到该节点上的本地 Ceph 对象网关 (RGW) 守护程序。
让我们逐步了解如何验证 DNS 是否正常工作以及负载平衡客户端请求是否符合预期。
步骤 1:使用 dig 解析 S3 端点 ¶
在我们的客户端节点上,我们将配置 DNS 服务器与运行 CoreDNS 的三个 Ceph 节点的 IP 地址
$ cat /etc/resolv.conf
Generated by NetworkManager
nameserver 192.168.122.12
nameserver 192.168.122.179
nameserver 192.168.122.94
我们将首先使用 dig 直接查询您的 Ceph 节点上运行的一个 CoreDNS 服务器。这将确认 DNS 重写正在工作,并且 Consul 注册的服务 ingress-rgw-s3 正在返回健康的 IP 地址。
$ dig @192.168.122.12 s3.cephlab.com
;; ANSWER SECTION:
s3.cephlab.com. 0 IN A 192.168.122.179
s3.cephlab.com. 0 IN A 192.168.122.12
s3.cephlab.com. 0 IN A 192.168.122.94
$ getent hosts test.s3.cephlab.com
192.168.122.12 test.s3.cephlab.com
192.168.122.94 test.s3.cephlab.com
192.168.122.179 test.s3.cephlab.com
这表明 DNS 正在解析为三个健康的节点,基于当前的 Consul 健康检查。getent hosts 查询系统解析器,该解析器指向监听 53 端口的 CoreDNS。
这确认虚拟主机风格的 DNS 解析正在工作。查询通过 CoreDNS 解析,CoreDNS 将 test.s3.cephlab.com 重写为 ingress-rgw-s3 Consul 服务,该服务返回仅健康的端点。
步骤 2:检查负载平衡分布 ¶
为了验证负载平衡是否在健康的节点上正常工作,让我们执行 100 次连续查询,并计算哪个 IP 地址最常返回。这是测试跨您的入站点 DNS 级别分布有效性的简单方法。
$ for i in {1..100}; do getent hosts s3.cephlab.com | awk '{print $1}' | head -n1; done | sort | uniq -c | sort -nr
37 192.168.122.179
34 192.168.122.94
29 192.168.122.12
这显示了三个 Ceph 节点之间的相当均匀的分布,表明 CoreDNS(由 Consul 提供支持)正在提供轮询结果,并且系统解析器正在以平衡的方式使用这些结果。
这确认了
DNS 查询返回仅健康的节点
负载平衡在节点之间正常工作
您的 CoreDNS + Consul 设置正在动态且智能地路由流量
使用 S3 客户端和 RGW Ops 日志验证请求分布 ¶
现在我们已经确认 DNS 基于解析级别的工作,是时候验证实际的 S3 操作是否正在跨 Ceph 对象网关 (RGW) 端点分发,如预期的那样。
为此,我们将启用 RGW Ops 日志,该日志提供有关传入 S3 请求的详细信息,包括处理每个请求的 RGW 守护程序。然后我们将使用 AWS CLI 运行一些 S3 操作并检查日志,以查看使用了哪些 RGW。
这种方法使我们能够具体了解 CoreDNS 和 Consul 如何影响实际客户端流量。
步骤 1:在 Ceph 中启用 Ops 日志 ¶
要捕获 S3 操作,请启用 RGW ops 日志并确保它们写入文件。可以使用 ceph config CLI 直接应用这些设置
$ ceph config set client.rgw rgw_enable_ops_log true
$ ceph config set client.rgw rgw_ops_log_rados false
$ ceph config set global log_to_file true
$ ceph config set global mon_cluster_log_to_file true
$ ceph orch restart client.rgw
步骤 2:运行一些 S3 操作 ¶
使用 AWS CLI(或任何兼容的 S3 客户端)通过负载平衡的端点列出您的存储桶并上传一个对象
$ aws --profile test --endpoint http://s3.cephlab.com:8080 s3 ls
$ aws --profile test --endpoint http://s3.cephlab.com:8080 s3 ls
$ aws --profile test --endpoint http://s3.cephlab.com:8080 s3 cp /etc/hosts s3://bucket1/
这些请求将通过 CoreDNS 和 Consul 路由到健康的入站节点,并由 HAProxy 转发到该节点上的本地 Ceph 对象网关 (RGW) 守护程序之一。
步骤 3:检查 Ops 日志 ¶
每个 RGW 守护程序都有自己的 opslog 文件。您可以启用仪表板集中式日志记录。在我们的例子中,我们使用脚本将日志集中到一个节点上。这是输出
2025-08-19T11:44:19.296500Z 192.168.122.12 list_buckets GET / HTTP/1.1 ceph-node-00-RGW5
2025-08-19T11:47:29.213482Z 192.168.122.12 list_buckets GET / HTTP/1.1 ceph-node-00-RGW6
2025-08-19T12:50:32.375753Z 192.168.122.12 put_obj PUT /bucket1/hosts HTTP/1.1 ceph-node-00-RGW5
HAProxy 在
ceph-node-00(192.168.122.12) 上接收到请求。负载在
rgw5` 和rgw6`` 之间分发,这两个对象网关守护程序正在该节点上本地运行。PUT 操作确认对象上传也通过动态 DNS 路径路由。
模拟节点故障并观察动态恢复 ¶
有了 Consul 和 CoreDNS,我们的基于 DNS 的负载平衡现在可以感知服务健康。让我们测试当入站节点发生故障时,系统如何表现,以及流量如何自动重新路由到剩余的健康节点,而无需手动干预。
此场景验证了
- Consul 健康检查正在主动监控入站服务。
- DNS 答案仅包含健康的节点。
- 客户端继续访问 S3 兼容的服务而不会中断。
- 节点恢复会触发自动重新集成到 DNS。

我们将通过超融合管理器(在本例中为 kcli)停止 Ceph 节点来模拟故障,但行为在任何实际的 BM 故障场景中都相同,无论是由于硬件、电源还是维护造成的。
步骤 1:模拟入站节点故障 ¶
让我们停止 ceph-node-00,它当前托管 HAProxy 和 Ceph 对象网关 (RGW) 守护程序。
$ kcli stop vm ceph-node-00
这立即将节点从网络中移除。Consul 将通过其失败的健康检查检测到丢失的服务。
几秒钟后,我们可以验证 CoreDNS(由 Consul 提供支持)不再将其 DNS 响应中包含 ceph-node-00。
$ getent hosts s3.cephlab.com
192.168.122.179 s3.cephlab.com
192.168.122.94 s3.cephlab.com
正如预期的那样,192.168.122.12 (ceph-node-00) 不再返回,因为其 HAProxy 健康检查失败并且 Consul 取消了其注册。
步骤 2:继续访问 S3 ¶
现在让我们执行一个正常的 S3 操作,使用相同的负载平衡端点。尽管一个节点已关闭,但流量应该透明地路由到健康的节点。
$ aws --profile test --endpoint http://s3.cephlab.com:8080 s3 ls
步骤 3:检查哪个 RGW 处理了请求 ¶
我们可以现在检查 RGW ops 日志,以查看哪个节点处理了 S3 请求。示例 ops 日志输出
2025-08-19T15:24:54.179558Z 192.168.122.94 list_buckets GET / HTTP/1.1 ceph-node-02-RGW1
2025-08-19T15:27:03.889488Z 192.168.122.94 list_buckets GET / HTTP/1.1 ceph-node-02-RGW1
正如我们所看到的,请求现在路由到 ceph-node-02,它是健康的并且正在运行其本地 HAProxy 和 RGW 服务。
步骤 4:恢复故障节点 ¶
现在让我们恢复 ceph-node-00 并验证它是否自动重新加入集群并进入 DNS 响应。
$ kcli start vm ceph-node-00
Consul 将在健康检查通过后重新注册本地入站服务。几秒钟后,让我们重新运行 DNS 查询
$ getent hosts s3.cephlab.com
192.168.122.94 s3.cephlab.com
192.168.122.12 s3.cephlab.com
192.168.122.179 s3.cephlab.com
一切正常!节点已恢复在线并健康,并自动重新集成到负载平衡池中。无需手动 DNS 更新、故障转移或集群重新配置。
结论。使用 Consul 和 CoreDNS 现代化 S3 负载平衡 ¶
随着存储环境的扩展,尤其是那些提供高吞吐量、S3 兼容工作负载的环境,传统的负载平衡方法开始显示其局限性。静态 HAProxy 堆栈和固定的 VIP 对于较小的集群是可靠的,但当处理故障域、弹性以及大规模流量分布时,它们会迅速成为运营瓶颈。
通过结合
- 每个节点的入站终结器(HAProxy 集中器)。
- Consul 用于动态、感知健康的的服务发现。
- CoreDNS 用于基于 DNS 的路由和虚拟主机存储桶支持。
我们构建了一个分布式、自愈且高度可扩展的解决方案,可以满足现代对象存储的需求。
继续阅读 第 3 部分:由 Consul 提供支持的 Ceph 对象网关 (RGW) 的全局负载平衡
作者感谢 IBM 对社区的支持,为我们提供时间来创建这些帖子。