10G 网络升级(服务器端 bonding)

本次升级最大的"意外"之一就是关于服务器 bonding 的问题,归根到底还是在升级之前文档看的不够充分,调研的不够仔细。下面会对其做一个比较全面的分析。
说到 bonding,最重要的问题之一就是模式的选择,这个是要根据各自不同业务来选择的,切勿人云亦云,我整理了一份表格,说明每一种模式的一些特性以及交换机对其的支持情况。

选哪个模式最合适?很明显,正常情况下,mode4 是一个比较好的选择,但是需要注意的是端对端尤其是交换机 active/on 选择,对于服务器来说,稍微有点繁杂,需要根据网口的情况来分:

  • 四口的,如果有内外网,没有问题
  • 两口的,如果仅仅有内网或者公网,也没有问题
  • 两口的,如果既要有内网又要有公网,很明显,还缺少两个端口,这时候在 Linux 上做 VLAN  的价值就体现出来了

确认完模式,接下来就是 bonding 的安装,bonding 这个 module 默认应该都是随发型版本加载的,可以在 /etc/modprobe.d/ 目录下面加载;接下来就是修改网卡对应的配置了,各个不同的发型版本大同小异,这里分别给一个 Ubuntu 以及 RHEL 的范例。这两个主流发型版本的 bonding 的配置还是比较灵活的,除了可以在 /etc/modprobe.d/ 里面指定 bonding 的各种参数之外,还可以在 network-scripts/ 以及 interface 里面指定,比如可以在 ifcfg-bond0 里面指定 bonding opts:
# cat /etc/sysconfig/network-scripts/ifcfg-bond0
DEVICE=bond0

BONDING_OPTS="mode=4 miimon=100"

跟 bonding 有关的几个实时文件分别在 /proc/net/bonding/:
# cat /proc/net/bonding/bond0

以及 /sys/class/net/ 下面:
# cat /sys/class/net/bonding_masters
bond0

# cat /sys/class/net/bond0/bonding/mode
balance-alb 6

# cat /sys/class/net/bond0/address
99:11:11:11:dd:dd

要让 bonding 生效,我认为最 KISS 的办法还是直接重启机器,尽管可以通过 ifenslave 或者在加载完 bonding 之后直接在 /sys/(/sys/class/net/ 下面) 里面 "on the fly"。官方的建议是通过 iproute2(ip link set eth0 master bond0) 或者 sysfs 修改生效,ifenslave 会被逐渐抛弃。
在启动的时候,注意查看系统的 /var/log/messages,这个文件里面能看到很多跟 bonding 相关的信息。

对于 bonding 一对或者多对网卡的监控,可以二选一:
1. miimon
2. arp_interval 以及 arp_ip_target
不用任何监控的弊端之一就是一个网卡挂了无法及时的切换到另外一块网卡上,这个明显是不容许的。
对于 ARP 的监控方式,一般用在兼容 etherchannel 的模式里面,也就是交换机会将流量分散到多条链路上;如果是以 XOR 的方式(单条链路)则不可行。除此之外,ARP 的方式不可以跟 miimon 同时使用。
对于 miimon 来说,有 downdelay, updelay, user_carrier 几个参数比较重要。
如果想使用 balance-xor 或者 802.3ad,还需要了解下 xmit_hash_policy 以便更好的平衡流量。

既然是端到端的系统,除了要考虑服务器方面的 bonding 状态,也要考虑对端 FEX 的支持情况,在上篇已经说过,主流的 2k 跟 5k 的接法无外乎 single-homed 也就是一台 2k 仅连接一台 5k 或者是 dual-homed 也就是一台 2k 同时连接两台 5k。其中前者的 topo 支持 2k 的到服务器的 vPC、FCOE 以及 static pinning,而后者是不可以对 2k 下挂的服务器做 vPC,单凭这一点就没什么优势了,更何况这种接法还有其他不少的缺点。

这里有一篇文章提到遇到 Orphan Port 也就是单上联的情况,这个在实际情况中还时有发生,尤其是比较早期的服务器,那时候网口的数量还不足以达到双上联的标准,对于这类情况,文中分析在 peer link 参与的情况下流量的分布以及需要注意的地方,值得看看。

还有几个需要注意的地方:
1. 路由问题,原先由 eth0 单块网卡处理的现在将由 bond0 接替处理,如果是通过 ifensalve、modprobe 等方式启动的 bonding,注意也要修改对应的路由,重启不存在这类问题。
2. SNMP 问题,需要确保 bonding  这个模块在其他的网络模块之前加载,否则 SNMP 取得的数据会有错乱。
3. 在混杂(promiscuous) 模式下,balance-rr, balance-xor, broadcast 以及 802ad 这四种模式会将混杂模式的设定会传播到所有的 slave 接口;而 active-backup, balance-tlb 以及 balance-alb 这三种则只会传播到 active 的 slave 接口。
4. duplicated 包的问题,最常见的是在初次或者闲置一段时间之后 ping 某台机器的过程中发现不少 (DUP!) 表示的包,正常现象,主要在于交换机广播的机制,最简单的方式是清空一次 MAC 转发表,Nexus 上的示例:
# clear mac address-table dynamic


update: 服务器端的注意 xmit_hash_policy 这个参数,默认值为 layer2,也就是 mac 层的 hash,在某些业务下,会出现带宽跑不满,上不去的情况,可以考虑使用 xmit_has_policy=1(layer3+4) 的组合,这个还是要根据具体的业务来定。

10G 网络升级(整体架构 & vPC)

上篇介绍了升级过程中涉及到的业务层面的内容,接下来两篇会着重总结一些技术上的实现细节。在主持此次升级之前,把《Network Warrior》上面的一部分内容过了一遍,除了介绍 752 之外,其他的章节总结的也很到位,尤其是最后的几章节,很多问题都是一针见血,强烈推荐各位看看,上面的总结只有经历过的人才会有共鸣。下面的内容也有部分是出自这本书。

Nexus 7000 使用的是 midplane 架构,跟之前的 backplane 不同,因此需要重新考虑散热问题。比如 7004 使用的是 side-rear 的方式,7018 则是 side-side 的方式。 Nexus 5000/2000 的则是从前到后或者从后到前谁前谁后,这个务必要理解清楚,否则跑了一半机器就烧了歇火了。因此需要考虑 IDC 里面的 hot/cold aisle。这里有两篇(1, 2)  比较早期的文档,专门探讨 752 的散热问题(不仅仅 752 存在这个问题,4948E 也有类似的问题),解决的办法也比较简单,花钱买套 "Nexus Airflow Extension Sleeve"。
上面谈到的是散热问题,7K 的电源模块可能会存在一些问题,默认使用的 250V,16A 的电源线,一般的插线板可能无法插入;另外功耗问题也需要考虑进去,一般的测试环境是无法满足这么大的功耗问题的,所以不管是测试还是正式上架,务必确认这些问题。

Nexus 5000 基本跟 7000 看齐,除了 U 位小些,没有冗余 supervisor 以及 VDC 这类高端功能罢了,其他的差异我认为不是很大。

Nexux 2000 严格来说,并不是交换机,只是一个 fabric extender,他有两类端口,一种叫主机端口,就是连接服务器的,默认激活了 STP BUDU Guard,一旦连上服务器便会 error-disable;另一种是 fabric 端口,用来连接 N5K/N7K,所有的 fabric 端口都是 10G 端口。

说完整体再总结几个 nexus 改进最大的地方,也就是最像 *nix 的地方(1, 2, 3)。
几乎所有的协议都已模块化的方式加载:
# show feature

所有的接口均已 Ethernet 开头,不再分 FastEthernet、GigabitEthnet,这样比较方便操作。

可以使用 tab 补全,类似 shell;除此之外多了很多 pipe,多了 grep 等过滤的工具。

管理平面、控制平面以及数据平面隔离。比如 ssh 产生的为管理流量,并不会影响数据转发的流量。管理平面挂了对生产环境并没有致命的威胁。

默认情况下,nexus 7000 所有的接口都是三层的,因此,要变成 trunk,记得加 switchport。

VDC 这个是 nexus 最大的一个卖点。本次我们没有采用 VDC 这种看上去逼格很高的技术,仔细想想,根本不适合我们的业务场景,线上全是生产环境,第一并不需要流量隔离,第二毕竟是一个虚拟技术,对整体的性能多少还是有些影响的,这个可以类比 *nix 下各种 VM 的实现,其优缺点很明显。根据业务需求选择对应的技术,而不是为了用技术而用技术,技术最终都是为业务服务的,脱离了他技术没有任何意义。

接下来会着重总结 vPC 这个比较创新的技术。在开始之前还是还有必要过一下这个 quick start 的 《Virtual PortChannel Quick Configuration Guide
vPC 这个在 752 的架构中用的很多,主要是为了增加上联的带宽减小收敛比,其次冗余也是一方面,并且他可以做到跨机箱,比传统 port-channel 要好的多。官方有两个文档,一个是《Configuring Virtual Port Channels》,另外一个是《vpc best practices design guide》  可以没事翻阅看看,都是经验总结,看完了可以少走不少弯路。

使用 vPC 最重要的是注意 consistency 的问题,这篇文档描述了这个问题。 show vpc consistency-parameters 是一个非常 handy 的命令,出了问题先通过他查看查看,很可能会发现问题的原因。如果这条命令解决不了,那就按照这个操作一步一步来吧。 《Troubleshooting Virtual Port Channel Issues

vPC 的 domain 编号跟 port channel 的编号一致,否则以后出了问题有的你受了,这是减轻你的痛苦也是减轻后来维护人员的痛苦。 另外,由于 vPC 受众多因素的影响,一点点小的改动都可能导致出现 type 1 的完全中断或者 type 2 的部分中断,因此操作包含 vPC 的机器时,需要格外小心。vPC Domain ID 问题需要注意的是,7K 上的 domain ID 不能跟 5K 上的一样,否则 port channel 会一直处于 suspend 的状态而导致 vPC 无法连接,原因可以看这里

需要注意的是,不管是 port channel 还是 vPC,都无法实现每条物理链路流量的均分。比如我们之前在 stacking 过的 3750X 上做 cross-stack,实现 port-channel。很明显的可以看到,两条物理链路的流量并不均等。


上面这个是两条 1G 的绑定,理论上,要实现流量的均分,必须是 2 条、4 条或者 8 条的绑定,但是实事情况是,即使是两条,也会出现流量不均等的情况。 默认情况下,port channel 会通过目的 mac 的方式做 LB,由此可以看到,当数据包要发往的目的地比较多的时候,才能体现 port channel 的价值。如果,发往的 mac 地址很单一,就会造成流量很集中在某一条物理链路上,后果是,即使这一条物理链路出现过载,交换机也不会自动的将一部分的流量切分到其他的空闲物理链路上。因此,是选择根据源 mac 方式还是目的 mac 亦或是其他更复杂的方式,还是需要根据业务类型来定。

要做 vPC 就离不开 Peer-Keepalive。其最重要的就是 internal 以及 timeout 的时间。前者有 400ms 到 10s 可选,默认 1s 的应该足够了。后者有 3 到 20s 可选,默认 5s。 Peer-keepalive 可以使用 management VRF 或者 default VFR。官方推荐使用前者, 也就是使用 mgmt0 的 ip 作为 src/dst 的地址;如果使用 default VFR,还要建立 SVI,没有必要。另外,两台 peer 的配置最好一样,详细情况可以看这里

接下来就是 Peer-Link,这这两有先后顺序,不要弄反,只有在对端 peer 挂了情况下,Peer-Keepalive 才会启动侦测。

最后,熟悉我们前年升级的应该会知道(1, 2, 3, 4),我们会涉及到跨机房的通信的问题。 之前是在两台 3750X 上起的 port channel,现在一方升级另一方不变,vPC 依然可以很好的胜任,对端 port channel 不变,要升级的这端起 vPC 就可以了。

10G 网络升级(业务)

前年(12年)带着一个实习在啥都缺的情况下搞定了两个模块(30+ network devices)的基础网络。今年又搞了一把,又是一个危急存亡关头(真佩服那些经历了若干危急存亡还没死掉的 startup)临危受命,这种烂摊子的事发生的次数已经记不清了,要么忍要么滚,这其实是个很简单的道理。回到正题,既然答应再干一票,索性就做好。
这次的情况是啥都缺但是不缺钱,那问题就相对好办的多,钱能解决的问题都不是问题了,本着"能交给第三方做的尽量都交由其做"的原则(也正是由于这点给后面带了很多的问题),从前期的方案制定一直到最后走线、机器上架加电都外包由他们实施,在这个过程中我们是承担了包工头的角色,一方面跟他们协商一些细节一方面是在后面盯着往前推。当然最核心的 752 的灌装还是我们的人亲自动手来做。

问题的起源之前已经解释过了,业务上来了,想挡都挡不住。最终的架构设计也是烂大街的 752,其实除了这种经典的方式之外,还有一种 766 的架构,不过不大适合我们的业务。下一篇博客会着重总结一下技术面的细方,这篇博客仅仅总结一些业务层面的内容。

在这之前我们一直有一家固定的银牌代理商,合作的还算比较愉快,但是此次升级列出的清单的价格比后来半路杀出的干爹提供的要高一大截,当然直接跟他们说拜拜了,后来发现这是一个非常正确的选择,预算倒不是主要的原因,这个问题我会单独写一篇博客谈谈商务以及采购在整个运维生命周期里面的作用。
接上文,就在跟这家银牌代理商谈的差不多的时候,我们专注于卖假货的干爹半路出世。托他的福,找了家金牌代理商,大陆就那么几家,最终的报价当然有很大的杀伤力。
前戏依然是跟一帮销售加售前的黄金组合扯皮,几次谈下来,合作的也确实比较愉快,最起码邮件的书写没有任何的问题。但是越往后越发现靠不住,全程包括一个预约非常麻烦工作行程排的非常紧的售前兼售后,典型的半吊子。不吹牛逼的说,我花一天时间熟悉下某个协议绝对不会比他差;另外就是若干围绕他转的不知名酱油工程师以及若干实施布线的工程师,布线的老大是我接触的这么多人中比较有好感的,第一次意识到一条光纤也能弯的如此的优雅,看到多少会有些震撼,他们的线是按照弯曲的度数来计算的。
后来跟销售反馈了这个问题,他们也给足了面子,准确的说是给干爹的面子,特意从杭州调了一个工程师,结果打了半天酱油,第二天就回去了。自此之后,在经历了这么多的扯皮之后,还是要说句,不管做什么还是得靠自己,尤其是一些重要的程序。
为什么绝大部分的售前都是个半吊子了?举个印象特深的例子。用百度谷歌我已经不在乎了,能解决问题并且说明原因就好。当时我做了一次 write erase 操作,从头把 752 的十来台设备灌装一遍,因为不是很熟悉,花了估计有 2h,并且很不幸的,最后 7k 跟 5k 之间的 port channel 不通,尝试了若干方法都没找到问题缘由,后来该售前通过一条条对比我的 running-config 跟他自己的 running-config 这种非常 dirty 的方式发现原来是我把 7k 跟 5k 的 domain ID 弄重合了,至于为什么不能这样,含糊其辞的解释了几句话最后来了一句你记住不能一样就好了。后来我翻了下官方文档发现上面写的很清楚,domain ID 确实不能一样。从这件事来说,确实是我对系统的认知不足导致了这个问题的发生,并且由于时间关系,我也没有一页一页的去翻官方几千页的阿拉伯字母,很多都只是看一些 quick start 之类的文档速成学习的,最终的情况就是有些问题理解的不是很透彻。我一知半解因为我的主要工作方向不在这个方面,升级这事顶多算是我的副业,况且 752 的这套架构都是我现学起来的。而对于一个专业从事 752 架构的技术支持来说不能一针见血的指出这么基本的一个问题是不是显得太业余了。这类问题我认为只要平时脱离手册操作过几遍 752,浏览过一部分的官方文档应该都能很快的解决。
所以,在这里由衷的给那些看我博客的工程师一点建议,如果想从事技术路线,尽量少跟或者不跟这类人员打交道,除了浪费时间,你基本不能学到什么有用的。我做这个接口人的角色也并非自愿,上面已经说了。

由于公司之前没有一个人对此类架构的细节熟悉,机器到了之后倒是闹出了不少的笑话,最搞笑的是 7k 由于是 250V 的电源线不适用于目前通用的插线板,前前后后换过好几次插线板以及电源线。另外,由于之前规划的非常糙粗快,导致确定最终的接口方案时,发现还缺少包括 N2K、10G 多膜在内的不少整机以及零部件,好在这类问题都得到了及时的解决。

本次升级就当公司土豪了一把,扔了百来万学费给我去现场学习一下吧。当年见到一台两三万的现在看来非常烂的 R410 还敬畏一下,现在看到这百来万的设备都是直接加电插线开搞,丝毫没有了当年的的那份激动。

推荐两个官方文档,下篇会涉及一些重要的技术细节。
官方有个很基础也很重要的 《NX-OS CLI Management Best Practices Guide》,里面包含了从 Initial Configuration 到 Software upgrade/downgrade 等主要方面的介绍。
还有个 troubleshooting 的手册,写的非常完善。建议好好读读,出现问题之后的解决问题才是体现一个普通工程师跟优秀工程师区别的时候。

另外需要注意的一点,这里的 10G 是指除接入层服务器之外的 10G,除了一些相对特殊的服务(web server, cdn 等)之外,目前 10G 的服务器还不是那么的广泛应用,因此这里的接入层服务器还都是 1G 的接入。如果想了解 10G 服务器的接入,可以参考《Nexus 5K Layout for 10Gb/s Servers》这个(1, 2, 3, 4)系列的博客。 

最后这个是我写的一个简明的 752 step by step

目前网络架构的缺陷

去年(12 年)我设计的方案在我们某一个机房跑了快一年,目前出现了很严重的性能问题。简单的讲就是交换机撑不住了,下面服务器流量稍微大点就开始丢包。当初为了节约成本的苦头终于吃到了。
我虽然不是专业搞网络的,但是一些基本的理论概念还是很清楚的,至于实践问题,看看文档,在正式上线之前把步骤都理清楚了,自然不会出什么大问题。我之前写了一个小系列的博客,纪录我们的那次升级,可以看看这里(1, 2, 3, 4) 。另外,该机房主要是用来跑 hadoop 的,数据量有多大可想而知。
说说目前存在的问题。
先说优点,当初设计的一个原则就是坚决走二层(核心、接入)的方案,而非传统的三层(核心、汇聚、接入)的方案,这个现在证明完全是正确的。首先都是内网,安全性问题可以放在后面考虑,二层扁平结构最明显的特点就是更小的收敛比,这个对于有大量数据传输的机房是很重要的;相比之下,传统的三层由于收敛比比较高,性能会收到一定的影响,比较时候园区等办公环境而不适合机房尤其是跑 hadoop 的环境。
接着是重点,缺点。目前是一台 2960S 下面挂 10 台 1G(没有做 bonding)的服务器,接入跟核心做的是 2G 的 channel。写到这里应该已经看出来了,这个收敛比还是比较大的,5:1。这个在初期还不是很明显,起初机器数量少,流量也少。但是随着机器数量的增加,情况就不一样了,每台服务器实际是跑不到 1G 的,以我们统计的图表来看,下图,平均一台 200M 左右,但是峰值基本都在 600M 左右,最终计算收敛比的话,还是以 600M 的峰值计算,最好的情况是 600M x 10 = 6G ,但是上面只有 2G 的可用带宽,不行,一种看上去行得通的办法是将 channel 进一步扩大,扩大到 6G,那就意味着一台 2960G 需要额外的 6 个端口来跟 3750X 上联,3750X 也需要由原先的 2 台扩展到 6 台。这也只能满足目前的需求,如果服务器的带宽进一步的往上跑,单台 3750X 的负载也需要进一步的加大,基本就没戏。上面这种方案并不能根本的解决问题。

所以比较根本的解决方案是直接上 N7K,下面可以考虑直接挂 N2K,或者通过先通过一层 N5K 再走 N2K,不管哪种方式,都能达到比较好的效果,收敛比达到 1:1 不在话下,并且应该能满足今后两年的需求。


要发现上面这些问题,除了通过在服务器上的监控数据采集得到的结果做分析之外,最简单的还是在上层的交换机上直接 show:

# show interfaces GigabitEthernet1/0/2
GigabitEthernet1/0/2 is up, line protocol is up (connected)

     reliability 255/255, txload 114/255, rxload 183/255

  Input queue: 0/75/0/0 (size/max/drops/flushes); Total output drops: 2696237866

# show interfaces summary
 *: interface is up
 IHQ: pkts in input hold queue     IQD: pkts dropped from input queue
 OHQ: pkts in output hold queue    OQD: pkts dropped from output queue
 RXBS: rx rate (bits/sec)          RXPS: rx rate (pkts/sec)
 TXBS: tx rate (bits/sec)          TXPS: tx rate (pkts/sec)
 TRTL: throttle count

  Interface               IHQ   IQD  OHQ   OQD  RXBS RXPS  TXBS TXPS TRTL
————————————————————————-
* GigabitEthernet1/0/2     0     0    0 2696238164 724931000  83002 441240000  65852    0  

很明显的可以看到,Gi1/0/2 不管是 txload 还是 rxload 都已经很高的,OQD 也高的惊人。

基础网络升级(四)

其实到基础网络升级(三)应该就结束了,不过在使用过程中发现内网的路由之前规划的不是很好,老机房(192.168.10.0/24)的都是从一台 NAT 上出去,当时为了省事,把新机房(192.168.20.0/24, 192.168.30.0/24)的所有流量通过路由到了老机房,然后再从那台 NAT 出去。这样造成结果就是流量比较『混乱』,一个出口也同时存在 SPOF 的问题。比较好的方式还是老的不变,新的从新机房的 NAT 上出去,这样至少有两个出口,一个挂了还有挽救的措施 ;-)
要修改的地方不是很多,老机房的 NAT(192.168.10.254)、三层设备的路由不需要变。NAT 通过 MASQUERADE 的方式出去:
# iptables -t nat -L -n
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination        

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination        
MASQUERADE  all  —  0.0.0.0/0            0.0.0.0/0          

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination        

# cat /etc/iptables
-A POSTROUTING  -o eth0 -j MASQUERADE

老三层设备的静态路由信息,默认路由是指向 NAT 的 IP:
ip classless
ip route 0.0.0.0 0.0.0.0 192.168.10.254
ip route 192.168.20.0 255.255.255.0 192.168.1.2
ip route 192.168.30.0 255.255.255.0 192.168.1.2
no ip http server
ip http secure-server
!

新 NAT 机器(192.168.20.254):
# iptables -t nat -L -n
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination        

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination        
MASQUERADE  all  —  0.0.0.0/0            0.0.0.0/0          

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination        

# cat /etc/iptables
-A POSTROUTING -o em2 -j MASQUERADE

新三层设备,默认的路由指向新 NAT 设备:
ip classless
ip route 0.0.0.0 0.0.0.0 192.168.20.254
ip route 192.168.10.0 255.255.255.0 192.168.1.1
no ip http server
ip http secure-server
!

以上只是简化的模型,实际的比这个复杂些,不过思想不变。