路由
案例
ip route
default via 192.168.3.2 dev ens192 proto static metric 100
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
172.18.0.0/16 dev br-e7e594295f85 proto kernel scope link src 172.18.0.1
172.19.0.0/16 dev br-56e50cd24f77 proto kernel scope link src 172.19.0.1
172.20.0.0/16 dev br-a944ffd8013f proto kernel scope link src 172.20.0.1
172.23.0.0/16 dev br-cd33dac77e49 proto kernel scope link src 172.23.0.1
172.24.0.0/16 dev br-ca29dc3e64e8 proto kernel scope link src 172.24.0.1
172.27.0.0/16 dev br-395c493c2f43 proto kernel scope link src 172.27.0.1
192.168.3.0/24 dev ens192 proto kernel scope link src 192.168.3.204 metric 100
192.168.16.0/20 dev br-03e3965a8912 proto kernel scope link src 192.168.16.1
192.168.32.0/20 dev br-8a171fb9786b proto kernel scope link src 192.168.32.1
192.168.49.0/24 dev br-648f45dc8c75 proto kernel scope link src 192.168.49.1
1. 默认路由(互联网的出口)
default via 192.168.3.2 dev ens192 proto static metric 100
default 代表“所有其他未匹配到的目标地址”(通常指互联网或其他非本地网络)。
* 动作:如果服务器要访问百度、谷歌,或者任何不在下面列表中的 IP,它会把数据包发给 网关 192.168.3.2。
* 接口:数据包会通过网卡 ens192 发出去。
* 场景:这就是你服务器能上网的原因。
2. 直连路由(本地局域网)
192.168.3.0/24 dev ens192 proto kernel scope link src 192.168.3.204 metric 100
192.168.3.0/24 表示从 192.168.3.0 到 192.168.3.255 的所有 IP。
* 动作:如果目标是这个范围内的 IP(比如你的同事电脑 192.168.3.50),服务器不需要经过网关,而是直接通过 ens192 网卡在局域网内广播寻找目标。
* 来源 IP:发送时,服务器会使用 192.168.3.204 作为源 IP(这是你这台机器的内网 IP)。
* 来源:proto kernel 表示这是内核自动发现的,因为网卡配置了这个 IP 段。
3. Docker 容器网络路由(虚拟网络)
剩下的那些长得很像的规则,全部是 Docker 创建的:
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
172.18.0.0/16 dev br-e7e594295f85 proto kernel scope link src 172.18.0.1
... (以及 172.19, 172.20, 192.168.16, 192.168.32 等)
docker0, br-xxxx)和独立的子网。
* 含义:
* 172.17.0.0/16:这是 Docker 默认的网桥网络。如果有数据包要去 172.17.0.5,系统知道直接发给 docker0 这个虚拟接口。
* br-xxxx:这些通常是用户自定义的 Docker Network(使用 docker network create 创建的)。每个项目或每组容器可能有一个独立的网段(如 172.18.0.0/16, 192.168.16.0/20 等)。
* 作用:这保证了宿主机(你的这台机器)知道如何找到并通信连接到这些虚拟网桥上的容器。如果没有这些路由,宿主机 ping 不通容器,容器之间也可能无法跨网段通信。
总结:数据包是如何旅行的?
假设你的服务器 (192.168.3.204) 要发送数据:
-
目标 IP 是
8.8.8.8(Google DNS):- 查表 -> 不匹配任何具体网段 -> 匹配
default。 - 结果:发给网关
192.168.3.2,走物理网卡ens192出外网。
- 查表 -> 不匹配任何具体网段 -> 匹配
-
目标 IP 是
192.168.3.50(局域网同事):- 查表 -> 匹配
192.168.3.0/24。 - 结果:直接走
ens192网卡,在局域网内直达,不经过网关。
- 查表 -> 匹配
-
目标 IP 是
172.17.0.2(某个 Docker 容器):- 查表 -> 匹配
172.17.0.0/16。 - 结果:转发给虚拟接口
docker0,由 Docker 引擎负责把数据塞进对应的容器里。
- 查表 -> 匹配
关键术语解释
- dev (Device):数据包从哪个接口(物理或虚拟)出去。
- via:下一跳网关是谁(只有非直连网络才有这个)。
- proto (Protocol):路由是怎么来的?
kernel:内核自动添加(配置 IP 地址时自动生成)。static:管理员手动添加或通过配置文件静态指定的(如默认网关)。boot/dhcp:通常由 DHCP 服务分配。
- scope link:表示目标就在该链路(接口)直连的范围内,不需要网关。
- metric:优先级。如果有两条路都能到同一个地方,数字越小优先级越高。
新增路由
sudo ip route add <目标网段> via <网关IP> dev <网卡名称>
目标网段:你想访问的 IP 范围(如10.0.0.0/8或单个 IP1.2.3.4)。via <网关IP>:下一跳是谁(数据包交给谁)。dev <网卡名称>:从哪个接口发出去(如eth0,docker0)。
📝 常见场景举例
1. 添加一条通往特定内网的路由
假设你想访问另一个内网段 10.10.10.0/24,且知道网关是 172.16.15.1:
sudo ip route add 10.10.10.0/24 via 172.16.15.1 dev eth0
10.10.10.x 的数据,都扔给 172.16.15.1,从 eth0 出去。
2. 添加一条通往特定单机的路由
假设你想强制访问某台特定服务器 192.168.50.5,走特定的网关 172.16.15.253:
sudo ip route add 192.168.50.5 via 172.16.15.253 dev eth0
/32。
3. 修复 Docker 网络(特殊场景)
如果你手动创建了一个 Docker 网络但没有自动生效路由(极少见),你可以手动指过去。
假设 br-xxxx 的 IP 是 172.21.0.1,网段是 172.21.0.0/16:
sudo ip route add 172.21.0.0/16 dev br-xxxx
4. 添加默认网关(慎用!)
如果你想修改默认出口(比如加一个备用线路):
# 添加一个优先级较低的默认路由 (metric 越大优先级越低)
sudo ip route add default via 172.16.15.254 dev eth0 metric 200
⚠️ 重要:如何让路由永久生效?
ip route add 添加的路由是临时的! 重启服务器或重启网络服务后就会消失。
根据你的操作系统,永久生效的方法不同:
编辑 netplan 配置文件(通常在 /etc/netplan/ 目录下,文件名如 50-cloud-init.yaml):
- 打开文件:
sudo nano /etc/netplan/50-cloud-init.yaml - 在
eth0下添加routes部分(注意缩进必须严格对齐):network: version: 2 ethernets: eth0: dhcp4: true routes: - to: 10.10.10.0/24 via: 172.16.15.1 metric: 100 - 应用配置:
sudo netplan apply
编辑网卡配置文件 /etc/sysconfig/network-scripts/route-eth0:
- 创建或编辑文件:
sudo vi /etc/sysconfig/network-scripts/route-eth0 - 添加内容(格式:
目标网段 via 网关):10.10.10.0/24 via 172.16.15.1 - 重启网络:
sudo systemctl restart network