解决双网卡虚拟机linux无法上外网问题的经历

之前为了能够在Win10宿主机里通过ssh连接archlinux虚拟机,添加了一块仅主机网卡,但是从宿主机访问虚拟机是通了,却发现虚拟机archlinux却无法连接外网了,也就是说只有一块NAT网卡时可以连接因特网,添加了另一块仅主机网卡后就无法连外网了。ping外网ip既没有反应,也不报超时,百思不得其解。
一通查询之后才发现,是因为两块网卡都有默认路由,而新加的用来内网ssh连接虚拟机的网卡(Host Only)有更高的路由优先级。所有的网络数据包默认发给高优先级的纯内网网关了,导致无法连接外网。
所以解决办法就是调整路由优先级。
image

如上图所示,enp0s3是NAT网卡(可连接外网的网卡),enp0s8是仅主机网卡(只与宿主机内网连接的网卡)
enp0s8的Metric路由优先级为0,而enp0s3 的Metric 路由优先级为1002,Metric数字越小,优先级越高。

我们要配置Linux网卡的优先级,就需要修改某个网卡的Metric,然而route命令不允许直接修改,因此需要先删除,后添加。

例如将enp0s8的Metric改大,就需要执行:

route del default gw 192.168.56.1 enp0s8
route add default gw 192.168.56.1 dev enp0s8 metric 1200

再查看路由表:
image

enp0s3的优先级现在高于enp0s8
试一下能不能访问外网了:
ping 223.5.5.5 # ping 阿里云的dns
image

ok,问题解决!

但是!!!这样虚拟机的路由表在下次重启后就会失效,因为route命令所作的修改只是在当前启动时生效。总不能每次开机都重新执行一下route命令吧。如何才能永久生效呢?

有两种方案:

  1. 把之前的两条route配置命令写入开机启动项,每次开机时自动执行
  2. 通过系统的网络管理服务配置来永久修改路由表

方案1是可行的,但不够优雅,因此选择方案2。

google了几下没有找到关于archlinux的永久修改路由表的比较优雅的方案。
想到应该去查手册,achwiki,没有使用桌面版通常会使用的NetworkManager,因为没有安装桌面,装个NetworkManager感觉有点多此一举。我们使用的是系统自带的systemd-networkd服务来掌管archlinux的网络服务。

systemd-networkd简介

systemd-networkd 是一个管理网络配置的系统守护进程。它会在网络设备出现时检测和配置;它还可以创建虚拟网络设备。这个服务对被 systemd-nspawn 管理的容器或者虚拟机的复杂网络配置尤其有用,同样也适用于简单的网络配置。

果然还是官方手册好用:
image

于是给enp0s8网卡的systemd-networkd配置文件加上[Route]字段,添加Metric=1200

sudo vim /etc/systemd/network/20-wired.network

image

保存退出,重启虚拟机archlinux系统看是否生效了?
image

令人尴尬的是,并未生效,enp0s8网卡的路由优先级Metric并没有变成1200,仍然是0(最高)。
问题出在哪里呢?查看systemd-networkd的日志。

journalctl -u systemd-networkd

按下G滚动到最近的日志
image

/etc/systemd/network/20-wired.network: Route section without Gateway=, Gateway=, Destination=, Source=, Source=, or PreferredSource= field configured. Ignore

原来是缺少字段,Route里不能只改Metric,必须要加上其他必要参数才行,从日志里的报错提示可以看到缺少的参数为Gateway=, Destination=, Source=
再去查Archwiki,发现

Gateway= 这个选项必选

好吧
那就加上:

[Route]
Gateway=192.168.56.1
Metric=1200

image

重启systemd-network

sudo systemctl restart systemd-networkd

再次查看路由表:

route -n

image

可以看到路由表还是不对, 1200有了,可是还是多了一条enp0s8 Metric为0的默认路由.
想起应该还是配置文件的问题,前面的[Network]里有Gateway这个字段.[Route]里又加了一个必须的Gateway字段, 是不是[Network]里的Gateway多余了惹的祸呢?
去除[Network]里的Gateway字段
/etc/systemd/network/20-wired.network配置文件内容如下:

[Match]
Name=enp0s8

[Network]
Address=192.168.56.100/24
DNS=223.5.5.5

[Route]
Gateway=192.168.56.1
Metric=1200

image

再次重启systemd-networkd服务

sudo systemctl restart systemd-networkd

查看路由表:

route -n

image

可以看到这次终于正常了, enp0s8网卡默认路由的Metric为1200, 优先级低于enp0s3.
再测试一下网络连通性:

ping 223.5.5.5 # ping 阿里云dns

image

可以看到能够正常连接外网了.
重启虚拟机后再看:
image

一切正常!

参考链接:
ubuntu 双网卡 默认 路由 问题
Linux网卡优先级配置及同时访问内外网设置
ArchWiki:systemd-networkd
man.archlinux.org/man/systemd.network.5

posted @ 2022-12-15 14:50  Adosa(无嗔)  阅读(1923)  评论(0编辑  收藏  举报
levels of contents