1. 程式人生 > 其它 >14 Linux網路管理

14 Linux網路管理

目錄

14 Linux網路管理

1. 網路基本概述

1.1 為何需要網路

  • 假設沒有網路:(也就是將所有的計算機網路都關閉)
    • 如果我的計算機上有非常不錯的電影,想要進行傳
      輸,就比較的費勁了;
    • 因為我們可能處在不同的城市、或者不同的國家;
  • 但如果有了網路:(也就是將所有計算機通過網線連
    接在一起)
    • 1.打破了地域上資料傳輸的限制;
    • 2.提高資訊之間的傳輸效率,以便更好的實現”資源
      的共享“;

1.2 什麼是網路

  • 網路是由"若干節點"和"連線這些節點"的鏈路構成,
    表示諸多物件及其相互聯絡。
  • 網路是資訊傳輸、接收、共享的虛擬平臺,通過它把
    各個資訊聯絡到一起,從而實現這些資源的共享。
  • 網路將節點連線在一起,需要實現 ”資訊傳輸“(資訊
    通訊)有幾個大前提:
    • 1.使用物理連線的介質將所有計算機連線在一起
      (網絡卡、網線、交換機、路由器);
    • 2.雙方在通訊過程中,必須使用統一的通訊標準,
      也就是通訊協議(網際網路通訊協議);

2.網際網路通訊協議

  • 協議其實就是規定了一堆標準,用來定義計算機如何
    接入 internet 以及接入 internet 的計算機通訊的
    標準;所以計算機都需要學習此標準、遵循此標準來
    進行資訊傳輸(資訊通訊);
  • 國際標準化組織:推出了 OSI 七層參考模型,將互聯
    網通訊協議分成了不同的層,每一層都有專門的標
    準,以及組織資料的格式;
    • (應、表、會、傳、網、數、物)
  • 對於寫程式來說,通常會將七層歸納為五層協議;
    • (應、傳、網、數、物)
  • 所以我們需要學習協議的規定了哪些標準;

2.1 物理層

物理層:定義物理裝置的標準,如網絡卡網線,傳輸速
率;最終實現資料轉成電訊號傳輸;
問題:如果只是單純傳送電訊號是沒有意義的,因為沒
有規定開頭也沒有規定結尾;要想變得有意義就必須對

電訊號進行分組;比如:xx位為一組、這樣的方式去傳
輸,這就需要“資料鏈路層”來完成了;

2.2 資料鏈路層

  • 資料鏈路層定義:定義了電訊號的分組的標準方式,
    一組資料稱之為一個數據幀,這個標準遵循
    ethernet 乙太網協議,乙太網規定了如下幾件事;
  • 1.資料幀分為 head 和 data 兩部分組成;其中 head
    長度固定18位元組;
    • head :傳送者/源地址、接收者/目標地址(源地址
      6位元組、目標地址6位元組、資料型別6位元組)
      • 源地址: MAC 地址
      • 目標地址: MAC 地址
    • data :主要存放是網路層整體的資料,最長1500
      位元組,超過最大限制就分片傳送;
  • 2.但凡接入網際網路的主機必須有一塊網絡卡,網絡卡燒製
    了全世界唯一的 MAC 地址;
  • 3.有了乙太網協議規定以後,它能對資料分組、也可
    以區分資料的意義,還能找到目標主機的地址、就可
    以實現計算機通訊;但是計算機是瞎的,所以乙太網
    通訊採用的是"廣播"方式;
  • 那什麼是廣播:
    • 假設我們都在一個小黑屋裡面,大家互相通訊靠
      吼,假設 oldxu 讓 laowang 買包煙;
      • 1.資料:買菸(型別:乾糧)
      • 2.源地址: oldxu
      • 3.目標地址: laowang
    • 此時屋子裡所有人都收到了該資料包,但只有
      laowang 會接收執行,其他人收到後會丟棄;
  • 如果我們將全世界的計算機都接入在一起,理論上是
    不是就可以實現全世界通訊:
    • 首先:無法將全世界計算機放在一個交換機上,因
      為沒有這樣的裝置;
    • 其次:就算放在同一裝置上,每臺計算機都廣播一
      下,那裝置也無法正常工作;
    • 所以:我們應該將主機劃區域,隔離在一個又一個
      的區域中,然後將多個區域通過"閘道器/路由"連線在
      一起;

2.3 網路層

  • 網路層定義:用來劃分廣播域,如果廣播域內主機要
    往廣播域外的主機發送資料,一定要有一個"閘道器/路
    由"幫其將資料轉發到外部計算機;閘道器和外界通訊走
    的是路由協議(這個我們不做詳細闡述)。其次網路
    層協議規定了如下幾件事;

    • 規定1:資料包分成: head 和 data 兩部分組成;
      • head :傳送者/源地址、接收者/目標地址,該
        地址為IP地址;
      • data :主要存放是傳輸層整體的資料;
    • 規定2: IP 地址來劃分廣播域,主要用來判斷兩臺
      主機是否在同一廣播域中;
      • 一個合法 IPV4 地址組成部分= ip地址/子網掩
        碼 ,線上子網計算器
      • 172.16.1.100/24、172.16.1.1/24、
        172.16.1.2/24
      • 172.16.1.200/24
      • 網段:172.16.1.0
      • 主機:100臺
      • 廣播地址:172.16.1.255
      • 如果計算出兩臺地址的廣播域一樣,說明兩臺
        計算機處在同一個區域中;

  • 計算兩臺計算機是否在同一區域網(牽扯到如何傳送資料):
  • 假設:現在計算機1要與計算機2通訊,計算機1必須
    拿到計算機2的ip地址;
    • 如果它們處於同一網路(區域網) 10.0.0.1-->10.0.0.100 :
      • 1.本地電腦根據資料包檢查目標 IP 如果為本地
        區域網;
      • 2.直接通過交換機廣播MAC定址;將資料包轉
        發過去;
    • 如果它們處於不同網路(跨區域網) 10.0.0.1--
      39.104.16.126 :
      • 1.本地根據資料包檢查目標 IP 如果不為本地局
        域網,則嘗試獲取閘道器的 MAC 地址;
      • 2.本地封裝資料轉發給交換機,交換機拆解發現
        目標 MAC 是閘道器,則送往閘道器裝置;
      • 3.閘道器收到資料包後,拆解至二層後發現請求目
        標 MAC 是閘道器本機 MAC ;
      • 4.閘道器則會繼續拆解資料報文到三層,發現目標
        地址不為閘道器本機;
      • 5.閘道器會重新封裝資料包,將源地址替換為閘道器
        的 WAN 地址,目標地址不變;
      • 6.出口路由器根據自身“路由表”資訊將資料包發
        送出去,直到送到目標的閘道器 ;

2.4 傳輸層

  • 傳輸層的由來:網路層幫我們區分子網,資料鏈路層
    幫我們找到主機,但一個主機有多個程序,程序之間
    進行不同的網路通訊,那麼當收到資料時,如何區分
    資料是那個程序的呢;其實是通過埠來區分;埠
    即應用程式與網絡卡關聯的編號。
  • 傳輸層的定義:提供程序之間的邏輯通訊;
  • 傳輸層也分成: head 和 data 兩部分組成;
    • head :源埠、目標埠、協議(TCP、
      UDP);
    • data :主要存放是應用層整體的資料;
    • 80:http
    • 443:https
    • mysql:3306
    • tomcat:8080
    • redis:6379
    • dns:53
    • dhcp:67 68

2.5 應用層

  • 應用層定義:為終端應用提供的服務,如我們的瀏覽
    器互動時候需要用到的 HTTP 協議,郵件傳送的
    SMTP,檔案傳輸的 FTP 等。
  • 瀏覽器:
    • 請求百度的內容: 請求包; 請求的協議;
      http 源斷口: 1234 目標埠:80

3.TCP協議

  • tcp可靠資料傳輸協議;為了實現可靠傳輸,在通訊之
    前需要先建立連線,也叫"雙向通路",就是說客戶端
    與服務端要建立連線,服務端與客戶端也需要建立連
    接,當然建立的這個雙向通路它只是一個虛擬的鏈
    路,不是用網線將兩個裝置真實的捆綁在一起;
  • 虛擬鏈路的作用:由於每次通訊都需要拿到IP和
    Port,那就意味著每次都需要查詢,建立好虛擬通
    路,下次兩臺主機之間就可以直接傳遞資料;

3.1 三次握手

  • 第一次:客戶端要與服務端建立連線,需要傳送請求
    連線訊息;
  • 第二次:服務端接收到資料後,返回一個確認操作
    (至此客戶端到服務端鏈路建立成功);
  • 第三次:服務端還需要傳送要與客戶端建立連線的請求;
  • 第四次:客戶端接收到資料後,返回一個確認的操作
    (至此服務端到客戶端的鏈路建立成功);
  • 由於建立連線時沒有資料傳輸,所以第二次確認和第
    三次請求可以合併為一次傳送
  • TCP協議為了實現可靠傳輸,通訊雙方需要判斷自已
    經發送的資料包是否都被接收方收到,如果沒收到,
    就需要重發。為了實現這個需求,就引出序號
    (seq)和確認號(ack)的使用。
  • 舉例:傳送方在傳送資料包時,序列號(假設為
    123),那麼接收方收到這個資料包以後, 就可以回覆
    一個確認號(124=123+1)告訴傳送方 “我已經收到
    了你的資料包,你可以傳送下一個資料包,序號從
    124 開始”,這樣傳送方就可以知道哪些資料被接收
    到,哪些資料沒被接收到,需要重發。

3.2 四次揮手

  • 第一次揮手:客戶端(服務端也可以主動斷開)向服
    務端說明想要關閉連線;
  • 第二次揮手:服務端會回覆確認。但不是立馬關閉,
    因為此時服務端可能還有資料在傳輸中;
  • 第三次揮手:待到服務端資料傳輸都結束後,服務端
    向客戶端發出訊息,我要斷開連線了;
  • 第四次揮手:客戶端收到服務端的斷開資訊後,給予
    確認。服務端收到確認後正式關閉。

3.3 轉換狀態

  • 三次握手狀態轉換:
  • 1.客戶端傳送syn包向服務端請求建立 TCP 連線,客戶
    端進入 SYN_SEND 狀態;
  • 2.服務端收到請求之後,向客戶端傳送 SYN+ACK 的合
    成包,同時自身進入 SYN_RECV 狀態;
  • 3.客戶端收到回覆之後,傳送 ACK 資訊,自身進入
    ESTABLISHED 狀態;
  • 4.服務端收到ACK資料之後,進入 ESTABLISHED 狀
    態。
  • 四次揮手過狀態轉換:

  • 1.客戶端傳送完資料之後,向伺服器請求斷開連線,
    自身進入 FIN_WAIT_1 狀態;

  • 2服務端收到 FIN 包之後,回覆 ACK 包表示已經收到,
    但此時服務端可能還有資料沒傳送完成,自身進入
    CLOSE_WAIT 狀態,表示對方已傳送完成且請求關閉
    連線,自身傳送完成之後可以關閉連線;

  • 3.服務端資料傳送完成後,傳送 FIN 包給客戶端,自
    身進入 LAST_ACK 狀態,等待客戶端 ACK 確認;

  • 4.客戶端收到 FIN 包之後,回覆一個 ACK 包,並進入
    TIME_WAIT 狀態;

  • 注意: TIME_WAIT 狀態比較特殊,當客戶端收到服務
    端的 FIN 包時,理想狀態下,是可以直接關閉連線
    了;但是有幾個問題:

    • 問題1:網路是不穩定的,可能服務端傳送的一些
      資料包,比服務端傳送的 FIN 包還晚到;
    • 問題2:.如果客戶端回覆的ACK包丟失了,服務端
      就會一直處於 LAST_ACK 狀態,如果客戶端沒有關
      閉,那麼服務端還會重傳 FIN 包,然後客戶端繼續
      確認;
  • 所以客戶端如果 ACK 後立即關閉連線,會導致資料不
    完整、也可能造成服務端無法釋放連線。所以此時客
    戶端需要等待2個報文生存最大時長,確保網路中沒
    有任何遺留報文了,再關閉連線;期間客戶端不斷給
    服務端傳送ACK確認,防止服務端收不到一直處於LAST_ACK狀態

  • 如果機器 TIME_WAIT 過多,會造成埠會耗盡,可以
    修改核心引數 tcp_tw_reuse=1 埠重用;

  • 為什麼必須要等待2MSL?而不是4MSL?8MSL?
  • 一個MSL就是報文在網路中的最長生存時間,大白話
    的話,就是如果存在丟包的話,在MSL時間內也會觸
    發重傳了,這裡2MSL,就相當於兩次丟包,一次丟
    包概率是百分之一,連續兩次丟包的概率是萬分之
    一,這個概率實在是太小了,所以2MSL是足夠的。

3.4 UDP協議

  • udp 是不可靠傳輸協議;不可靠指的是傳輸資料時不
    可靠;
  • udp 協議不需要先建立連線,只需要獲取服務端的
    ip+port ,傳送完畢也無需伺服器返回 ack
  • udp 協議如果在傳送在資料的過程中丟了,那就丟
    了;
  • 場景:直播;彈幕; DNS 採用; QQ早起UDP;

4. 網路配置

4.1 查詢網路資訊

1.使用 ifconfig 當前處於活動狀態的網路介面

[root@node ~]# yum install net-tools -y
[root@node ~]# ifconfig
#僅檢視eth0網絡卡狀態資訊
[root@node ~]# ifconfig eth0
#檢視所有網絡卡狀態資訊, 包括禁用和啟用
[root@node ~]# ifconfig -a
#UP: 網絡卡處於活動狀態 BROADCAST: 支援廣播
RUNNING: 網線已接入
#MULTICAST: 支援組播 #MTU: 最大傳輸單元(位元組),接
口一次所能傳輸的最大包
eth0:
flags=4163<UP,BROADCAST,RUNNING,MULTICAST>
mtu 1500
#inet: 顯示IPv4地址行
inet 10.0.0.100 netmask
255.255.255.0 broadcast 10.0.0.255
#inet6: 顯示IPv6地址行
inet6 fe80::a879:62cf:396c:e7d9
prefixlen 64 scopeid 0x20<link>
inet6 fe80::22a2:cb:8a69:bf63
prefixlen 64 scopeid 0x20<link>
#enther: 硬體(MAC)地址 
#txqueuelen: 傳輸快取區長度大小
ether 00:0c:29:5f:6b:8a txqueuelen
1000 (Ethernet)
#RX packets: 接收的資料包
RX packets 3312643 bytes
4698753634 (4.3 GiB)
RX errors 0 dropped 0 overruns 0
frame 0
#TX packets: 傳送的資料包 
TX packets 235041 bytes 20504297
(19.5 MiB)
TX errors 0 dropped 0 overruns 0
carrier 0 collisions 0
#errors: 總的收包的錯誤數量 
#dropped: 拷貝中發生錯誤被丟棄
#collisions: 網路訊號衝突情況, 值不為0則可能存在
網路故障

2.使用 ip 命令檢視當前地址

[root@node ~]# ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,①UP,LOWER_UP>
mtu 1500 qdisc pfifo_fast state UP qlen
1000
②link/ether 00:0c:29:5f:6b:8a
ff:ff:ff:ff:ff:ff
③inet 10.0.0.100/24 brd④ 192.168.69.255
scope global ens32
valid_lft forever preferred_lft
forever
⑤inet6 fe80::bd23:46cf:a12e:c0a1/64
scope link
valid_lft forever preferred_lft
forever

#①: 活動介面為UP
#②: Link行指定裝置的MAC地址
#③: inet行顯示IPv4地址和字首
#④: 廣播地址、作用域和裝置名稱在此行
#⑤: inet6行顯示IPv6資訊

3.使用 ip -s link show eth0 命令檢視網路效能的統
計資訊, 比如: 傳送和傳送的資料包、錯誤、丟棄

[root@node ~]# ip -s link show eth0
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP>
mtu 1500 qdisc mq state UP mode DEFAULT
qlen 1000
link/ether 14:18:77:35:0d:f5 brd
ff:ff:ff:ff:ff:ff
RX: bytes packets errors dropped
overrun mcast
518292951 4716385 0 0 0 
709280
TX: bytes packets errors dropped
carrier collsns
23029861512 15391427 0 0 0
0

4.2 修改網絡卡名稱

  • Centos6 網絡卡名稱是 eth0、eth1....
  • Centos7 網絡卡名稱是 ens32、ens33...
  • 由於這種無規則的命名方式給後期維護帶來了困難,
    所以需要將網絡卡名稱修改為 eth0、eth1..

場景示例1:已經安裝完作業系統,修改網絡卡命名規
則為 eth0 eth1

1.修改網絡卡配置檔案

[root@node ~]# cd /etc/sysconfig/network-scripts/
[root@node network-scripts]# mv ifcfg-ens32 ifcfg-eth0
[root@node network-scripts]# vim ifcfg-eth0
NAME=eth0
DEVICE=eth0

2.修改核心啟動引數,禁用預測命名規則方案,將
net.ifnames=0 biosdevname=0 引數關閉

[root@node~]# vim /etc/sysconfig/grub
GRUB_CMDLINE_LINUX="...net.ifnames=0 biosdevname=0 quiet"
[root@node~]# grub2-mkconfig -o /boot/grub2/grub.cfg

3.重啟系統,然後檢查網絡卡名稱是否修改成功

[root@node~]# reboot
[root@node~]# ifconfig
  • 場景示例2:在新安裝系統時,修改網絡卡名稱規則

1.在安裝系統選擇 Install Centos7 按下 Tab 設定
kernel 核心引數;

2.增加核心引數: net.ifnames=0 biosdevname=0 ;

3.檢查是否修改成功,成功後可繼續安裝系統;

4.3 配置網路地址

  • CentOS7 系統預設採用 NetworkManager 來提供網
    絡服務,這是一種動態管理網路配置的守護程序,能
    夠讓網路裝置保持連線狀態。 NetworkManager 提供
    的命令列和圖形配置工具對網路進行設定,設定儲存
    的配置檔案在 /etc/sysconfig/network-scripts
    目錄下,工具有 nmcli、nmtui
  • NetworkManager 有如下兩個概念需要了解:
    • device 物理裝置,例如: enp2s0,virbr0,team0
    • connection 連線設定,具體網路配置方案
    • 一個物理裝置 device 可以有多套邏輯連線配置,
      但同一時刻只能使用一個 connection 連線配置;

4.3.1 nmcli檢視網路狀態

1.使用 nmcli device 命令檢視裝置情況

# 檢視所有裝置
[root@node ~]# nmcli device
DEVICE TYPE STATE CONNECTION
eth0 ethernet connected eth0
lo loopback unmanaged --
# 指定檢視某個裝置的詳細狀態
[root@node ~]# nmcli dev show eth0

2.使用 nmcli connection 命令檢視連線狀態

#檢視連線狀態
[root@node ~]# nmcli connection 
NAME UUID 
TYPE DEVICE
eth0 a4319b27-80dc-4d63-a693-2927ea1018e7
802-3-ethernet eth0
# 檢視所有活動連線的狀態
[root@node ~]# nmcli con show --active
# 檢視指定連線狀態
[root@node ~]# nmcli con show "eth0"

4.3.2 nmcli配置IP地址

  • 使用 nmcli 建立一個 static 的連線,配置IP、掩
    碼、閘道器等
    • 1、新增一個連線配置,並指定連線配置名稱
    • 2、將連線配置繫結物理網絡卡裝置
    • 3、配置網絡卡的型別,網絡卡是否開機啟動
    • 4、網絡卡使用什麼模式配置IP地址(靜態、dhcp)
    • 5、配置網絡卡的IP地址、掩碼、閘道器、DNS等等
[root@node ~]# nmcli connection add \
con-name eth0-static \
ifname eth0 \
type ethernet \
autoconnect yes \
ipv4.addresses 10.0.0.222/24 \
ipv4.gateway 10.0.0.2 \
ipv4.dns 223.5.5.5 \
ipv4.method manual
[root@oldxu ~]# nmcli connection add con-
name eht0-static ifname eth0 \
type ethernet autoconnect yes \
ipv4.method manual \
ipv4.addresses 10.0.0.222/24 \
ipv4.gateway 10.0.0.254 \
ipv4.dns 233.5.5.5.5 \
+ipv4.dns 8.8.8.8
#啟用eht1-static的連線
[root@node ~]# nmcli connection up eht0-static
[root@node ~]# nmcli connection show
NAME UUID 
TYPE DEVICE
eht0-static 6fdebe6e-5ef0-4a05-8235-
57e317fdada0 802-3-ethernet eth0

4.3.3 nmcli修改IP地址

1.取消 eht1-static 連線開機自動啟用網路

[root@node ~]# nmcli connection modify eht0-static \
autoconnect no

2.修改 eht1-static 連線的 dns 配置

[root@node ~]# nmcli connection modify
eht0-static \
ipv4.dns 8.8.8.8

3.給連線再增加 dns 有些設定值通過 +/- 可以增加或則移除設定

[root@node ~]# nmcli connection modify
eht0-static \
+ipv4.dns 8.8.8.8

4.替換連線的靜態IP和預設閘道器

[root@node ~]# nmcli connection modify
eht0-static \
ipv4.addresses 10.0.0.111/24 ipv4.gateway
10.0.0.254

5.nmlci 僅僅修改並儲存了配置,要啟用更改,需要重啟用連線

[root@node ~]# nmcli connection down eht1-
static && \
nmcli connection up eht1-static

6.刪除自建的 connection

[root@node ~]# nmcli connection delete
eht1-static

4.3.4 nmcli管理配置檔案

  • 使用 nmcli 管理 /etc/sysconfig/network-
    scripts/ 配置檔案,其實就是自定義一個網絡卡的配
    置檔案,然後加入至 NetworkManager 服務進行管
    理;

    • 1、新增物理網絡卡
    • 2、拷貝配置檔案(可以和裝置名稱一致)
    • 3、修改配置,UUID、連線名稱、裝置名稱、IP地址
    • 4、重新載入網路配置
    • 5、啟用連線,並檢查

    1.新增一個物理裝置,進入 /etc/sysconfig/network-
    script/ 目錄拷貝一份網絡卡配置檔案;

    [root@node network-scripts]# cp ifcfg-
    eth0-static ifcfg-eth1-static
    

    2.修改網絡卡配置檔案如下

    [root@node network-scripts]# cat ifcfg-
    eth1-static
    TYPE=Ethernet
    BOOTPROTO=none # 網絡卡型別 none;
    static;dhcp; 硬體伺服器都選擇static、雲主機、
    docker容器例項一般都是dhcp
    IPADDR=10.0.0.222 # IP地址
    PREFIX=24 # 子網掩碼
    DEFROUTE=yes # 預設路由(明天講
    路由)
    NAME=eth1-static # 連結的配置名稱
    DEVICE=eth2 # 裝置名稱
    ONBOOT=yes # 開機是否啟動
    

    3.過載 connetction 連線,讓 NetworkManager 服務能夠識別新增自定義網絡卡配置;

    [root@node network-scripts]# nmcli connection reload
    NAME UUID 
    TYPE DEVICE
    eth0 5fb06bd0-0bb0-7ffb-45f1-
    d6edd65f3e03 ethernet eth0 
    eth1-static 8f105ed6-1361-8e14-51fd-
    dedb8ef3510a ethernet eth1 
    

    4.eth1-static 連線配置已經關聯了 eth1 物理裝置,如果希望修改 IP 地址,可以用如下兩種方式;

    # 方式一、nmcli modify方式修改然後過載配置
    [root@node ~]# nmcli modify eth1-static
    ipv4.address 10.0.0.233/24
    [root@node ~]# nmcli down eth1-static &&
    nmcli up eth1-static
    # 方式二、vim修改,先reload,然後過載
    [root@node network-scripts]# cat ifcfg-
    eth1-static
    ...
    IPADDR=10.0.0.234
    ...
    [root@node ~]# nmcli connection reload
    [root@node ~]# nmcli connection down eth1-
    static && nmcli connection up eth1-static
    
    #重啟網絡卡
    systemctl restart network
    
    

5. 網絡卡繫結

  • 網絡卡繫結 Bonding
    • 1、可以實現網路冗餘,避免單點故障;
    • 2、可以實現負載均衡,以提升網路的傳輸能力;
  • 網絡卡繫結實現模式:
    • 模式0 balance-rr 負載輪詢:兩網絡卡單獨是
      100MB ,聚合為1個網路傳輸,則可提升為 200MB
    • 模式1 active-backup 高可用:兩塊網絡卡,其中一
      條若斷線,另外的線路將會自動頂替

5.1 配置round-robin

5.1.1 eth0網絡卡配置

[root@node ~]# cat /etc/sysconfig/network-
scripts/ifcfg-eth0
TYPE=Ethernet
DEVICE=eth0
NAME=eth0
ONBOOT=yes
MASTER=bond0
SLAVE=yes

5.1.2 eth1網絡卡配置

[root@node ~]# cat /etc/sysconfig/network-
scripts/ifcfg-eth1
TYPE=Ethernet
DEVICE=eth1
NAME=eth1
ONBOOT=yes
MASTER=bond0
SLAVE=yes

5.1.3 bond網絡卡配置

[root@node ~]# cat /etc/sysconfig/network-
scripts/ifcfg-bond0
TYPE=Bond
BOOTPROTO=none
ONBOOT=yes
DEVICE=bond0
NAME=bond0
IPADDR=10.0.0.100
PREFIX=24
GATEWAY=10.0.0.2
DNS1=223.5.5.5
DEFROUTE=yes
BONDING_MASTER=yes
BONDING_OPTS="miimon=200 mode=0" # 檢查間
隔時間ms

5.1.4 bond狀態檢查

[root@node ~]# cat /proc/net/bonding/bond0
Ethernet Channel Bonding Driver: v3.7.1
(April 27, 2011)
Bonding Mode: load balancing (round-robin)
# 模式
MII Status: up
MII Polling Interval (ms): 200
Up Delay (ms): 0
Down Delay (ms): 0
Slave Interface: eth0
MII Status: up
Speed: 1000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 00:0c:29:aa:8d:2e
Slave queue ID: 0
Slave Interface: eth1
MII Status: up
Speed: 1000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 00:0c:29:aa:8d:42
Slave queue ID: 0

使用 ethtool 檢查網絡卡傳輸速率

[root@node ~]# ethtool bond0
Settings for bond0:
Speed: 2000Mb/s # 每秒傳輸速度
Duplex: Full

5.1.5 bond網絡卡刪除

刪除 bond 可以使用 nmcli 命令

[root@node ~]# nmcli connection delete
bond0

5.2 配置active-backup

5.2.1 eth0 網絡卡配置

[root@node ~]# cat /etc/sysconfig/network-
scripts/ifcfg-eth0
TYPE=Ethernet
DEVICE=eth0
NAME=eth0
ONBOOT=yes
MASTER=bond1
SLAVE=yes

5.2.2 eth1網絡卡配置

[root@node ~]# cat /etc/sysconfig/network-
scripts/ifcfg-eth1
TYPE=Ethernet
BOOTPROTO=none
DEVICE=eth1
NAME=eth1
ONBOOT=yes
MASTER=bond1
SLAVE=yes

5.2.3 bond 網絡卡配置

[root@node ~]# cat /etc/sysconfig/network-scripts/ifcfg-bond1
TYPE=Bond
BOOTPROTO=none
ONBOOT=yes
DEVICE=bond1
NAME=bond1
IPADDR=10.0.0.200
PREFIX=24
GATEWAY=10.0.0.2
DNS1=223.5.5.5
BONDING_MASTER=yes
BONDING_OPTS="miimon=200 mode=1 fail_over_mac=1"
# bond1獲取mac地址有兩種方式
#1、從第一個活躍網絡卡中獲取mac地址,然後其餘的
SLAVE網絡卡的mac地址都使用該mac地址;
#2、使用fail_over_mac引數,是bond0使用當前
活躍網絡卡的mac地址,mac地址隨著活躍網絡卡的轉換而變。
# fail_over_mac引數在VMWare上是必須配置,物理機
可不用配置;

5.2.4 bond狀態檢查

[root@node ~]# cat /proc/net/bonding/bond1
Ethernet Channel Bonding Driver: v3.7.1
(April 27, 2011)
Bonding Mode: fault-tolerance (active-
backup) (fail_over_mac active)
Primary Slave: None
Currently Active Slave: eth0
MII Status: up
MII Polling Interval (ms): 200
Up Delay (ms): 0
Down Delay (ms): 0
Slave Interface: eth0
MII Status: up
Speed: 1000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 00:50:56:38:85:72
Slave queue ID: 0
Slave Interface: eth1
MII Status: up
Speed: 1000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 00:50:56:25:33:ee
Slave queue ID: 0

5.2.5 bond故障模式

關閉活躍網絡卡 eth0

[root@node ~]# ifdown eth0
成功斷開裝置 'eth0'

再次檢查狀態,會發現備用網絡卡 eth1 切換為活躍網絡卡

[root@node ~]# cat /proc/net/bonding/bond1
Ethernet Channel Bonding Driver: v3.7.1
(April 27, 2011)
Bonding Mode: fault-tolerance (active-
backup) (fail_over_mac active)
Primary Slave: None
Currently Active Slave: eth1
MII Status: up
MII Polling Interval (ms): 200
Up Delay (ms): 0
Down Delay (ms): 0
Slave Interface: eth1
MII Status: up
Speed: 1000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 00:50:56:25:33:ee
Slave queue ID: 0

嘗試 ping 該主機,一切正常

64 bytes from 10.0.0.220: icmp_seq=173
ttl=64 time=0.512 ms
64 bytes from 10.0.0.220: icmp_seq=174
ttl=64 time=0.512 ms
64 bytes from 10.0.0.220: icmp_seq=175
ttl=64 time=2.11 ms

6. 閘道器/路由

6.1 什麼是路由

  • 路由是指路由器從一個LAN介面上收到資料包,根據
    資料包的"目的地址"進行定向並轉發到另一個WAN接
    口的過程。(跨網路訪問的路徑選擇)
  • 路由工作包含兩個基本的動作:
    • 1、確定最佳路徑 user ---> LNA-- >route -->WAN -->選最近路線--》 傳輸
    • 2、通過網路傳輸資訊
  • 在路由的過程中,後者也稱為(資料)交換。交換相
    對來說比較簡單,而選擇路徑很複雜。

6.2 為什麼需要路由

如果沒有路由,就沒有辦法實現,不同地域的主機互聯互通了;

6.3 如何配置路由

  • linux系統配置路由使用 route 命令;可以使用
    route 命令來顯示和管理路由表;
  • route 命令語法示例:
  • route [add|del] [-host|-net|default]
    [address[/mask]] [netmask] [gw] [dev]
    • [add|del] :增加或刪除路由條目;
    • -host :新增或刪除主機路由;
    • -net :新增或刪除網路路由;
    • default :新增或刪除預設路由;
    • address :新增要去往的網段地址 由
      ip+netmask 組成;
    • gw :指定下一跳地址,要求下一跳地址必須是能
      到達的,且一般是和本網段直連的介面。
    • dev :將新增路由與對應的介面關聯,一般核心額
      會自動判斷路由應該關聯哪個介面;
  • route 新增路由命令示例:
[root@node ~]# route add -host 1.1.1.1/32
dev eth0
[root@node ~]# route add -net 1.1.1.1/32
dev eth1
[root@node ~]# route add -net 1.1.1.1/32
gw 1.1.1.2
[root@node ~]# route add default gw
1.1.1.2

6.4 路由的分類

6.4.1 主機路由

  • 主機路由作用:指明到某臺主機具體應該怎麼走;
    Destination 精確到某一臺主機
  • Linux上如何配置主機路由:
# 去往1.1.1.1主機,從eth0接口出
[root@node ~]# route add -host 1.1.1.1/32
dev eth0
# 去往1.1.1.1主機,都交給10.0.0.2轉發
[root@node ~]# route add -host 1.1.1.1/32
gw 10.0.0.2

6.4.2 網路路由

  • 網路路由作用:指明到某類網路怎麼走;
    Destination 精確到某一個網段的主機
  • Linux上如何配置網路路由:
# 去往2.2.2.0/24網段,從eth0接口出
[root@node ~]# route add -net 2.2.2.0/24
dev eth0
# 去往2.2.2.0/24網段,都交給10.0.0.2轉發
[root@node ~]# route add -net 2.2.2.0/24
gw 10.0.0.2

6.4.3 預設路由

  • 預設路由:如果匹配不到主機路由、網路路由的,全
    部都走預設路由(閘道器);
  • Linux上如何配置網路路由:
[root@node ~]# route add -net 0.0.0.0 gw
10.0.0.2
[root@node ~]# route add default gw
10.0.0.2

6.4.4 永久路由

  • 使用 route 命令新增的路由,屬於臨時新增;那如
    何新增永久路由條目;
  • 在 /etc/sysconfig/network-scripts 目錄下建立
    route-ethx 的網絡卡名稱,新增路由條目
[root@dns-master ~]# cat
/etc/sysconfig/network-scripts/route-eth0
1.1.1.0/24 dev eth0
1.1.1.0/24 via 1.1.1.2
[root@dns-master ~]# route -n
Kernel IP routing table
Destination Gateway Genmask 
Flags Metric Ref Use Iface
1.1.1.0 0.0.0.0 
255.255.255.0 U 100 0 0
eth0
1.1.1.0 1.1.1.2 
255.255.255.0 UG 100 0 0
eth0

6.5 路由專案案例

  • 一臺Linux主機能夠被當成路由器用需要三大前提:
    • 1.至少有兩塊網絡卡分別連線兩個不同的網段;
    • 2.開啟路由轉發功能 /proc/sys/net/ipv4/ip_forward ;
    • 3.在 linux 主機新增閘道器指向該伺服器(路由);

6.5.1 環境準備

  • 實驗環境
  • 虛擬機器網段配置

6.5.2 虛擬機器1網絡卡配置

1.eth0網絡卡

[root@vm1 ~]# cat /etc/sysconfig/network-
scripts/ifcfg-eth0
TYPE=Ethernet
BOOTPROTO=static
DEFROUTE=yes
NAME=eth0
DEVICE=eth0
ONBOOT=yes
IPADDR=10.0.0.100
PREFIX=24

2.eth1網絡卡

[root@vm1 ~]# cat /etc/sysconfig/network-
scripts/ifcfg-eth1
TYPE=Ethernet
BOOTPROTO=static
DEFROUTE=yes
NAME=eth1
DEVICE=eth1
ONBOOT=yes
IPADDR=1.1.1.1
PREFIX=24

3.路由資訊

[root@vm1 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
1.1.1.0 0.0.0.0 
255.255.255.0 U 101 0 0
eth1
10.0.0.0 0.0.0.0 
255.255.255.0 U 100 0 0
eth0

6.5.3 虛擬機器2網絡卡配置

1.eth0網絡卡配置

[root@vm2 ~]# cat /etc/sysconfig/network-
scripts/ifcfg-eth0
TYPE=Ethernet
BOOTPROTO=static
DEFROUTE=yes
NAME=eth0
DEVICE=eth0
ONBOOT=yes
IPADDR=1.1.1.2
PREFIX=24

2.eth1網絡卡配置

[root@vm2 ~]# cat /etc/sysconfig/network-
scripts/ifcfg-eth1
TYPE=Ethernet
BOOTPROTO=static
DEFROUTE=yes
NAME=eth1
DEVICE=eth1
ONBOOT=yes
IPADDR=2.2.2.2
PREFIX=24

3.路由資訊

[root@vm2 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask 
Flags Metric Ref Use Iface
1.1.1.0 0.0.0.0 
255.255.255.0 U 100 0 0
eth0
2.2.2.0 0.0.0.0 
255.255.255.0 U 101 0 0
eth1

6.5.4 虛擬機器3網絡卡配置

1.eth0網絡卡配置

[root@vm3 ~]# cat /etc/sysconfig/network-
scripts/ifcfg-eth0
TYPE=Ethernet
BOOTPROTO=static
DEFROUTE=yes
NAME=eth0
DEVICE=eth0
ONBOOT=yes
IPADDR=2.2.2.3
PREFIX=24

2.eth1網絡卡配置

[root@vm3 ~]# cat /etc/sysconfig/network-
scripts/ifcfg-eth1
TYPE=Ethernet
BOOTPROTO=static
DEFROUTE=yes
NAME=eth1
DEVICE=eth1
ONBOOT=yes
IPADDR=3.3.3.3
PREFIX=24

3.路由資訊

[root@vm3 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask 
Flags Metric Ref Use Iface
2.2.2.0 0.0.0.0 
255.255.255.0 U 100 0 0
eth0
3.3.3.0 0.0.0.0 
255.255.255.0 U 101 0 0
eth1

6.5.5 虛擬機器4網絡卡配置

1.eth0網絡卡配置

[root@vm4 ~]# cat /etc/sysconfig/network-
scripts/ifcfg-eth0
TYPE=Ethernet
BOOTPROTO=static
DEFROUTE=yes
NAME=eth0
DEVICE=eth0
ONBOOT=yes
IPADDR=3.3.3.4
PREFIX=24

2.eth1網絡卡配置

[root@vm4 ~]# cat /etc/sysconfig/network-
scripts/ifcfg-eth1
TYPE=Ethernet
BOOTPROTO=static
DEFROUTE=yes
NAME=eth1
DEVICE=eth1
ONBOOT=yes
IPADDR=4.4.4.4
PREFIX=24

3.路由資訊

[root@vm4 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask 
Flags Metric Ref Use Iface
3.3.3.0 0.0.0.0 
255.255.255.0 U 100 0 0
eth0
4.4.4.0 0.0.0.0 
255.255.255.0 U 101 0 0
eth1

6.5.6 場景示例1

  • 問:1.1.1.1地址能否與1.1.1.2 互通;

  • 可以通,因為本機1.1.1.1與目標主機1.1.1.2 兩臺機器

    處於一個LAN中,並且兩臺機器上的路由表裡具有
    Destination指向對方的網段路由條目

    [root@vm1 ~]# route -n
    Kernel IP routing table
    Destination Gateway Genmask 
    Flags Metric Ref Use Iface
    10.0.0.0 0.0.0.0 
    255.255.255.0 U 100 0 0
    eth0
    1.1.1.0 0.0.0.0 
    255.255.255.0 U 101 0 0
    eth1
    [root@vm2 ~]# route -n
    Kernel IP routing table
    Destination Gateway Genmask 
    Flags Metric Ref Use Iface
    1.1.1.0 0.0.0.0 
    255.255.255.0 U 100 0 0
    eth0
    2.2.2.0 0.0.0.0 
    255.255.255.0 U 101 0 0
    eth1
    
    • 問:1.1.1.1地址能否與2.2.2.2地址互通
    • 答:不能;因為資料包只能送到1.1.1.2,而無法送達
      2.2.2.2
    • 所以需要新增一條去往2.2.2.0/24網段的路由,從
      eth1介面發出即可;
    [root@vm1 ~]# route add -net 2.2.2.0/24 dev
    eth1
    [root@vm1 ~]# route -n
    Kernel IP routing table
    Destination Gateway Genmask 
    Flags Metric Ref Use Iface
    1.1.1.0 0.0.0.0 
    255.255.255.0 U 101 0 0
    eth1
    2.2.2.0 0.0.0.0 
    255.255.255.0 U 0 0 0
    eth1
    10.0.0.0 0.0.0.0 
    255.255.255.0 U 100 0 0
    eth0
    [root@vm1 ~]# ping 2.2.2.2
    PING 2.2.2.2 (2.2.2.2) 56(84) bytes of
    data.
    64 bytes from 2.2.2.2: icmp_seq=1 ttl=64
    time=0.602 ms
    64 bytes from 2.2.2.2: icmp_seq=2 ttl=64
    time=1.60 ms
    

6.5.7 場景示例2

  • 問:1.1.1.1地址能否與2.2.2.3地址互通;
  • 答:不能;因為資料包只能送到vmnet2交換機,送
    不到vmnet3交換機
  • 解決方案:將去往2.2.2.0/24網段的資料包交給
    1.1.1.2這臺主機幫我們轉發給2.2.2.3這臺主機;
# vm1新增路由
[root@vm1 ~]# route add -net 2.2.2.0/24 gw
1.1.1.2
[root@vm1 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask 
Flags Metric Ref Use Iface
1.1.1.0 0.0.0.0 
255.255.255.0 U 101 0 0
eth1
2.2.2.0 1.1.1.2 
255.255.255.0 UG 0 0 0
eth1
# vm2開啟核心轉發(由於vm2上有去往2.2.2.0/24網段
路由,所以新增)
[root@vm2 ~]# echo "1" > /proc/sys/net/ipv4/ip_forward
[root@vm2 ~]# sysctl -p
# vm1測試是否能ping通
[root@vm1 ~]# ping 2.2.2.3
PING 2.2.2.3 (2.2.2.3) 56(84) bytes of
data.
64 bytes from 2.2.2.3: icmp_seq=1 ttl=63
time=0.690 ms

6.5.8 場景示例3

  • 問:1.1.1.1地址能否與3.3.3.3地址互通;
  • 答:不能;因為資料包只能送到vmnet2交換機,送
    不到vmnet3交換機
  • 解決方案:
    • 1.在vm1主機上將去往3.3.3.0/24網段的資料包交
      給1.1.1.2,由這臺主機幫我們轉發給3.3.3.3;
    • 2.在vm2上需要新增到3.3.3.0/24網段的路由,然
      後開啟轉發功能,否則資料包無法轉發,會被丟棄;
    • 3.資料包到達vm3主機,但是無法送回來,所以還
      需要在vm3主機上新增去往1.1.1.0/24網段的資料
      包走2.2.2.2這臺主機轉發
# vm1新增路由
[root@vm1 ~]# route add -net 3.3.3.0/24 gw
1.1.1.2
[root@vm1 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask 
Flags Metric Ref Use Iface
3.3.3.0 1.1.1.2 
255.255.255.0 UG 0 0 0
eth1
# vm2開啟轉發,新增路由
[root@vm2 ~]# echo "1" >
/proc/sys/net/ipv4/ip_forward
[root@vm2 ~]# sysctl -p
[root@vm2 ~]# route add -net 3.3.3.0/24
eth1
[root@vm2 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask 
Flags Metric Ref Use Iface
3.3.3.0 0.0.0.0 
255.255.255.0 U 0 0 0
eth1
# vm3添加回包路由
[root@vm3 ~]# route add -net 1.1.1.0/24 gw
2.2.2.2
[root@vm3 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask 
Flags Metric Ref Use Iface
1.1.1.0 2.2.2.2 
255.255.255.0 UG 0 0 0
eth0
#vm1主機測試
[root@vm1 ~]# ping 3.3.3.3
PING 3.3.3.3 (3.3.3.3) 56(84) bytes of data.
64 bytes from 3.3.3.3: icmp_seq=1 ttl=63 time=0.788 ms

6.5.9 場景示例4

  • 問:1.1.1.1地址能否與3.3.3.4地址互通;
  • 答:不能;因為資料包只能從vmnet2交換機送往
    vmnet3交換機,無法達到vmnet4交換機;
  • 解決方案:
    • 1.在vm1主機上將去往3.3.3.0/24網段的資料包交
      給1.1.1.2,由這臺主機幫我們轉發給3.3.3.4;
    • 2.在vm2上開啟轉發功能,然後新增到3.3.3.0/24
      網段的路由,由2.2.2.3幫我們轉發給3.3.3.4;
    • 3.在vm3上開啟轉發功能;
    • 4.資料包到達vm4主機,但是無法送回來,所以還
      需要在vm4主機上新增去往1.1.1.0/24網段的資料
      包走3.3.3.3這臺主機轉發;
#vm1新增路由
[root@vm1 ~]# route add -net 3.3.3.0/24
gw 1.1.1.2
[root@vm1 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask 
Flags Metric Ref Use Iface
3.3.3.0 1.1.1.2 
255.255.255.0 UG 0 0 0
eth1
#vm2開啟轉發,新增路由規則
[root@vm2 ~]# echo "1" >
/proc/sys/net/ipv4/ip_forward
[root@vm2 ~]# sysctl -p
[root@vm2 ~]# route add -net 3.3.3.0/24
gw 2.2.2.3
[root@vm2 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask 
Flags Metric Ref Use Iface
3.3.3.0 2.2.2.3 
255.255.255.0 UG 0 0 0
eth1
#vm3開啟轉發
[root@vm3 ~]# echo "1" >
/proc/sys/net/ipv4/ip_forward
[root@vm3 ~]# sysctl -p
#vm4添加回包路由
[root@centos7 ~]# route add -net
1.1.1.0/24 gw 3.3.3.3
[root@centos7 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask 
Flags Metric Ref Use Iface
1.1.1.0 3.3.3.3 
255.255.255.0 UG 0 0 0
eth0
#vm1測試
[root@vm1 ~]# ping 3.3.3.4
PING 3.3.3.4 (3.3.3.4) 56(84) bytes of
data.
64 bytes from 3.3.3.4: icmp_seq=80 ttl=62
time=0.506 ms
64 bytes from 3.3.3.4: icmp_seq=81 ttl=62
time=0.594 ms

6.6 路由條目優化

  • 以虛擬機器1為例,除了第一個路由條目外,其他的路
    由條目其實都需要由1.1.1.2來轉發;
  • 所以我們可以統一用一條路由規則;(配置預設路由)
    1.刪除vm1上無用的路由;
[root@vm1 ~]# route del -net 2.2.2.0/24
[root@vm1 ~]# route del -net 2.2.2.0/24
# 需要刪除兩次;因為添加了兩次;
[root@vm1 ~]# route del -net 3.3.3.0/24
[root@vm1 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask 
Flags Metric Ref Use Iface
1.1.1.0 0.0.0.0 
255.255.255.0 U 101 0 0
eth1
10.0.0.0 0.0.0.0 
255.255.255.0 U 100 0 0
eth0

2.配置預設路由

[root@vm1 ~]# route add -net 0.0.0.0/0 gw
1.1.1.2
[root@vm1 ~]# #route add default gw 1.1.1.2
[root@vm1 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask 
Flags Metric Ref Use Iface
0.0.0.0 1.1.1.2 0.0.0.0 
UG 0 0 0 eth1

3.測試效果

[root@vm1 ~]# ping 1.1.1.2
[root@vm1 ~]# ping 2.2.2.2
[root@vm1 ~]# ping 2.2.2.3
[root@vm1 ~]# ping 3.3.3.3
[root@vm1 ~]# ping 3.3.3.4
[root@vm1 ~]# ping 4.4.4.4

4.其他虛擬機器按如上方式進行優化即可;

7. Ubuntu網路配置

7.1 配置靜態IP地址

  • 單網絡卡配置地址
root@example:~# cat /etc/netplan/00-installer-config.yaml
network:
ethernets:
ens33:
dhcp4: no
dhcp6: no
addresses: [10.0.0.130/24]
gateway4: 10.0.0.2
nameservers:
addresses: [223.5.5.5]
routes: # 靜態路由,去往172.100.0.0/24
下一跳是10.0.0.2
- to: 172.100.0.0/24
via: 10.0.0.2
version: 2
root@example:~# sudo netplan apply
  • 多網絡卡配置地址
root@example:~# cat /etc/netplan/00-installer-config.yaml
network:
ethernets:
ens33:
dhcp4: no
dhcp6: no
addresses: [10.0.0.130/24]
gateway4: 10.0.0.2
nameservers:
addresses: [223.5.5.5]
routes:
- to: 172.100.0.0/24
via: 10.0.0.2
ens38:
dhcp4: no
dhcp6: no
addresses: [10.0.0.140/24]
gateway4: 10.0.0.2
nameservers:
addresses: [223.5.5.5]
version: 2

7.2 配置round-robin

root@example:~# cat /etc/netplan/00-
installer-config.yaml
# This is the network config written by
'subiquity'
network:
version: 2
ethernets:
ens33:
dhcp4: no
dhcp6: no
ens38:
dhcp4: no
dhcp6: no
bonds:
bond0:
interfaces:
- ens33
- ens38
addresses: [10.0.0.133/24]
gateway4: 10.0.0.2
nameservers:
addresses: [223.5.5.5,223.6.6.6]
parameters:
mode: balance-rr
mii-monitor-interval: 100

#檢視狀態
root@example:~# cat /proc/net/bonding/bond0
# 檢視速率
root@example:~# ethtool bond0

7.3 配置active-backup

root@example:~# cat /etc/netplan/00-installer-config.yaml
# This is the network config written by
'subiquity'
network:
version: 2
ethernets:
ens33:
dhcp4: no
dhcp6: no
ens38:
dhcp4: no
dhcp6: no
bonds:
bond1:
interfaces:
- ens33
- ens38
addresses: [10.0.0.133/24]
gateway4: 10.0.0.2
nameservers:
addresses: [223.5.5.5,223.6.6.6]
parameters:
mode: active-backup
mii-monitor-interval: 100
# 應用配置
root@example:~# netplan apply
# 嘗試關閉正在使用的網絡卡
root@example:~# ifconfig ens33 down
# 再次檢視bond狀態
root@example:~# cat /proc/net/bonding/bond1
Bonding Mode: fault-tolerance (active-
backup)
Primary Slave: None
Currently Active Slave: ens38 # ens38
網絡卡頂替
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 0
Down Delay (ms): 0
Peer Notification Delay (ms): 0
Slave Interface: ens38
MII Status: up
Speed: 1000 Mbps
Duplex: full
Link Failure Count: 1
Permanent HW addr: 00:0c:29:de:3b:6f
Slave queue ID: 0
Slave Interface: ens33
MII Status: down # 介面已經被down
Speed: 1000 Mbps
Duplex: full
Link Failure Count: 2
Permanent HW addr: 00:0c:29:de:3b:65
Slave queue ID: 0

8. 核心引數調優

  • 核心引數的調整是為了更好的利用系統資源,以便程式更好的執行;

8.1 ip_local_port_range (必調)

主動連線方(客戶端)會佔用本地隨機埠,
TIME_WAIT 狀態會佔用本地埠,如果佔用過多導致本
地埠不足,TCP連線不能成功建立,可以通過調整參
數來增加本地埠的範圍;

1.檢視客戶端預設可用埠範圍

[root@client ~]# sysctl -a |grep
"net.ipv4.ip_local_port_range"
net.ipv4.ip_local_port_range = 32768 60999

2.調整埠數量,測試埠不夠用情況;

[root@client ~]# sysctl -w
net.ipv4.ip_local_port_range="10000 10002"

3.準備兩臺伺服器,一臺 nginx 伺服器,客戶端使用
curl 來訪問伺服器並主動關閉連線,在客戶端產生
TIME_WAIT 狀態的;伺服器: 10.0.0.100 nginx 、客戶端: 10.0.0.99 client

# 客戶端指令碼
[root@client ~]# cat test.sh
#!/usr/bin/bash
ip=10.0.0.100
date
for i in `seq 1 3`
do
echo "第 $i 次 curl "
curl -s http://$ip/ -o /dev/null
echo "RETURN: " $?
ss -ant |grep TIME
done
# 只有當 socket 距離上次收到資料包已經超過1秒時,
端口才會被重用
sleep 2
echo "第 4 次 curl "
date
curl -s http://$ip/ -o /dev/null
echo "RETURN: " $?
ss -ant|grep TIME

4.執行指令碼,從結果可見第4次 curl 時的狀態為7,失
敗,無法正常 curl ,說明埠已經被佔用完。

[root@client ~]# sh test.sh
2021年 07月 28日 星期三 14:21:52 CST
第 1 次 curl
RETURN: 0
TIME-WAIT 0 0 10.0.0.99:10000 
10.0.0.100:80
第 2 次 curl
RETURN: 0
TIME-WAIT 0 0 10.0.0.99:10002 
10.0.0.100:80
TIME-WAIT 0 0 10.0.0.99:10000 
10.0.0.100:80
第 3 次 curl
RETURN: 0
TIME-WAIT 0 0 10.0.0.99:10001 
10.0.0.100:80
TIME-WAIT 0 0 10.0.0.99:10002 
10.0.0.100:80
TIME-WAIT 0 0 10.0.0.99:10000 
10.0.0.100:80
第 4 次 curl
2021年 07月 28日 星期三 14:21:54 CST
RETURN: 7
TIME-WAIT 0 0 10.0.0.99:10001 
10.0.0.100:80
TIME-WAIT 0 0 10.0.0.99:10002 
10.0.0.100:80
TIME-WAIT 0 0 10.0.0.99:10000 
10.0.0.100:80

5.通過調整埠效果有限,因為 TIME_WAIT 需要等待
2MSL 時長,在這個時長內,最多也就能使用
ip_local_port_range 定義的埠範圍,其實這些是
不夠的,所以我們還可以使用 tcp_tw_reuse 引數來重
用 TIME_WAIT

8.2 tcp_tw_reuse

tw_reuse 表示埠重用,只有當
net.ipv4.tcp_timestamps = 1 ,
net.ipv4.tcp_tw_reuse = 1 兩個選項同時開啟時,
並且只有當 socket 距離上次收到資料包已經超過1秒
時, tcp_tw_reuse 埠重用才會有效
1.開啟 tcp_tw_reuse 以及 tcp_timestamps 核心引數

[root@client ~]# sysctl -w
net.ipv4.tcp_timestamps=1
[root@client ~]# sysctl -w
net.ipv4.tcp_tw_reuse=1

2.再次執行指令碼測試

[root@client ~]# sh test.sh
2021年 07月 28日 星期三 14:46:50 CST
第 1 次 curl
RETURN: 0
TIME-WAIT 0 0 10.0.0.99:10001 
10.0.0.100:80
第 2 次 curl
RETURN: 0
TIME-WAIT 0 0 10.0.0.99:10003 
10.0.0.100:80
TIME-WAIT 0 0 10.0.0.99:10001 
10.0.0.100:80
第 3 次 curl
RETURN: 0
TIME-WAIT 0 0 10.0.0.99:10003 
10.0.0.100:80
TIME-WAIT 0 0 10.0.0.99:10001 
10.0.0.100:80
TIME-WAIT 0 0 10.0.0.99:10002 
10.0.0.100:80
第 4 次 curl
2021年 07月 28日 星期三 14:46:52 CST
RETURN: 0 # 這裡發現第4次已經return 為0了,代
表埠已經被重用;
TIME-WAIT 0 0 10.0.0.99:10003 
10.0.0.100:80
TIME-WAIT 0 0 10.0.0.99:10001 
10.0.0.100:80
TIME-WAIT 0 0 10.0.0.99:10002 
10.0.0.100:80

8.3 tcp_max_tw_buckets

net.ipv4.tcp_max_tw_buckets 引數表示作業系統允
許 TIME_WAIT 數量的最大值,如果超過這個數字,
TIME_WAIT 套接字將立刻被清除,該引數預設為
180000 ,可以對其進行調整,確保 time-wait 狀態不消
耗太多的連線,以保證新連線可以正常請求;
1.引數調整

[root@client ~]# sysctl -w
net.ipv4.tcp_max_tw_buckets=2

2.測試驗證

[root@client ~]# sh test.sh
2021年 07月 28日 星期三 15:20:40 CST
第 1 次 curl
RETURN: 0
TIME-WAIT 0 0 10.0.0.99:12792 
10.0.0.100:80
第 2 次 curl
RETURN: 0
TIME-WAIT 0 0 10.0.0.99:12794 
10.0.0.100:80
TIME-WAIT 0 0 10.0.0.99:12792 
10.0.0.100:80
第 3 次 curl
RETURN: 0
TIME-WAIT 0 0 10.0.0.99:12794 
10.0.0.100:80
TIME-WAIT 0 0 10.0.0.99:12792 
10.0.0.100:80
第 4 次 curl
2021年 07月 28日 星期三 15:20:42 CST
RETURN: 0
TIME-WAIT 0 0 10.0.0.99:12794 
10.0.0.100:80
TIME-WAIT 0 0 10.0.0.99:12792 
10.0.0.100:80
TCP: time wait bucket table overflow
TCP: time wait bucket table overflow
TCP: time wait bucket table overflow

8.4 tcp_max_syn_backlog

一般我們將 ESTABLISHED 狀態的連線稱為全連線,而將
SYN_RCVD 狀態的連線稱為半連線, backlog 定義了處
於 SYN_RECV 的 TCP 最大連線數,當處於 SYN_RECV 狀態
的 TCP 連線數超過 tcp_max_syn_backlog 後,會丟棄後
續的 SYN 報文(也就是半連線池最大可接受的請求)關
閉cookies,否則容易干擾,造成不生效的情況。

當伺服器收到一個 SYN 後,它建立一個子連線加入到
SYN_RCVD 佇列。在收到 ACK 後,它將這個子連線移動到
ESTABLISHED 佇列。最後當用戶呼叫 accept() 時,會
將連線從 ESTABLISHED 佇列取出。
1.調整服務端引數

[root@oldxu ~]# sysctl -w
net.ipv4.tcp_max_syn_backlog=2

2.客戶端執行如下操作

# 禁止客戶端返回ack,模擬服務端SYN_RECV狀態
[root@client ~]# iptables -t filter -I
OUTPUT -p tcp --sport 22 -j ACCEPT
[root@client ~]# iptables -t filter -A
OUTPUT -p tcp -m tcp --tcp-flag SYN,ACK ACK
-j DROP
# 使用telnet連線遠端主機
[root@client ~]# telnet 10.0.0.100 22 &
[1] 11913
[root@client ~]# telnet 10.0.0.100 22 &
[2] 11916
[root@client ~]# telnet 10.0.0.100 22 &
[3] 11917
[root@client ~]# telnet 10.0.0.100 22 &
[4] 12012
[root@client ~]# Trying 10.0.0.100...

3.檢查服務端連線狀態

[root@web01 ~]# netstat -tn
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address 
Foreign Address State
tcp 0 0 10.0.0.100:22 
10.0.0.99:17304 SYN_RECV
tcp 0 0 10.0.0.100:22 
10.0.0.99:17302 SYN_RECV
tcp 0 0 10.0.0.100:22 
10.0.0.99:17300 SYN_RECV
# 核心會提示丟棄了一些請求
[root@web01 ~]# dmesg
[31204.380052] TCP: drop open request from
10.0.0.99/17320
[31205.382226] TCP: drop open request from
10.0.0.99/17320
  • 注意: SYN_RECV 有3條記錄,我們調整的限制2,怎
    麼多出了一條;是因為系統的判斷條件是 > 而不是>= ,

    所以當達到3條記錄時才算超過限制,所以有3
    條 SYN_RECV 記錄;

8.5 core_somaxconn

net.core.somaxconn 用於定義服務端全連線佇列的大
小,預設為128,對於生產環境而言,肯定是不夠用;

1.調整服務端全連線佇列大小為3

[root@server ~]# sysctl -w
net.core.somaxconn=2

2.服務端指令碼

[root@server ~]# cat server.c
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define BACKLOG 200
int main(int argc, char **argv)
{
int listenfd;
int connfd;
struct sockaddr_in servaddr;
listenfd = socket(PF_INET, SOCK_STREAM,
0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr =
htonl(INADDR_ANY);
servaddr.sin_port = htons(50001);
bind(listenfd, (struct sockaddr
*)&servaddr, sizeof(servaddr));
listen(listenfd, BACKLOG);
while(1)
{
sleep(1);
}
return 0;
}

3.編譯並啟動服務端指令碼

[root@server ~]# gcc server.c -o server
[root@server ~]# ./server

4.編寫客戶端指令碼

[root@client ~]# cat client.c
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in servaddr;
sockfd = socket(PF_INET, SOCK_STREAM,
0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(50001);
servaddr.sin_addr.s_addr =
inet_addr("10.0.0.100");
if (0 != connect(sockfd, (struct
sockaddr *)&servaddr, sizeof(servaddr)))
{
printf("connect failed!\n");
}
else
{
printf("connect succeed!\n");
}
sleep(30);
return 1;
}

5.編譯並啟動客戶端指令碼

[root@client ~]# gcc client.c -o client
[root@client ~]# ./client &
[1] 16368
[root@client ~]# connect succeed!
./client &
[2] 16370
[root@client ~]# connect succeed!
./client &
[3] 16371
[root@client ~]# connect succeed!
./client &
[4] 16372
[root@client ~]# connect succeed!
./client &
[5] 16375
[root@client ~]# connect succeed!

5.檢查服務端狀態(會發現已建立連線佇列就3條,其餘
都在半連線池中無法進入連線佇列)

[root@server ~]# netstat -nt | grep 50001
tcp 0 0 10.0.0.100:50001 
10.0.0.99:17405 SYN_RECV
tcp 0 0 10.0.0.100:50001 
10.0.0.99:17407 SYN_RECV
tcp 0 0 10.0.0.100:50001 
10.0.0.99:17399 ESTABLISHED
tcp 0 0 10.0.0.100:50001 
10.0.0.99:17403 ESTABLISHED
tcp 0 0 10.0.0.100:50001 
10.0.0.99:17401 ESTABLISHED

6.調整全連線佇列大小,然後再次啟動多次客戶端進行檢視

[root@server ~]# sysctl -w
net.core.somaxconn=10
[root@web01 ~]# ./server
# 檢視服務端連線狀態
[root@server ~]# netstat -nt | grep 50001
tcp 0 0 10.0.0.100:50001 
10.0.0.99:17431 SYN_RECV
tcp 0 0 10.0.0.100:50001 
10.0.0.99:17433 SYN_RECV
tcp 0 0 10.0.0.100:50001 
10.0.0.99:17425 ESTABLISHED
tcp 0 0 10.0.0.100:50001 
10.0.0.99:17417 ESTABLISHED
tcp 0 0 10.0.0.100:50001 
10.0.0.99:17419 ESTABLISHED
tcp 0 0 10.0.0.100:50001 
10.0.0.99:17415 ESTABLISHED
tcp 0 0 10.0.0.100:50001 
10.0.0.99:17421 ESTABLISHED
tcp 0 0 10.0.0.100:50001 
10.0.0.99:17409 ESTABLISHED
tcp 0 0 10.0.0.100:50001 
10.0.0.99:17429 ESTABLISHED
tcp 0 0 10.0.0.100:50001 
10.0.0.99:17411 ESTABLISHED
tcp 0 0 10.0.0.100:50001 
10.0.0.99:17413 ESTABLISHED
tcp 0 0 10.0.0.100:50001 
10.0.0.99:17427 ESTABLISHED
tcp 0 0 10.0.0.100:50001 
10.0.0.99:17423 ESTABLISHED
# 全連線佇列11條記錄,之所以會這樣,是因為系統採用>
而>=所以條目會+1
[root@server ~]# netstat -nt | grep 50001
|wc -l
13

8.6 tcp_syn_retries

net.ipv4.tcp_syn_retries 表示應用程式進行傳送
SYN 包時,在對方不返回 SYN + ACK 的情況下,核心默
認重試傳送 6 次 SYN 包,也就是說如果一直收不到對方返
回 SYN + ACK 那麼應用程式最大的超時時間就是
(1+2+4+8+16+32+64=127 秒) 這對於很多客戶端而言
是很難以接受的;

  • 第 1 次傳送 SYN 報文後等待 1s(2^0) ,如果超
    時,則重試
  • 第 2 次傳送後等待 2s(2^1) ,如果超時,則重試
  • 第 3 次傳送後等待 4s(2^2) ,如果超時,則重試
  • 第 4 次傳送後等待 8s(2^3) ,如果超時,則重試
  • 第 5 次傳送後等待 16s(2^4) ,如果超時,則重試
  • 第 6 次傳送後等待 32s(2^5) ,如果超時,則重試
  • 第 7 次傳送後等待 64s(2^6) ,如果超時,則超時
    失敗
    1.服務端配置 iptables 來丟棄指定埠的 SYN 報文
# 進來流量如果syn標誌位為1則拒絕
[root@server ~]# iptables -A INPUT -p tcp -
-dport 22 --syn -j DROP
# 服務端使用tcpdump抓包
[root@server ~]# tcpdump -i eth0 -n src
10.0.0.99 and dst 10.0.0.100 and port 22

2.然後客戶端使用 telnet 連線服務端指定埠

[root@client ~]# date '+ %F %T'; telnet
10.0.0.100 22; date '+ %F %T';
2021-07-29 23:32:57 # 開始時間
Trying 10.0.0.100...
telnet: connect to address 10.0.0.100:
Connection timed out
2021-07-29 23:35:05 # 結束時間

3.最後分析抓包結果,從 tcpdump 的輸出也可以看到,一
共發了7次SYN包(都是同一個seq號碼),第一次是正常請
求,後面6次是重試,正是該核心引數設定的值.

[root@server ~]# tcpdump -i eth0 -n src
10.0.0.7 and dst 10.0.0.100 and port 22
23:32:57.809282 IP 10.0.0.99.ndmp >
10.0.0.100.ssh: Flags [S], seq 2633109385,
23:32:58.812226 IP 10.0.0.99.ndmp >
10.0.0.100.ssh: Flags [S], seq 2633109385,
23:33:00.816151 IP 10.0.0.99.ndmp >
10.0.0.100.ssh: Flags [S], seq 2633109385,
23:33:04.820449 IP 10.0.0.99.ndmp >
10.0.0.100.ssh: Flags [S], seq 2633109385,
23:33:12.837846 IP 10.0.0.99.ndmp >
10.0.0.100.ssh: Flags [S], seq 2633109385,
23:33:28.884418 IP 10.0.0.99.ndmp >
10.0.0.100.ssh: Flags [S], seq 2633109385,
23:34:00.942801 IP 10.0.0.99.ndmp >
10.0.0.100.ssh: Flags [S], seq 2633109385,

4.修改客戶後端重試次數,在測試

[root@client ~]# sysctl -w
net.ipv4.tcp_syn_retries=2
# 再次測試
[root@client ~]# date '+ %F %T'; telnet
10.0.0.100 22; date '+ %F %T';
2021-07-29 23:39:15 # 起始時間
Trying 10.0.0.100...
2021-07-29 23:39:22 # 結束時間
  • 注意:作為代理伺服器這個值就應該調整

8.7 核心引數示例

[root@oldxu ~]# vim /etc/sysct.conf
# tcp優化
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_tw_buckets = 5000
net.ipv4.tcp_syncookies = 1 # 防止
SYN Flood攻擊,開啟後max_syn_backlog理論上沒有
最大值
net.ipv4.tcp_max_syn_backlog = 8192 # SYN半
連線佇列可儲存的最大值
net.core.somaxconn = 32768 # SYN全
連線佇列可儲存的最大值
# 修改TCP TIME-WAIT超時時間
https://help.aliyun.com/document_detail/155
470.html
# net.ipv4.tcp_tw_timeout = 5
# 重試
net.ipv4.tcp_syn_retries=2 # 傳送
SYN包重試次數,預設6
net.ipv4.tcp_synack_retries = 2 # 返回
syn+ack重試次數,預設5
# 其他
# net.ipv4.ip_forward = 1 # 支援轉
發功能;
# net.ipv4.ip_nonlocal_bind = 1 # 如果我
的應用程式需要繫結埠,需要指明具體的IP地址
# net.ipv4.tcp_keepalive_time = 600 # 當
keepalive啟動時,TCP傳送keepalive訊息的頻度;默
認是2小時,將其設定為10分鐘,可更快的清理無效連結
# 系統中允許存在檔案控制代碼最大數目(系統級)
fs.file-max = 204800
#
vm.swappiness = 0

本文來自部落格園,作者:GaoBeier,轉載請註明原文連結:https://www.cnblogs.com/gao0722/p/15087005.html