🐳Docker網絡

一.網絡基礎

Docker 使用到的與 Linux 網絡有關的技術分別有:網絡名稱空間、Veth、Iptables、網橋、路由python

1.什麼是網絡名稱空間

  • 爲了支持網絡協議棧的多個實例,Linux 在網絡協議棧中引入了網絡名稱空間(Network Namespace)
  • 這些獨立的協議棧被隔離到不一樣的命名空間中
  • 處於不一樣的命名空間的網絡協議棧是徹底隔離的,彼此之間沒法進行網 絡通訊,就好像兩個「平行宇宙」
  • 經過這種對網絡資源的隔離,就能在一個宿主機上虛擬多個不一樣的網絡環境

image-20201203095835616

ps : 若是不一樣網絡名稱空間之間要進行通訊該怎麼辦呢?linux

2.Veth 設備對

  • 引入 Veth 設備對就是爲了在不一樣的網絡名稱空間之間進行通訊
  • 利用它能夠直接將兩個網絡名稱空間連接起來, Veth 設備是成對出現
  • 像一對網卡, 咱們將其中一端稱爲另外一端的 peer

image-20201203100041308

2.1.底層原理實驗示例

  • 需求 : 創建兩個名稱空間, 並實現相互 ping
  • 查看, 添加, 刪除 namespace 命令
ip netns list                # 查看
ip netns add [namespace]     # 添加
ip netns delete [namespace]  # 刪除
  • 創建兩個名稱空間
[root@shawn ~]#ip netns add test1
[root@shawn ~]#ip netns add test2
[root@shawn ~]#ip netns list
test2
test1
  • 創建一對 veth
[root@shawn ~]#ip link add veth1 type veth peer name veth2
[root@shawn ~]#ip link

image-20201203100822449

  • 建立 veth 後, 咱們將 veth 分別添加到名稱空間 test1test2
[root@shawn ~]#ip link set veth1 netns test1
[root@shawn ~]#ip link set veth2 netns test2
  • 查看一下是否已經添加成功了
[root@shawn ~]#ip netns exec test1 ip link
[root@shawn ~]#ip netns exec test2 ip link

image-20201203101119038

image-20201203101141390

  • 添加完成後咱們就須要爲其設置 IP 了, 並將其狀態 up
[root@shawn ~]#ip netns exec test1 ip addr add 172.17.0.111/20 dev veth1
[root@shawn ~]#ip netns exec test2 ip addr add 172.17.0.112/20 dev veth2
[root@shawn ~]#ip netns exec test1 ip link set dev veth1 up
[root@shawn ~]#ip netns exec test2 ip link set dev veth2 up
  • 查看 IP 是否設置成功
[root@shawn ~]#ip netns exec test1 ip a
[root@shawn ~]#ip netns exec test2 ip a

image-20201203101635359

image-20201203101654298

  • 最後, 檢測一下是否能相互 ping
[root@shawn ~]#ip netns exec test1 ping 172.17.0.112
[root@shawn ~]#ip netns exec test2 ping 172.17.0.111

image-20201203101901104

image-20201203101912789

  • 成功

3.網橋

  • Linux 能夠支持多個不一樣的網絡,它們之間可以相互通訊,就須要一個網橋, 網橋就是二層的虛擬網絡設備
  • 它是把若干個網絡接口「鏈接」起來,從而報文可以互相轉發

image-20201203103048745

  • 網橋命令格式 : docker network [命令參數]
⚽查看當前系統有哪些網橋 "ls"
[root@shawn ~]#docker network ls
'''
NETWORK ID          NAME                DRIVER              SCOPE
befd59194a71        bridge              bridge              local
94f8e35f3357        host                host                local
79fb28a9a12e        none                null                local
'''

⚽建立網橋 "create"
[root@shawn ~]#docker network create shawn
ffac93578a0ce40395936d226bd097fd049ad077022419a9b6b074b6fe2f892b
[root@shawn ~]#docker network ls
'''
NETWORK ID          NAME                DRIVER              SCOPE
befd59194a71        bridge              bridge              local
94f8e35f3357        host                host                local
79fb28a9a12e        none                null                local
ffac93578a0c        shawn               bridge              local  #新建的網橋
'''

⚽查看網橋信息,格式 : "docker network inspect [網橋的名稱|網橋ID]"
[root@shawn ~]#docker network inspect shawn
'''
[
    {
        "Name": "shawn",
        "Id": "ffac93578a0ce40395936d226bd097fd049ad077022419a9b6b074b6fe2f892b",
        "Created": "2020-12-03T11:56:35.554136022+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]
'''

⚽刪除網橋 "rm"
[root@shawn ~]#docker network rm shawn
shawn
[root@shawn ~]#docker network ls
'''
NETWORK ID          NAME                DRIVER              SCOPE
befd59194a71        bridge              bridge              local
94f8e35f3357        host                host                local
79fb28a9a12e        none                null                local
''' # "Shawn"被刪除了

⚽清理網橋 "prune", 咱們先建立多個網橋,而後一次性清除
[root@shawn ~]#docker network create shawn1
f4d2f2b57b48cd35b3cc9eddad0377cae95d213032ed0d6a92e9de9571adeb4e  #建立成功
[root@shawn ~]#docker network create shawn2
ea66ed0d06adbe7f5211f3ae38b6edeb47dffac0f53240e9204fd3dcaf4670d5  #建立成功
[root@shawn ~]#docker network create shawn3
222d6e298d6091cea0a6229e19c84825a41ea92b7c0b512db47c858dde7259f0  #建立成功
[root@shawn ~]#docker network prune
WARNING! This will remove all custom networks not used by at least one container.
Are you sure you want to continue? [y/N] y  # 問你是否要這樣作"yes"
Deleted Networks:  # 將要刪除如下網橋
shawn1
shawn2
shawn3
[root@shawn ~]#docker network ls
'''
NETWORK ID          NAME                DRIVER              SCOPE
befd59194a71        bridge              bridge              local
94f8e35f3357        host                host                local
79fb28a9a12e        none                null                local
'''  # 發現並無 "shawn"系列的網橋

4.Iptables

  • iptables是 linux 系統自帶的優秀且徹底免費的基於包過濾的防火牆工具、它的功能十分強大、使用很是靈活、能夠對流入、流出及流經服務器的數據包進行精細的控制

5.總結

network namespace 主要提供了關於網絡資源的隔離,包括網絡設備、IPv4 和 IPv6 協議棧、IP 路由 表、防火牆、/proc/net 目錄、/sys/class/net 目錄、端口(socket)等
linux Bridge 功能至關於物理交換機,爲連在其上的設備(容器)轉發數據幀。如 docker0 網橋
iptables 主要爲容器提供 NAT 以及容器網絡安全
veth pair 兩個虛擬網卡組成的數據通道。在 Docker 中,用於鏈接 Docker 容器和 Linux Bridge。一端在容器中做爲 eth0 網卡,另外一端在 Linux Bridge 中做爲網橋的一 個端口

二.Docker網絡模式

安裝Docker時,它會自動建立三個網絡,bridge(建立容器默認鏈接到此網絡)、 none 、hostnginx

  • docker network ls : 查看當前系統有哪些網絡(網橋)
[root@shawn ~]#docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
befd59194a71        bridge              bridge              local
94f8e35f3357        host                host                local
79fb28a9a12e        none                null                local

1.原理

  • Docker使用Linux橋接,在宿主機虛擬一個Docker容器網橋(docker0)
  • Docker啓動一個容器時會根據Docker網橋的網段分配給容器一個IP地址,稱爲Container-IP, 同時Docker網橋是每一個容器的默認網關
  • 由於在同一宿主機內的容器都接入同一個網橋,這樣容器之間就可以經過容器的Container-IP直接通訊
  • Docker網橋是宿主機虛擬出來的,並非真實存在的網絡設備,外部網絡是沒法尋址到的,這也意味着外部網絡沒法經過直接Container-IP訪問到容器
  • 若是容器但願外部訪問可以訪問到,能夠經過映射容器端口到宿主主機(端口映射),即docker run建立容器時候經過 -p-P 參數來啓用,訪問容器的時候就經過 [宿主機IP]:[容器向外暴露的端口] 訪問容器

2.四類網絡模式

網絡模式 設置方法 簡介
Host --network host 容器將不會虛擬出本身的網卡,配置本身的IP等,而是使用宿主機的IP和端口
Bridge --network bridge(默認此模式) 此模式會爲每個容器分配、設置IP等,並將容器鏈接到一個docker0虛擬網橋,經過docker0網橋以及Iptables nat表配置與宿主機通訊
None -- network none 該模式關閉了容器的網絡功能
Container --network "container:[共享容器名稱]" 建立的容器不會建立本身的網卡,配置本身的IP,而是和一個指定的容器共享IP、端口範圍

2.一、Host 模式

  • 至關於Vmware中的橋接模式,與宿主機在同一個網絡中,但沒有獨立IP地址
  • 可是,容器的其餘方面,如文件系統、進程列表等仍是和宿主機隔離的
  • 格式 : docker run --network host [鏡像名稱或ID]
[root@shawn ~]#docker run -d --network host nginx:latest

img

2.二、Container 模式

  • 這個模式指定新建立的容器和已經存在的一個容器共享一個Network Namespace,而不是和宿主機共享
  • 新建立的容器不會建立本身的網卡,配置本身的IP,而是和一個指定的容器共享IP、端口範圍等
  • 一樣,兩個容器除了網絡方面,其餘的如文件系統、進程列表等仍是隔離的。兩個容器的進程能夠經過lo網卡設備通訊
  • 格式 : docker run --network "containe:[共享容器名稱]" [鏡像名稱或ID]
  • 實驗:
⚽建立共享容器 "cont01"
[root@shawn ~]#docker run -dit --name cont01 busybox:latest sh

⚽建立連接容器 "cont02", 並指定網絡模式 "container"
[root@shawn ~]#docker run -dit --name cont02 --network "container:cont01" busybox:latest sh

⚽查看兩個容器的 "ip", 發現同樣
[root@shawn ~]#docker exec cont01 ip a
[root@shawn ~]#docker exec cont02 ip a

image-20201203114012145

image-20201203114036897

img

2.三、None 模式

  • 該模式將容器放置在它本身的網絡棧中,可是並不進行任何配置
  • 該模式關閉了容器的網絡功能 , 通常是由於容器並不須要網絡(例如只須要寫磁盤卷的批處理任務)
  • 格式 : docker run --network none [鏡像名稱或ID]
[root@shawn ~]#docker run -dit --network none --name none_test busybox:latest sh

img

2.四、Bridge 模式

  • 至關於Vmware中的Nat模式,容器使用獨立network Namespace,並鏈接到docker0虛擬網卡(默認模式)
  • 虛擬網橋的工做方式和物理交換機相似,這樣主機上的全部容器就經過交換機連在了一個二層網絡中
  • bridge模式是docker的默認網絡模式,不寫 --network 參數,就是bridge模式
  • 使用docker run -p時,docker實際是在iptables作了DNAT規則,實現端口轉發功能

image-20201203115027432

相關文章
相關標籤/搜索