从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 Baker、John Brzozowski、Vint Cerf、Lorenzo Colitti、Jason Fesler、Lee Howard、Pradeep Kathail、Martin Levy、Christopher Morikang、Paul Saab、Mark Townsley、Eric Vyncke、Dan Wing、Jan Zorz。