卡優(yōu)先級配置:路由選路、metric與策略路由實戰(zhàn))
雙網(wǎng)卡配置優(yōu)先級這六個字我琢磨了好多年。早年幫人調(diào)機器十次里有八次碰上同一類問題服務器插了兩塊網(wǎng)卡之后要么內(nèi)網(wǎng)通外網(wǎng)不通要么外網(wǎng)通內(nèi)網(wǎng)又不通要么網(wǎng)絡時好時壞像抽風。根因基本都指向同一個地方——Linux 內(nèi)核收到報文之后并不知道你的流量該走哪塊網(wǎng)卡出去而我們又沒明確告訴系統(tǒng)什么流量優(yōu)先走哪個口。這篇文章就圍繞 CentOS 環(huán)境下的雙網(wǎng)卡優(yōu)先級問題把路由選路規(guī)則、臨時調(diào)整命令、永久配置方式、策略路由用法以及那些常出現(xiàn)的怪毛病一次講透。適合正在被多網(wǎng)卡路由問題折磨的運維、測試以及剛接觸 Linux 網(wǎng)絡想系統(tǒng)搞懂路由表機制的開發(fā)者。1. 雙網(wǎng)卡場景里繞不開的默認路由爭奪戰(zhàn)1.1 三種典型雙網(wǎng)卡拓撲分別要解決什么問題我在實際工作中遇到的雙網(wǎng)卡需求基本可以歸成下面三類。不同的業(yè)務預期決定了你后續(xù)要用完全不同的配置思路。場景類型網(wǎng)卡A網(wǎng)卡B期望的效果內(nèi)外網(wǎng)隔離內(nèi)網(wǎng)段如 10.0.0.0/24互聯(lián)網(wǎng)出口如 192.168.1.1默認流量走互聯(lián)網(wǎng)業(yè)務內(nèi)網(wǎng)段走內(nèi)網(wǎng)口雙線上網(wǎng)/冗余線路1網(wǎng)關線路2網(wǎng)關平時以線路1為主線路2只做備用虛擬化調(diào)試NAT網(wǎng)絡口Host-Only 網(wǎng)絡口默認走 NAT 上網(wǎng)調(diào)試專用網(wǎng)段走 Host-Only第一類最常見我在某跨平臺系統(tǒng)的測試環(huán)境里就搭過類似的組網(wǎng)。一塊網(wǎng)卡接辦公網(wǎng)用來訪問互聯(lián)網(wǎng)、收郵件、拉更新包另一塊網(wǎng)卡接內(nèi)部測試網(wǎng)用來連數(shù)據(jù)庫、調(diào)用內(nèi)部接口。表面上看只要兩塊網(wǎng)卡都配上 IP 就能正常工作但實際一開機就會發(fā)現(xiàn)不對勁要不就是默認走了內(nèi)網(wǎng)網(wǎng)關導致互聯(lián)網(wǎng)訪問超時要不就是內(nèi)網(wǎng)業(yè)務全部繞到辦公網(wǎng)網(wǎng)關被防火墻攔了個干凈。第二類雙線冗余對優(yōu)先級更敏感。兩個網(wǎng)關都想當默認路由如果 metric 配得不好就會出現(xiàn)今天走的 A 線明天重啟變成 B 線監(jiān)控圖上忽高忽低查了半天才發(fā)現(xiàn)是路由表里同時存在兩條 default其中一條是 DHCP 動態(tài)下發(fā)后蓋住了原來手工配置的條目。第三類虛擬化調(diào)試場景里NAT 口和 Host-Only 口其實可以共存但新手很容易把兩塊網(wǎng)卡都設成自動獲取 IP自動默認網(wǎng)關結果默認路由被最后激活的網(wǎng)卡搶走。我見過不少同學在虛擬機上裝完系統(tǒng)后 ping 外網(wǎng) ping 不通一查route -ndefault 指到了 Host-Only 那個根本沒有外部鏈路的網(wǎng)卡上。1.2 內(nèi)核選路的底層邏輯最長匹配、metric、路由表三件事想理解雙網(wǎng)卡優(yōu)先級不能只背命令。Linux 內(nèi)核在決定一個數(shù)據(jù)包往哪個網(wǎng)卡送時走的是這樣一套邏輯第一在路由表里查找最精確的條目。路由條目的本質(zhì)是目的網(wǎng)段 下一跳 出接口。系統(tǒng)會先把目標 IP 和所有路由條目做匹配前綴越長也就是掩碼位數(shù)越多的條目優(yōu)先級越高。比如訪問 192.168.56.10 時路由表中如果有192.168.56.0/24這條它肯定比0.0.0.0/0這條默認路由更優(yōu)先哪怕默認路由寫了什么特殊 flag 都不管用。所以特定網(wǎng)段走特定網(wǎng)卡這件事靠更精確的路由條目就能做到不一定非要動策略路由。第二當多條路由的前綴長度完全一樣時比較 metric也叫 metric 值老文檔里常寫作 cost。metric數(shù)值越小路由優(yōu)先級越高。比如兩條0.0.0.0/0默認路由同時存在系統(tǒng)就會選擇 metric 比較小的那個網(wǎng)關。這就是雙網(wǎng)卡默認路由優(yōu)先級的核心戰(zhàn)場——兩個網(wǎng)關都在搶這條default誰能當上真正的話事人完全看誰的 metric 小。第三如果 metric 也一樣系統(tǒng)再按路由的插入順序或者其他內(nèi)部策略做選擇。這個狀態(tài)很不穩(wěn)定重啟一次、網(wǎng)卡 re-up 一次順序就可能變所以我不建議讓生產(chǎn)環(huán)境出現(xiàn)兩條默認路由完全等價的情況。用生活里的例子類比你打開地圖軟件查回家路線系統(tǒng)給出三條方案它先找終點精確匹配的路線如果都被選中就按預計耗時排序耗時短的最優(yōu)如果耗時也一樣就看你上一次選了哪條。Linux 的 metric 就相當于這個預計耗時是我們手里最直接、最常用的優(yōu)先級調(diào)節(jié)旋鈕。2. 先用命令把默認路由切到目標網(wǎng)卡臨時方案2.1 兩個查看路由的工具route 和 ip route在系統(tǒng)層面動手之前得先看清當前路由長什么樣。CentOS 上常見的查看命令有兩個route -n輸出里有一列Flags如果條目中有UG標志U表示這條路由可用G表示要經(jīng)過網(wǎng)關轉(zhuǎn)發(fā)??吹経G的條目基本就是默認路由或者到某個網(wǎng)段的網(wǎng)關路由。另一個命令是ip route這是 iproute2 軟件包提供的輸出更詳細metric 直接能看到ip route show對比一下route -n也能顯示 metric其實是能的老版本route -n輸出末尾就有Metric列只是很多朋友沒注意。平時調(diào)試我更推薦ip route show因為它還能顯示路由來源比如proto dhcp或者proto static這信息在排查配置被誰覆蓋時特別有用。2.2 臨時切換默認網(wǎng)關的操作流程假設當前機器有兩塊網(wǎng)卡eth0走了內(nèi)網(wǎng)網(wǎng)關 10.0.0.1eth1走的是互聯(lián)網(wǎng)網(wǎng)關 192.168.1.1而我們希望默認路由切到eth1。臨時調(diào)整分三步# 第一步查看當前默認路由 ip route show # 輸出可能長這樣 # default via 10.0.0.1 dev eth0 proto dhcp metric 100 # 192.168.1.0/24 dev eth1 proto kernel scope link src 192.168.1.100 metric 200 # 第二步把默認路由切到目標網(wǎng)關 sudo ip route replace default via 192.168.1.1 dev eth1 metric 100 # 第三步確認結果 ip route show # 應該看到 # default via 192.168.1.1 dev eth1 proto static metric 100這里我用的是ip route replace不是先ip route del default再加新路由。為什么因為直接刪掉那條 default在那一瞬間路由表里就沒有默認路由了如果你正在通過這臺機器遠程維護ssh 連接走默認路由出去很可能會在刪掉路由的同時斷開連接等新路由加進去你的會話已經(jīng)回不來了。replace是原子操作直接把舊條目替換成新的風險小得多。如果你確實想保留兩條默認路由做備份也可以同時存在只要把它們設定成不同的 metric 值就行# 主用 sudo ip route add default via 192.168.1.1 dev eth1 metric 100 # 備用 sudo ip route add default via 10.0.0.1 dev eth0 metric 200這樣正常情況下所有未知流量都走 192.168.1.1只有當 eth1 鏈路掛掉、192.168.1.1 不可達時內(nèi)核才會嘗試走 10.0.0.1 這條備用路由。這是做雙線上網(wǎng)冗余最簡單粗暴但也最有效的配置方法。2.3 驗證是否生效的三板斧改完路由不能光看ip route show就說完事兒了還得驗證實際流量走的路徑。我常用的驗證命令有三個第一板斧看某個目標 IP 實際走哪個接口ip route get 223.5.5.5 # 輸出里能看到 dev eth1 以及 src 源地址這個命令會把從這臺機器到 223.5.5.5 的真實出口網(wǎng)卡和源地址顯示出來是診斷路由配了沒生效的最快方式強烈建議養(yǎng)成習慣。第二板斧強制指定網(wǎng)卡去 pingping -I eth1 -c 4 223.5.5.5-I參數(shù)指定出接口可以驗證某塊網(wǎng)卡到某目標的連通性繞開路由表的干擾。如果你不確定是不是路由表問題用這個命令分別從 eth0 和 eth1 各自 ping 一下就能知道問題在物理鏈路還是路由決策。第三板斧traceroute 看第一跳traceroute -i eth1 -n 223.5.5.5第一跳應該是 192.168.1.1。如果第一跳不是期望的網(wǎng)關說明數(shù)據(jù)包的源地址或者路由表還有沒處理干凈的地方。這類臨時命令適合應急和驗證思路改完當下就生效不寫文件。但你也應該明白只要網(wǎng)絡服務重啟、NetworkManager 重載、或者系統(tǒng)重啟這些改動就會還原。所以接下來要講永久化。3. 讓優(yōu)先級寫入配置文件ifcfg 和 NetworkManager 的持久化手段3.1 為什么重啟后配置總被覆蓋很多朋友遇到過這種情況頭天晚上用ip route把優(yōu)先級調(diào)好了第二天早上開機發(fā)現(xiàn)又回到了原來那個錯誤狀態(tài)甚至更亂。原因在于CentOS 7 以后默認由 NetworkManager 接管網(wǎng)絡配置它在啟動網(wǎng)卡時會按照網(wǎng)卡配置文件或者 DHCP 獲取到的信息重新生成路由表。你用命令行敲進去的臨時路由只存在于內(nèi)核的路由表里面屬于內(nèi)存態(tài)數(shù)據(jù)。系統(tǒng)一路由NetworkManager 就按配置文件里的內(nèi)容重新計算一遍路由之前的手工路由自然灰飛煙滅。所以持久化雙網(wǎng)卡優(yōu)先級本質(zhì)上是搞清楚如何在網(wǎng)卡配置層面表達優(yōu)先級意圖讓 NetworkManager 每次重算路由時都能算出我們希望的結果。3.2 ifcfg 文件里的三員大將GATEWAY、DEFROUTE、METRICCentOS 的網(wǎng)卡配置文件默認在/etc/sysconfig/network-scripts/ifcfg-ethX。里面跟默認路由優(yōu)先級相關的主要是三個字段GATEWAY配置該網(wǎng)卡的網(wǎng)關地址NetworkManager 看到后會為這張網(wǎng)卡生成一條默認路由。DEFROUTE控制這張網(wǎng)卡是否生成默認路由。DEFROUTEno的意思就是你只管自己直連網(wǎng)段別去搶 default。METRIC指定這條默認路由的 metric 值值越小優(yōu)先級越高。舉個例子。假設 eth0 接內(nèi)網(wǎng)eth1 接互聯(lián)網(wǎng)我希望默認路由只歸 eth1同時內(nèi)網(wǎng)直連路由照常走 eth0那么可以這樣寫# /etc/sysconfig/network-scripts/ifcfg-eth0 BOOTPROTOstatic IPADDR10.0.0.100 NETMASK255.255.255.0 GATEWAY10.0.0.1 DEFROUTEno# /etc/sysconfig/network-scripts/ifcfg-eth1 BOOTPROTOstatic IPADDR192.168.1.100 NETMASK255.255.255.0 GATEWAY192.168.1.1 DEFROUTEyes METRIC100這里的關鍵點是全局默認路由只讓一個網(wǎng)卡去當主角另一個網(wǎng)卡的DEFROUTE直接設為no避免它再往路由表里硬塞一條 default。如果兩塊網(wǎng)卡都需要上網(wǎng)雙線冗余那你可以在保留兩個 GATEWAY 的同時為其中一個顯式設置更大的METRIC200讓默認路由始終優(yōu)先走 metric 小的那張卡。另外一個老坑是/etc/sysconfig/network文件里也有一個GATEWAY字段這個文件是全局網(wǎng)絡配置老版本 CentOS 下它可以直接指定默認網(wǎng)關。在 CentOS 7/8 上它仍然會被讀取但很容易和 ifcfg 里的 GATEWAY 打架。我的習慣是盡量不用/etc/sysconfig/network里的 GATEWAY讓它保持默認內(nèi)容網(wǎng)關全部在 ifcfg 里管避免來源太多導致路由生成順序難以預測。3.3 用 nmcli 在 CentOS 7/8 上快速調(diào)整在沒有條件改文件、或者懶得重啟網(wǎng)絡服務的機器上我更推薦用 nmcli 來調(diào)整。先查看現(xiàn)有連接nmcli connection show找到對應網(wǎng)卡的連接名稱比如eth0和eth1然后直接修改路由 metricsudo nmcli connection modify eth1 ipv4.route-metric 100 sudo nmcli connection modify eth0 ipv4.route-metric 200 sudo nmcli connection up eth0 sudo nmcli connection up eth1這兩條命令的效果等同于在 ifcfg 文件里分別指定METRIC100和METRIC200重啟之后依然保留。如果你希望 eth0 完全不參與默認路由爭奪還可以把它設為不自動獲取默認路由sudo nmcli connection modify eth0 ipv4.never-default yesnever-default對應 ifcfg 里的DEFROUTEno在純命令行環(huán)境下操作節(jié)約很多時間。改完記得nmcli connection up讓配置生效。我特別提醒一句用了 nmcli 和 NetworkManager 的機器別再回頭手動編輯 ifcfg除非你把NM_CONTROLLEDno寫進文件里否則兩邊不同步會造成各種莫名其妙的我明明改了卻不生效。4. 更精細的流量分流策略路由ip rule與獨立路由表4.1 為什么光調(diào)默認路由還不夠默認路由只能解決未知流量走哪個網(wǎng)關的問題。但不少雙網(wǎng)卡場景要求的是特定網(wǎng)段必須走特定網(wǎng)卡哪怕這個網(wǎng)段在公網(wǎng)上或者這個網(wǎng)段只有通過特定網(wǎng)關才能訪問。比如 test 環(huán)境的 192.168.56.0/24 網(wǎng)段只掛在 eth0 的內(nèi)網(wǎng)鏈路上而 223.5.5.5 這樣的公網(wǎng) IP 要繞 eth1 出去。如果只設置默認路由走 eth1、內(nèi)網(wǎng)直連走 eth0那訪問 192.168.56.0/24 確實沒問題——因為直連路由最精確。但如果內(nèi)網(wǎng)網(wǎng)關后面還掛著別的私網(wǎng)段比如 172.16.0.0/16那就麻煩了。默認路由會把它丟給 eth1 的互聯(lián)網(wǎng)網(wǎng)關互聯(lián)網(wǎng)網(wǎng)關根本不知道 172.16.0.0/16 往哪轉(zhuǎn)數(shù)據(jù)包就石沉大海了。這時候就需要策略路由讓內(nèi)核在做路由決策之前先按源地址是誰、目標是誰、從哪張網(wǎng)卡進來這些附加條件選一個專門的路由表來查而不是永遠只查那張 main 路由表。4.2 ip rule 與獨立路由表給特定流量單獨畫一條道Linux 支持多張路由表默認有main、local、default等。ip rule就是策略路由規(guī)則它決定數(shù)據(jù)包去查哪張表。操作流程我拆成四步。第一步編輯/etc/iproute2/rt_tables給自定義路由表起個名字比如叫dmz_route# /etc/iproute2/rt_tables 100 dmz_route表號不要和系統(tǒng)已有的沖突100 到 200 之間一般都能用。第二步添加一條策略規(guī)則源地址來自 192.168.56.0/24 的流量都去查dmz_route這張表sudo ip rule add from 192.168.56.0/24 table dmz_route priority 100priority數(shù)值越小越先匹配。之所以顯式寫 priority是避免后面加其他規(guī)則時出現(xiàn)兩條規(guī)則優(yōu)先級相同導致規(guī)則覆蓋的尷尬。第三步往dmz_route表里寫具體路由條目。這張表里我想讓 192.168.56.0/24 直連 eth0其余流量全部丟給內(nèi)網(wǎng)網(wǎng)關 192.168.56.1sudo ip route add 192.168.56.0/24 dev eth0 src 192.168.56.100 table dmz_route sudo ip route add default via 192.168.56.1 dev eth0 table dmz_route第四步驗證ip rule show ip route show table dmz_route ip route get 172.16.0.1 from 192.168.56.100最后一條命令的from參數(shù)很關鍵它模擬源地址為 192.168.56.100 的流量要訪問 172.16.0.1時內(nèi)核會匹配到dmz_route表里的默認路由出接口還是 eth0。這樣就把特定源網(wǎng)段走特定口這件事落到了實處。4.3 讓策略路由開機自動恢復ip rule和ip route ... table同樣是內(nèi)存態(tài)命令必須想辦法在開機后自動執(zhí)行。我習慣用的持久化方案是 NetworkManager 的 dispatcher 腳本。在/etc/NetworkManager/dispatcher.d/下放一個腳本當 eth0 被激活時自動添加規(guī)則和路由#!/bin/bash if [ $2 up ] [ $1 eth0 ]; then ip rule add from 192.168.56.0/24 table dmz_route priority 100 2/dev/null || true ip route add 192.168.56.0/24 dev eth0 src 192.168.56.100 table dmz_route 2/dev/null || true ip route add default via 192.168.56.1 dev eth0 table dmz_route 2/dev/null || true fi注意腳本要有可執(zhí)行權限而且 dispatcher 腳本默認不允許往標準輸出打印東西所以調(diào)試信息最好寫到日志文件。很多朋友在服務器上配置了策略路由但不生效十有八九是忘了chmod x。如果你不想依賴 NetworkManager更老派的做法是放到/etc/rc.d/rc.local里。只是 CentOS 7/8 的 rc.local 默認沒有執(zhí)行權限需要手動加一下sudo chmod x /etc/rc.d/rc.local然后在文件尾部追加那幾條ip rule和ip route命令。這個方案簡單、直觀、不依賴 NetworkManager 版本適合只想開機執(zhí)行一次的靜態(tài)場景。缺點是沒有網(wǎng)卡 down 了再 up的重置能力鏈路抖動時規(guī)則不會自動重灌但多數(shù)生產(chǎn)環(huán)境也用不上這種動態(tài)能力。5. 雙網(wǎng)卡踩坑實錄從路由覆蓋到 DNS 錯亂的完整排查鏈路5.1 路由被覆蓋一次配好又失效的完整排查有位同事在調(diào)試某套測試平臺時早上配好的雙網(wǎng)卡路由下午一刷新就失效了。他找我?guī)兔ξ蚁茸屗熏F(xiàn)場狀態(tài)拉全。排查鏈路是這樣走的先看當前路由表確認默認路由到底指向誰ip route show輸出顯示default via 10.0.0.1 dev eth0這就不對了按預期應該走 eth1 的 192.168.1.1。再查 NetworkManager 認為的合成配置是什么nmcli device show eth0 nmcli device show eth1重點看IP4.ROUTE那一項能看到 NM 自己生成的路由條目和 metric。這里 eth0 的IP4.ROUTE里居然有0.0.0.0/0。為什么 NM 會給 eth0 生成默認路由再翻 ifcfg 文件發(fā)現(xiàn) eth0 的 ifcfg 里寫著GATEWAY10.0.0.1而 eth1 的 ifcfg 里也有GATEWAY192.168.1.1。兩張卡都在搶默認路由的編制最終 NetworkManager 按網(wǎng)卡激活順序把默認路由分配給了先激活的那張。修復方式很清晰把 eth0 的GATEWAY10.0.0.1那條刪掉或者加上DEFROUTEno讓 eth0 只保留直連路由。然后sudo systemctl restart network重啟之后再看ip route show默認路由只剩一條指向 eth1。這個案例里最能說明問題的命令其實是nmcli device show eth0——很多人排查時只盯著內(nèi)核路由表卻忽略了 NetworkManager 自己那套合成配置也會參與路由計算。5.2 DNS 解析的隱藏優(yōu)先級能 ping 通卻解析不了另一個高頻坑是網(wǎng)絡通、路由也對但域名解析一卡就卡半天或者干脆解析失敗。雙網(wǎng)卡環(huán)境下DNS 配置經(jīng)常和路由優(yōu)先級各管各的我見過太多人把時間耗在路由上最后才發(fā)現(xiàn)是 DNS 在作妖。排查思路是先確認 DNS 服務器從哪來cat /etc/resolv.conf nmcli device show eth0 | grep DNS nmcli device show eth1 | grep DNS如果 resolv.conf 里第一個 nameserver 是內(nèi)網(wǎng) DNS而內(nèi)網(wǎng) DNS 又沒法解析外網(wǎng)域名那不管路由表多完美域名解析都會失敗。這里涉及 DNS 的優(yōu)先級問題resolv.conf自上而下依次嘗試 nameserver第一個失敗才會試第二個而不同網(wǎng)卡的 DNS 由 NetworkManager 按自己的規(guī)則排序?qū)懭?。解決方式有幾個。最簡單的是在兩塊網(wǎng)卡的 ifcfg 里都指定 DNS并把公網(wǎng) DNS 寫在DNS1、內(nèi)網(wǎng) DNS 寫在DNS2例如 eth0內(nèi)網(wǎng)口寫DNS1223.5.5.5 DNS210.0.0.53這是讓公網(wǎng) DNS 優(yōu)先的寫法前提是這臺機器確實需要解析互聯(lián)網(wǎng)域名。反過來如果機器是純內(nèi)網(wǎng)業(yè)務機那應該把內(nèi)網(wǎng) DNS 放在 DNS1并配置好DOMAINcorp.local之類的搜索域否則內(nèi)部短域名根本解析不了。如果 NetworkManager 版本比較新還可以直接設置連接的dns-priority屬性數(shù)值越小優(yōu)先級越高控制 resolv.conf 里 nameserver 的排列順序。較低版本的 NM 上這個屬性可能不生效穩(wěn)妥起見還是靠 DNS1/DNS2 顯式排列這個辦法在絕大多數(shù) CentOS 機器上都能用。5.3 同網(wǎng)段雙網(wǎng)關的迷惑行為到底誰在響應還有一種更隱蔽的情況兩塊網(wǎng)卡配了不同 IP但網(wǎng)關指向同一個網(wǎng)段甚至兩個網(wǎng)關 IP 本身同網(wǎng)段。比如 eth0 的網(wǎng)關是 192.168.1.1eth1 的網(wǎng)關也是 192.168.1.1 或者 192.168.1.2兩個網(wǎng)關都在 192.168.1.0/24 里。這種情況下即使你在路由表里硬性指定了某條流量走 eth1數(shù)據(jù)包出門時還要過 ARP 這一關。內(nèi)核要確定目標網(wǎng)關的 MAC 地址應該從哪個接口學習。如果兩張網(wǎng)卡掛在同一個二層網(wǎng)絡里就可能出現(xiàn)路由說走 eth1但 ARP 應答從 eth0 回來的錯亂。表現(xiàn)就是ip route get看著正確ping 卻不通或者特別慢用 tcpdump 抓包又能看到請求發(fā)出來了但 MAC 層地址不對。處理這種場景我一般直接建議改網(wǎng)絡規(guī)劃雙網(wǎng)卡就別讓它們掛在同一個廣播域里至少錯開 VLAN或者把其中一塊網(wǎng)卡的網(wǎng)關設到另一個網(wǎng)段。如果你必須在同一二層網(wǎng)絡里用兩個網(wǎng)關那得配合 ip rule 里的from規(guī)則加上 arp_filter 之類的內(nèi)核參數(shù)復雜度高不少生產(chǎn)環(huán)境盡量少碰。6. 把這些經(jīng)驗固化成一套可復用的日常操作習慣雙網(wǎng)卡優(yōu)先級不是配一次就完事的東西它經(jīng)常在系統(tǒng)升級、網(wǎng)卡卸載重裝、DHCP 租約續(xù)期后悄悄發(fā)生變化。我在實際運維中體會最深的一點是不要等出了問題再臨時敲命令而是要把正確狀態(tài)固化在配置里并且固化得可查、可對比。我現(xiàn)在的日常習慣大致是這幾條。第一配置層面明確一個默認路由主人全機器只讓一塊網(wǎng)卡啟動默認路由其他網(wǎng)卡一律DEFROUTEno或never-default如果確實需要冗余那就顯式給不同網(wǎng)卡設不同 metric并寫清楚主備關系。第二把檢查命令做成一個別名或小腳本。比如每次登錄雙網(wǎng)卡機器先跑ip route show加ip rule show再看一眼/etc/resolv.conf三個命令加起來十秒鐘卻能把 90% 的路由問題提前暴露。第三凡是遠程調(diào)整路由我一定會先留好帶外通道最不濟也要確認當前 ssh 會話不依賴即將被替換的默認路由再用ip route replace而不是ip route deladd。第四策略路由的規(guī)則要寫到 dispatcher 腳本里但腳本里每條命令都加上2/dev/null || true避免規(guī)則已經(jīng)存在時重復執(zhí)行產(chǎn)生報錯導致 NetworkManager 誤判腳本執(zhí)行失敗。如果你也跟著動手把雙網(wǎng)卡調(diào)通了你會慢慢發(fā)現(xiàn)所謂優(yōu)先級本質(zhì)上就兩件事一是讓系統(tǒng)明白哪條路是主要的二是讓系統(tǒng)知道什么流量必須走哪條路。搞清這兩件事CentOS 雙網(wǎng)卡的絕大多數(shù)疑難雜癥都能迎刃而解。最后分享一個小技巧調(diào)試時多用ip route get它比 ping 更能說明內(nèi)核的真實意圖——因為 ping 成功了只能證明物理鏈路通而ip route get能直接告訴你數(shù)據(jù)包打算怎么走。