LinkedIn 内部的 IPv6 第三部:不容忽视的问题

阅读数:794 2016 年 12 月 12 日

话题:语言 & 开发架构

从 2014 年起,LinkedIn 网站一直面向公众提供 IPv6,他们的雇员已经用 IPv6 来冲浪很久了。在本系列的第一部分中,我们解释了为什么决定将公司内部网络升级到 IPv6;在第二部分中,介绍了我们所面临的挑战,为了在一天的时间完全移除 IPv4,我们在数据中心开始启用双栈。在最后一部分中,介绍了如何部署和管理纯 IPv6 网络上的服务器或者其他设备,以及从软件工程角度看待 IPv6。我们还没有建好纯 IPv6 的数据中心,但这篇文章描述了纯 IPv6 数据中心的施工进展。

IPv6 的大型部署

个人或者小团队可以手动安装、配置和管理有限数量的设备(如服务器、交换机,路由器等)。但是在任何大型网络中,由于涉及到成百上千个设备,变得更加复杂,您就会希望开始自动化执行这些功能。这是扩大基础设施的一个维度。随着团队的发展,越来越多的人在相同设备上做同样的工作,所以有必要确保知识传播、变化综述等的工具,这是另一维度的扩展。

在大规模部署时,有几个因素必须考虑,包括:

  • 配置
  • 管理
  • 监控
  • 停运

下面介绍了一些我们在 IPv6 环境中执行上述功能的能力缺陷。为了使讨论更加具体,这些主题,都是围绕我们体验过的软件,它们有已知的公开错误报告的参考文献。我们要感谢所有的合作伙伴和社区帮助解决这些差距。

配置

当构建大型服务器网络时,其间通常会涉及多个不同的团队。数据中心技术人员敷设机架、电缆等设备,而网络和系统工程师配置并使它们在网络上运行。

您希望手动流程和接触点尽可能少:在理想情况下,您手动构建一个路由器和一个服务器,所有其他网络设备和服务器将从这两个设备自动安装和配置。这称为零接触配置(Zero Touch Provisioning,ZTP)。为了完全自动化,当设备上电时,它需要知道未被配置,在网络上查找其配置,然后安装自身。

在网络端,对于裸机交换机,有诸如开放网络安装环境(ONIE)的协议。在服务器端,有诸如 Preboot eXecution Environment(PXE)之类的协议。这两种技术以类似的方式起作用。如果设备没有配置,它将获得一个 IP 地址(通常通过 DHCP),然后通过 DHCP 选项使用 TFTP 下载一个小的内核映像文件(Image)或脚本,这个脚本用来通过复杂协议如 HTTP 以配置文件来执行检索更完善和更全的内核映像文件,然后可以进行设备安装和配置。此引导功能是硬件的一部分,位于主板和网卡的固件中。由于固件空间有限,TFTP 客户端是优先的,因为它简单、微小。但是 TFTP 可能无法与今天的大型操作系统映像一道很好地工作,部分原因在于它使用 UDP,与 TCP 不同,UDP 不是为可靠性而设计。为此,首先加载小的内核映像文件,然后使用更完善但更复杂的协议,如 HTTP,来下载较大的映像文件。

为了成功建立双栈环境,上面提到的 IPv4 进程需要在 IPv6 上执行同样的工作,甚至工作得更好。然而,向固件添加第二网络栈可能会超过固件的存储容量。要解决这个问题,传统的 BIOS 正在被 UEFI(Unified Extensible Firmware Interface,统一的可扩展固件接口)取代,这是当下更好的框架。然而,UEFI 相对较新,只有最近的版本才支持 IPv6。在较旧或当前的设备刷入较新的固件是很复杂的事,会造成停机。事实上,它经常会使设备变砖。由于这个原因,理想的情况是,硬件已经内置支持 UEFI 和 IPv6 的新固件。因此,通过 IPv6 进行引导的功能,只能在内置了最新固件、开箱可用的新服务器上使用。

在纯 IPv6 网络中,UEFI 网络引导只能使用 autoconfig 获取 IPv6 地址,而不能使用 DHCPv6。如果你不控制服务器所使用的协议(在 IPv4 中,设备通过 DHCP 获取 IP 地址,基于集中式 DHCP 配置中设置的某些规则),可能需要更改配置架构。目前已发现一些 TFTP 客户端使用 IPv6 受到限制,仅能够访问本地或者 IPv6 内网(/64 网络内)的文件,这意味着不能从不同的网络检索到映像文件,并且设备不能从全球的其他数据中心启动开机。

由于所有这些原因,在纯 IPv6 网络中,配置网络服务器(或网络设备)并非易事。用于选择正确的设备和网卡的选项是有限的。设备仍然可以通过 IPv4 进行配置,然后在纯 IPv6 环境中运行,但这涉及到运行多 IP 传输栈(Multiple IP Transport Stacks)。因此,当从双栈数据中心迁移到纯 IPv6 的数据中心时,确保设备在纯 IPv6 中可以配置非常重要。否则,IPv4 网络必须保留以便可以重新安装设备。

我们目前正与供应商合作,在纯 IPv6 测试服务器配置。任何感兴趣的人,在一天内运行纯 IPv6 环境时,应与供应商一起检查,因为硬件生命周期至少为三年,并且可能希望在这段时间内迁移到纯 IPv6 环境中。

UEFI 网络引导 IPv6

在超微(Supermicro)上使用新的网络固件,我们能够使用 grub2 通过 IPv6 进行 UEFI 网络启动。 这是我们的做法。

我们首先使用以下选项设置 DHCPv6 服务器:

option dhcp6.bootfile-url "tftp://[2001:DB8::245]/bootx64.efi";

我们在 [2001:DB8 :: 245] 上设置了 TFTP 和 raddvd 服务器。当通过 IPv6 引导时,UEFI 网络引导接收 DHCPv6 选项并通过 TFTP 下载 bootx64.efi 并执行它。我们尝试通过 IPv6 在网络上加载 Linux 和 initrd,使用带 grub2.02-beta2 的 HTTP 或 TFTP;但是,下载无法执行。Grub 需要在 IPv6 上进行更多的开发,以使其与在 IPv4 上具有相同的功能。

为了解决这个问题,所需的一切都被打包成一个 memdisk,包含在 bootx64.efi 里;Grub2 只需要链接这个映像文件(Linux + initrd)。

创建 memdisk:

mkdir -p memdisk/boot/grub/x86_64-efi/
cp /usr/lib/grub/x86_64-efi/*.mod
memdisk/boot/grub/x86_64-efi/
cp /usr/lib/grub/x86_64-efi/*.o
memdisk/boot/grub/x86_64-efi/
cp /usr/lib/grub/x86_64-efi/*.lst
memdisk/boot/grub/x86_64-efi/
cp /usr/lib/grub/x86_64-efi/*.sh
memdisk/boot/grub/x86_64-efi/
cp /boot/vmlinuz memdisk/boot/
cp /boot/initrd.img memdisk/boot/

创建 memdisk/boot/grub/grub.cfg:

set timeout=5
menuentry 'Linux diskless' --class os {
 insmod all_video
 set gfxpayload=keep
 insmod net
 insmod efinet
 insmod tftp
 insmod http
 insmod gzio
 insmod part_gpt
 insmod efi_gop
 insmod efi_uga
 insmod ext2

 # dhcp, tftp server in my network
 set net_default_server=2001:DB8::245

 # auto dhcp setup did not work for me, no idea why
 # net_bootp
 # ok let's assign a static address for now
 net_ipv6_autoconf
 echo 'Network status: '
 net_ls_cards
 net_ls_addr
 net_ls_routes

 echo 'Loading Linux ...'
 linux /boot/vmlinuz rd_NO_LUKS rd_NO_LVM rd_NO_MD rd_NO_DM ramdisk_size=100000 rdblacklist=qla2xxx ksdevice=bootif lang= text ip=dhcp6 ks=http://[2001:DB8::245]/repo/cfg/KS1.cfg

 echo 'Loading initial ramdisk ...'
 initrd /boot/initrd.img

然后打包:

cd memdisk
tar cf memdisk.tar *

创建映像文件:

# grub2-mkimage --directory '/usr/lib/grub/x86_64-efi' --prefix '(memdisk)/boot/grub' --output 'bootx64.efi' --format 'x86_64-efi' --compression 'auto'  --memdisk 'memdisk/memdisk.tar' 'memdisk' 'tar' 

bootx86.efi 映像文件相对较大,在我们的示例中大约为 42M,主要是因为我们的 initrd.img 就这么大。毋庸置言,TFTP 并非下载大文件的最佳工具,因为它依赖 UDP 而非 TCP(TCP 内置更多的纠错机制)。虽然根据 UEFI 规范应该是可能的,但是我们还没有成功地将 HTTP 用于 UEFI 通过 IPv6 的网络引导。到目前为止,这个工作正常——TFTP 是一个可行的解决方案。

在此配置中,UEFI 将下载映像,chainload 到 memdisk 中的 vmlinuz(无需使用 Grub 从网络中单独下载),并且此内核将与 kickstart 服务器联系并开始配置服务器。

虚拟 IP(VIPs)任播(Anycast)

虽然许多负载平衡器支持 IPv6,但我们为了提高可扩展性,采用了与可用选项不同的方法。我们通过在本地接口上添加 IP 在服务器上配置 VIPs,通过 BGP 会话使用 bird 和 bird6 向连接的交换机通告这些 IP。因为这是内部网络,我们可以选择通告网络的聚合级别:对于 IPv4 为 /24,对于 IPv6 为 /128。但是,您需要非常小心,因为一些网络设备可能不能容纳超过 /128 前缀的 128 个路由,因此它可能是一个更好的策略,保留一个完整的 /64 甚至一个 IPv6 地址用作任播。通过消除服务器与负载均衡器在同一网段中的要求,就赋予我们更大的灵活性。

我们使用 CFEngine 配置虚拟 IP 任播,我们不得不修改一些 RedHat 的网络脚本,使配置在 IPv4 和 IPv6 上类似。这在 CFEngine 一节中有描述。

管理

IPMI

IPMI(Intelligent Platform Management Interface,智能平台管理接口)是非常重要的部分,它能够在出现显著影响之前检测硬件问题,或者在操作系统关闭时也能够查询机器状态。

IPMI 是在不安装操作系统的情况下访问服务器的标准。它允许管理员在服务器启动时远程控制和查看屏幕,例如,当服务器启动时,监测各种硬件组件(如硬盘驱动器)的运行状况。该接入可以是“带外(out of band)”或“边带(side band)”。“带外”意味着为该管理保留一个接口,并且处于其所在的网络中。在“边带”设计中,相同的物理接口用于单独网络中的正常网络流量和管理。

由于管理可能在安装任何操作系统之前发生,因此 IPMI 必须能够在纯 IPv6 网络上自动配置。稍后,一旦安装了操作系统,服务器上的 ipmitools 将允许用户查询和设置硬件组件。

从 2015 年 5 月发行的版本 1.8.14起,Linux 上的 Ipmitool 支持 IPv6。然而,它仍然需要找到一些 Linux 发行版。例如 RedHat 7 中还没有正确的版本,因此我们需要创建自己的版本。

此外,您需要一个具有适当固件的网卡来支持 IPMI IPv6 扩展。这样的网卡也可能能够通过 IPv6 进行 UEFI 和 PXE。我们一直与供应商测试分布式管理任务组(Distributed Management Task Force)指定的 Redfish 兼容固件。

对于长期支持,管理员可能必须将当前运行的 Linux 版本更新为支持的完整 IPv6 支持版本 ; 这可能有下游影响,更不用说刷固件的困难。

CFEngine

管理服务器的另一方面是能够配置它们。有很多工具可用:Chef、Puppet、Foreman 等。我们使用 CFEngine。虽然 CFEngine 通过 IPv6 工作,但若尚未配置 IPV6 时,该软件内置了支持 IPv4 的功能。我们创建了一个 CFEngine 模块,它将从主机收集 IPv6 信息,并允许将其提供给我们想要的任何 CFEngine 序列。该模块为我们节省了大量的时间来配置 IPv6 服务器,设置网络接口,创建正确的 iptables,使用 IPv6 支持更新软件配置文件等。

我们使用的自动化方法很大程度上依赖于 Linux 虚拟接口。这需要我们在 Linux 上修补网络脚本,使其可以由 CFE 管理。难点在于接口上的其他 IP 地址。对于 IPv4,是通过配置的虚拟接口处理;而对于 IPv6,这只是一个包含所有附加 IP 的变量。我们的补丁允许在 IPv6 中使用虚拟接口。我们对 RedHat 的修改进行了考虑。

CFE 的 IPv6 支持的跟踪在这里,在支持问题中描述微小错误。CFE 开发人员报告说,该软件在纯 IPv6 环境中工作。对我们来说,它在双栈环境下工作良好,我们看到 IPv6 流量,但我们还没有验证它确实在纯 IPv6 环境下工作。我们一直与 CFE 开发人员密切合作,提供对我们的经验反馈,他们非常热烈——其中一些反馈将很快应用到未来版本,所以如果我们发现任何问题,相信他们将及时处理。

其他配置系统对 IPv6 具有各种级别的支持。重要的是在现实环境中测试它们并提供反馈,使每个系统总是持续改进。

监控和指标

多年来,我们已经建立了自己的监控和警报服务,称为 inGraphs 和 AutoAlerts,可以参考此处来了解。

此软件为各种收集器提供了从服务器、网络设备、应用程序或服务获取指标并将此信息以图形化呈现。如果数据不符合预期(硬盘驱动器已满、CPU 使用率、接口上流量过多、对服务的请求过多等),此过程也可能生成警报。 我们监控每个设备的许多指标,以便我们在以每天和每周为周期来了解趋势,而且,当情况变槽之前及时通知我们。这些指标还可用于事后分析。

inGraphs 和 AutoAlerts 只是一个框架,用于我们部署脚本,探测有助于衡量运营和服务之间的差异,无论是在 IPv4 或 IPv6。任何组织都会这样做,并在自己的监视系统中构建新的图形化警报,以便在服务期间,根据协议栈不同表现进行通知。

当我们从纯 IPv4 转换到双栈环境,最终转向纯 IPv6 时,我们需要有指标标准,以便我们能够了解服务在 IPv4 和 IPv6 上是否正常运行。我们是否能够观察到延迟,每秒查询等方面的差异吗?虽然我们可能不会对产品本身进行更改,但这意味着具有收集检查 IPv4 和 IPv6 性能所需的数据的工具和工具。例如,我们发现一些网络设备可能提供 IP、ICMP、TCP 或 UDP 的流量故障,但它们不告诉我们 IPv4 和 IPv6 流量之间的分割。这是一个非常重要的度量标准,用于衡量进度及成功的指标,且当移除 IPv4 时至关重要。

像 LinkedIn 这样的大公司不进行测量许多指标,就不能迁移到 IPv6,测量指标可以了解发现的问题是否是由于实施 IPv4 和 IPv6 之间的差异。有时变化并不显著,有时它们在百分比方面非常小,但仍然很重要,例如 4 亿成员的 0.1%仍然是 40 万成员。

停运

最终你需要停运机器。这需要从操作中删除它们,擦除数据,从网络中删除它们,最后解开它们。在纯 IPv6 环境中,软件需要能够在纯 IPv6 网络上执行这些操作。

早日规划如何停运,并同时仍然保证机器的供应,将在未来给您带来帮助。这是我们在 IPv4 上实施的,正在寻找如何在纯 IPv6 环境中执行的方案。

不容忽视的软件支持

有许多软件需要支持 IPv6。 在许多组织中大量部署的设备和软件可以与 Hadoop 网格的部署相关。我们将以Hadoop为例(因为这通常涉及在许多组织中大量部署设备),但是还要考虑其他软件和策略。

Hadoop

许多大公司必须存储和分析大数据。今天使用的常用系统之一是 Hadoop。这通常需要大量的服务器来进行数据存储和计算。目前 Hadoop 不支持 IPv6。社区已经创建了一个开发分支,以获得 IPv6 支持,一旦这个分支测试完毕,它将被合并回主分支。这是 Hadoop 社区在添加新功能时惯用的工作方式。它为功能和主要分支提供了一个安全的开发环境。

Facebook 工程师一直在努力为 Hadoop 添加 IPv6 支持,我们正在研究如何参与这项工作。该项目进展顺利。这是所有参与 Hadoop 项目最棒的工作,但不用说,像所有开源项目一样,我们相信社区总是欢迎更多的帮助。

一旦 Hadoop 支持 IPV6,我们就可以轻松地在许多组织中部署大型的纯 IPv6 机器,为每个组织节省数百万个 IPv4 地址。

我们期待能够测试支持 IPv6 的 Hadoop,并报告和帮助修复我们发现的 bug。

其他软件

许多工具和软件需要修改以便处理 IPv6 及其数据结构。对于常规套接字连接,有几个策略要考虑。默认情况下,操作系统将返回主机名(IPv4 或 IPv6)的首选 IP 地址。当设备在其一个接口上具有全局 IPv6 地址时,此首选项通常为 IPv6。但是,可以为了始终优先使用 IPv4 而更改此首选项。另一个策略是获取主机名的所有地址,并以不同于操作系统的方式在软件中处理它们。例如,Java 有几个标志设置,以便您可以通过 IPv6 启用连接。更多的示例,您可以在这里找到一个关于 Python 和 sockets 的优秀教程。

这只是一个例子,说明还有一些软件还没有准备好应用于 IPv6。在操作系统中禁用 IPv6 仍然是此软件中针对 IPv6 支持的任何问题的常见解决方案! 很可惜,因为这样无助于解决真正的问题。

在某些情况下,可以依赖外部第三方的任务,而不是固定所需的软件以使用 IPv6,您可以在其周围提供包装器或代理。例如,Apache 在代理模式或 Nginx 都已广泛用作 IPv6 前端到纯 IPv4 的后端。这是很多已经提供 IPv6 连接的网站。这也可以用于内部站点,使人们更熟悉 IPv6 并在内部增加 IPv6 流量,从而增加可见性,以便人们知道为 IPv4 编程不再是唯一选择。

为 IPv6 准备应用程序

ARIN(The American Registry for Internet Numbers,美国互联网号码注册管理机构)已经发布了如何确保开发人员制定网络无关代码的相关文档

下一步

路漫漫其修远兮,我们正处在完全支持所有设备和软件的前沿。不再有不受 IPv6 影响的任何领域,也不再是只有少数人才认识到它的重要性。

迁移所有的软件通过 IPv6 连接,是我们接下来几个月的任务。我们还将在提供设备的方式上继续工作,一旦完成,就是开始处理 IPv4 的时间。

致谢

在这一部分中,我们要感谢一些提供帮助的外部人员。还有很多人我们需要感谢,如果我们遗漏或者忘记姓名,请接收我们的道歉:Fred BakerJohn BrzozowskiVint Cerf、Lorenzo Colitti、Jason FeslerLee HowardPradeep KathailMartin LevyChristopher MorikangPaul SaabMark TownsleyEric VynckeDan WingJan Zorz


感谢陈兴璐对本文的审校。

给 InfoQ 中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ@丁晓昀),微信(微信号:InfoQChina)关注我们。