这篇文章上次修改于 475 天前,可能其部分内容已经发生变化,如有疑问可询问作者。

因近期项目K8s集群搭建需要,我给机房部署了交换机和路由器,打算给托管的几台独立服务器接上内网。
但我发现这其中存在一些比较天坑的问题。

网络具体情况

公网

公网网段是114.51.41.0/24,网关是114.51.41.1,对外能通公网

内网

内网网段是10.22.1.0/24,网关为10.22.1.1,无法连接公网

踩坑

问题详情

我一开始给Netplan的配置是这样的
94092-suqcfw452dc.png
在apply这个配置之后,我发现公网SSH断开了,同时icmp回包存在断断续续丢包的情况:
86847-pzh8kb230jk.png
我一开始以为是机房网络被攻击了,但技术排查之后发现内网链路居然是通的....
然后
28378-98twavy2nv7.png

原因分析

来说说这个配置的问题所在,它看上去没有问题,但实际上它同时允许了两个网关存在,这导致Kernel Route同时存在两个对外的default路由:
64460-9q14nkog2e.png
当存在两个优先级相等的Kernel Route的时候,系统转发就会出问题,无论是入网还是出网的数据包都会出现错乱,这就是本次问题的原因所在。

解决问题

所以分析到这里,解决问题的思路已经很清晰了————采用某种方法屏蔽、删除指向内网网关的Kernel Route,即可解决此问题。
我一开始想到了两种方案

方案一

其实解决问题最快的方法就是直接删除这条Kernel Route:

route del -net default gw 10.22.1.1

这种方法固然有效
但如果重启呢?
如果重装系统呢?
难道以后遇到问题都要这么解决?
难道需要将这条命令挂载到开机的时候去执行?
显然这种方法并不是那么优雅,我们需要更加优雅的方法来解决这一问题。

方案二

还有一种方法是直接对netplan的配置下手,直接在netplan配置里给网卡安排明白路由,配置如下:

network:
  ethernets:
    eno3:
      addresses:
        - 114.51.41.9/24
      routes:
      - to: 0.0.0.0/0
        via: 114.51.41.1
        metric: 300
      gateway4: 114.51.41.1
      nameservers:
        addresses:
        - 114.114.114.114
    eno4:
      addresses:
      - 10.22.1.2/24
      routes:
      - to: 10.22.1.0/24
        via: 10.22.1.1
        metric: 0
      gatewat4: 10.22.1.1
      nameservers:
        addresses:
        - 114.114.114.114
  version: 2

此处相当于直接给网卡规定路由,以代替network service自动配置gateway4为default kernel route。

总结

这个问题根本上是由于对网络概念理解不深,错误配置网络所造成的。
值得注意的是,如果采用我在文章开头发的那个配置,其实netplan apply之后并不会马上出事,而是在你reboot之后才会发作,这时候如果没有办法物理介入的话就麻烦了,所以建议各位多花点钱,养成给机器配置IPMI的好习惯。