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

Daniel Alexander Parkes, Anthony D'Atri

第 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-00192.168.122.12
  • ceph-node-01192.168.122.179
  • ceph-node-02192.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.12
  • 192.168.122.179
  • 192.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 对社区的支持,为我们提供时间来创建这些帖子。