使用 Openvswitch Agent 的分布式 DNS 转发器

RFE: https://bugs.launchpad.net/neutron/+bug/2112446

Neutron DHCP 代理(使用 dnsmasq)可以充当 DNS 转发器,或通过在运行 DHCP 代理的主机上配置的解析器为实例提供 DNS 解析。但是,当用户部署与 Open vSwitch (OVS) 代理一起使用的分布式 DHCP 时,他们有责任确保实例可以访问 DNS 服务器,或者设置自己的转发机制。

本文档描述了如何为 Neutron openvswitch 代理实现一个 DNS 转发器扩展,通过利用 OpenFlow 规则和 os-ken 应用程序,为虚拟机提供简单、完全分布式的 DNS 转发能力。

问题描述

  • DNS 在确保数据库、VPN 集群或任何动态更新 DNS 记录(无论是在 OpenStack 内部还是通过外部系统)的故障转移场景等服务的高可用性方面发挥着关键作用。此外,DNS 解析在 OpenStack 环境中至关重要,允许位于外部或项目网络上的实例访问这些服务,即使它们没有直接到达 DNS 服务器的路径。例如,在隔离的 VXLAN 网络中运行的 Web 服务器可能需要使用内部域名连接到同一网络上由云提供商提供的数据库服务。

  • Openvswitch Agent 的分布式 DHCP 对于大规模部署来说很好,但它缺乏内置的 DNS 解析能力,不像使用 dnsmasq 的 DHCP 代理。[1]

提议的变更

将添加 Neutron openvswitch 代理的新扩展,以实现 分布式 DNS 转发器 Openvswitch Agent

注意

此扩展仅适用于 openvswitch 代理,其他机制驱动程序将不予考虑,因为此新扩展将依赖于 openflow 协议和原理。对于 OVN,它已经支持使用 ovn-controller 的类似 DNS 解析机制。

提出的解决方案

在 OVS-agent 中开发一个新的 OS-Ken 应用程序,它将充当实例和 DNS 服务器之间的中间体,因此它可以响应实例的 DNS 查询,而无需直接连接到实际的 DNS 服务器。

基本数据管道可以描述如下

                        +--------------+                +---------------------+                +---------------------+
+-------+ DNS Query     |              |    packet-in   |  +----------------+ | DNS Query      |                     |
|  VM   +--------------->  Flows       +---------------->  |   os-ken app   | +---------------->   Local resolvers   |
|       <---------------+ (capture     <----------------+  |                | <----------------+        or           |
+-------+ DNS Answer    | DNS query    |    packet-out  |  | DNS Forwarder  | | DNS Answer     |   Real DNS servers  |
                        |   here)      |                |  +----------------+ |                |                     |
                        |   br-int     |                |      OVS-agent      |                |                     |
                        +--------------+                +---------------------+                +---------------------+

之后我们将得到

  • 比 DHCP 代理中的 dnsmasq 的 DNS 解析具有更高的可用性。

  • 具有分布式 DHCP 扩展的 OpenStack [1] 现在可以支持 DNS 查找。

  • 与 Openvswitch Agent 的分布式元数据数据路径的绝佳组合 [2]

DNS 转发器

我们将从数据包中提取 DNS 有效负载,然后将其发送到上游 DNS 服务器。

服务器端变更

OpenvSwitch Agent 侧的更改

对于 Neutron openvswitch 代理,我们将添加一个新的代理扩展,它将处理任何 DNS 查询的基本流安装。

将存在一些基本流,它们将检查 DNS 查询是否与目标匹配,然后将其提交到控制器。默认目标是 169.254.169.254:53[fd00::254]:53。我们将使其可配置。

table=60, priority=102,udp,nw_dst=169.254.169.254,tp_dst=53 actions=CONTROLLER:0
table=60, priority=102,udp6,nw_dst=fd00::254,tp_dst=53 actions=CONTROLLER:0

对于 openvswitch 代理的新扩展,它将注册一个本地 packet_in_handler,它将执行以下工作

  • 监听 EventOFPPacketIn 事件

  • 验证每个数据包是否与上述规则匹配

  • 从数据包中提取 DNS 有效负载

  • 将 DNS 有效负载发送到上游 DNS 服务器

  • 组装 DNS 答案响应并 send_msgin_port

响应 DNS 答案数据包的结构将是

+------------------------------------------+
|           *Source Mac Address            |
|   169.254.169.254/fd00::254 MAC Address  |
+------------------------------------------+
|       *Destination Mac Address           |
|        Neutron Port Mac Address          |
+------------------------------------------+
|           *Source IP Address             |
|        169.254.169.254/fd00::254         |
+------------------------------------------+
|         *Destination IP address          |
|             Neutron Port IP              |
+------------------------------------------+
  • Mac 地址 将是 169.254.169.254/fd00::254 MAC 地址。

  • 目标 Mac 地址 将是端口的 MAC 地址。

  • IP 地址 将是 169.254.169.254/fd00::254

  • 目标 IP 地址 将是端口 IP(v4/v6) 地址。

注意

与通常依赖于广播数据包的 DHCP 请求不同,此解决方案更像元数据服务,需要通过某个地方发送 DNS 查询数据包到 169.254.169.254/fd00::254。这些数据包将在 br-int 桥上捕获。DHCP 代理、分布式 DHCP 或通过 cloud-init 可以提供必要的路由。此外,指定的下一跳必须可达,这意味着实例应该能够使用 ARP 解析其 MAC 地址,并且在大多数情况下,此下一跳是默认网关。

潜在的配置

将为 neutron openvswitch 代理添加一个新的扩展别名 dns_forwarder

[agent]
extensions = ...,dns_forwarder

将为 neutron openvswitch 代理添加配置节 [dns_forwarder] 并注册一些常用选项

dns_forwarder_opts = [
  cfg.ListOpt('upstream_dns_server_ports',
              default=['1.1.1.1:53', '[2606:4700:4700::1111]:53'],
              help=_('Comma-separated list of the Upstream DNS server
                     'in ip:port format which will be used as resolvers.')),
  cfg.IntOpt('upstream_dns_query_timeout', default=5,
             help=_("Query timeout in seconds for each Upstream DNS servers")),
  cfg.ListOpt('client_dns_server_ports',
              default=['169.254.169.254:53', '[fd00::254]:53'],
              help=_('Comma-separated list of the Client DNS server
                     'in ip:port format which will be used inside client instances.')),
]

数据模型影响

REST API 影响

升级

此功能不会影响任何当前功能,因此我们只需启用它即可使用。

实现

负责人

主要负责人

工作项

  • 实现一个新的 DNS Responder OS-Ken 应用程序。

  • 实现一些新的配置选项。

  • 实现相关的单元和功能测试。

  • 编写文档。

测试

  • 单元/功能测试。

文档

  • 用户文档:如何使用 OVS 设置内部 DNS 解析。

参考资料