Docker單機網絡上


前言

Docker系列文章:

此篇是Docker系列的第六篇,大家一定要按照我做的Demo都手敲一遍,印象會更加深刻的,加油!

  1. 為什么要學習Docker
  2. Docker基本概念
  3. Docker鏡像基本原理
  4. Docker容器數據卷
  5. Dockerfile

網卡

網卡是一塊計算機硬件。其特點是每一個網卡都有獨立的MAC地址,用戶可以通過電纜進行相互之間的連接。其主要功能是將數據封裝成以太網中的幀,通過鏈路管理進行傳輸,接受數據后,對數據進行編碼和譯碼。其優點是提高了CPU的利用率通過鏈路管理進行傳輸,提升了CPU的性能。 再用通俗一點的話解釋,網卡其實就是七層或者四層網絡模型的門戶,復制接收和轉發數據如下圖:

Network Namespace介紹

Network Namespace在邏輯上是網絡堆棧的一個副本,它有自己的路由、防火牆規則和網絡設備。默認情況下,子進程繼承其父進程的Network Namespace。如果不顯式創建新的Network Namespace,所有進程都從 init 進程繼承相同的默認Network Namespace。

每個新創建的Network Namespace默認有一個本地回環接口 lo,除此之外,所有的其他網絡設備(物理/虛擬網絡接口,網橋等)只能屬於一個Network Namespace。每個Socket也只能和一個Network Namespace通信。

創建Network Namespace

備注:采用的環境為阿里雲CentOS 8.2

  1. 檢查默認的Network Namespace 的 ID;

    readlink /proc/$$/ns/net
  2. 創建名為networknamespacetest的Network Namespace;

     #創建名為networknamespacetest的Network Namespace
     ip netns add networknamespacetest
     #檢查netns是否創建成功
     ls /var/run/netns
  3. 在networknamespacetest中創建一個bash進程並且查看Network Namespace的ID;

      #創建bash進程
      ip netns exec networknamespacetest bash
      #查看Network Namespace的ID
      readlink /proc/$$/ns/net
  4. 經過上面可以得出每個Network Namespace都是相互隔離的,接下來我們看下networknamespacetest有什么構成;

     ip addr
  5. Network Namespace由本地回環接口 lo構成,並且這個接口是處於關閉狀態的,接下來我們啟動這個回環接口;

    ip link set lo up
  6. 測試lo的連通性;

兩個Network Namespace之間如何通信

Veth-Pair

什么是Veth-Pair

Veth是Linux中一種虛擬出來的網絡設備,Veth設備總是成對出現,所以一般也叫Veth-Pair。Veth-Pair特點就是無法單獨存在,刪除其中一個,另一個也會自動消失。Veth的兩頭都直接連着網絡協議棧,所以你創建一個Veth對,主機上就會多2個網卡。

Veth-Pair作用

Veth-Pair作用就是反向流轉數據,從一頭發數據,就會從另一頭收到數據。Veth-Pair常常充當着一個橋梁,連接着各種虛擬網絡設備。常見用途是連接兩個Netwok Namespace,或者連接Linux-Bridge、OVS 之類的。

實戰
  1. 創建兩個Network Namespace network01和network02;

     ip netns add network01
     ip netns add network02
  2. 創建一對Veth設備,默認情況下會自動為Veth-Pair生成名稱,這里為了方便我們測試,我們在創建時指定 Veth-Pair的名稱;

     #創建Veth-Pair
     ip link add veth01 type veth peer name veth02
     #查看主機中Veth-Pair
     ip link ls   
  3. 把這一對Veth-Pair分別放到Network Namespace network01 和 network02中;

     #綁定
     ip link set veth01 netns network01
     ip link set veth02 netns network02

     #查看namespace組成
     ip netns exec network01 ip addr
     ip netns exec network02 ip addr

     #查看主機中是否存在Veth-Pair
     ip link ls

    查看network01和network02中的網絡資源,發現各自多了一個網卡,也就是veth設備的兩個端點,如下圖:

​ 當我們把Veth-Pair分配到Network Namespace中后,在主機上就看不到它們了,如下圖:

  1. 給這些Veth-Pair分配IP並啟用它們;
#啟動設備veth01
ip netns exec network01 ip link set veth01 up
#綁定IP
ip netns exec network01 ip addr add 10.0.1.1/24 dev veth01
#設置IP路由
ip netns exec network01 ip route

#啟動設備veth02
ip netns exec network02 ip link set veth02 up
#綁定IP
ip netns exec network02 ip addr add 10.0.1.2/24 dev veth02
#設置IP路由
ip netns exec network02 ip route
  1. 通過ping命令來驗證兩個Network Namespace是否可以通信;

    ip netns exec network01 ping -c 3 10.0.1.2

至此我們就完成兩個Network Namespace之間的通信。

Bridge

什么是Bridge

Linux Bridge(網橋)是工作於二層的虛擬網絡設備,功能類似於物理的交換機。Bridge可以綁定其他Linux網絡設備作為從設備,並將這些設備虛擬化為端口,當一個從設備被綁定到Bridge上時,就相當於真實網絡中的交換機端口插入了一個連接有終端的網線。Bridge有多個端口,數據可以從任何端口進來,進來之后從哪個口出去和物理交換機的原理差不多。

Bridge作用

Veth-Pair可以實現兩個Network Namespace之間的通信,但是當需要在多個Network Namespace之間通信的時候,光靠Veth-Pair就顯得有一些麻煩了,我們需要在Network Namespace創建很多個Veth才能和多個Network Namespace通信,我們可以把很多Veth-Pair綁定到Bridge上面,Network Namespace就能連通了多個Network Namespace,當需要通信的時候,Network Namespace只要往Bridge發報文,所有Veth-Pair全都可以收到報文信息。

實戰
  1. 創建一個br0的網橋,並設置上線;

    ip link add br0 type bridge
    ip link set dev br0 up
    ip addr
  2. 創建Veth-Pair;

    #創建3個 veth pair
    ip link add type veth
    ip link add type veth
    ip link add type veth
  3. 創建Network Namespace;

    #創建3個Network Namespace
    ip netns add net0
    ip netns add net1
    ip netns add net2
  4. 將Veth-Pair的一邊掛到Network Namespace中,另一邊掛到bridge上,並設IP地址;

    #配置net0
    ip link set dev veth1 netns net0
    ip netns exec net0 ip link set dev veth1 name eth0
    ip netns exec net0 ip addr add 10.0.1.1/24 dev eth0
    ip netns exec net0 ip link set dev eth0 up
    ip link set dev veth0 master br0
    ip link set dev veth0 up


    #配置net1
    ip link set dev veth3 netns net1
    ip netns exec net1 ip link set dev veth3 name eth0
    ip netns exec net1 ip addr add 10.220.1.2/24 dev eth0
    ip netns exec net1 ip link set dev eth0 up
    ip link set dev veth2 master br0
    ip link set dev veth2 up


    #配置net2
    ip link set dev veth5 netns net2
    ip netns exec net2 ip link set dev veth5 name eth0
    ip netns exec net2 ip addr add 10.220.1.3/24 dev eth0
    ip netns exec net2 ip link set dev eth0 up
    ip link set dev veth4 master br0
    ip link set dev veth4 up
  5. 給br0設置IP;

    ip link set dev br0 down
    ip addr add 10.220.1.0/24 dev br0
    ip link set dev br0 up
    ip netns exec net0 ping -c 2 10.220.1.3
  6. 解決ping不通的問題,因為系統為bridge開啟了iptables功能,導致所有經過br0的數據包都要受iptables里面規則的限制,我在虛擬機已經安裝了Docker,Docker將iptables里面filter表的FORWARD鏈的默認策略設置成了drop,於是所有不符合docker規則的數據包都不會被forward,導致你這種情況ping不通;

    解決辦法有兩個:

    第一個就是關閉系統bridge的iptables功能,這樣數據包轉發就不受iptables影響了:

    echo0 >/proc/sys/net/bridge/bridge-nf-call-iptables;

    第二就是為br0添加一條iptables規則,讓經過br0的包能被forward:

     iptables -A FORWARD -i br0 -j ACCEPT;
  7. 驗證;

以上涉及的Linux技術其實已經和ocker底層的網絡技術有些類似,這里先整體介紹一下,下篇我們對Docker的網絡進行探究一下。

結束

歡迎大家點點關注,點點贊!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM