1. 程式人生 > >Docker網路介紹

Docker網路介紹


title: Docker網路
tags: Docker


        大量的網際網路應用服務包括多個服務元件,這往往需要多個容器之間通過網路通訊進行相互配合。

一、網路基礎

        在瞭解Docker的網路之前,必須先認識Docker所依賴的幾個linux技術,這對理解docker的網路有幫助。

        Docker的網路實現其實就是利用了 Linux上的網路名稱空間和虛擬網路裝置(特別是veth pair)。熟悉這兩部分的基本概念,可以有助於理解 Docker網路的實現過程。

1.名稱空間

        Linux Namespaces機制提供一種資源隔離方案。PID,IPC,Network等系統資源不再是全域性性的,而是屬於特定的Namespace。每個Namespace裡面的資源對其他Namespace都不可見。

        一個Network Namespace提供了一份獨立的網路環境,包括網絡卡、路由、Iptable規則等都與其他的Network Namespace隔離。一個Docker容器“通常”會分配一個獨立的Network Namespace。這樣每個docker容器就好像擁有了一套獨立的網路環境,甚至以為自己霸佔了全部的主機,也許這也是使人們經常認為容器就是虛機的原因之一吧。

現在我們就來演示一下:

1.1我們先執行兩個busybox容器:

docker run -d --name test1 busybox /bin/sh -c "while true; do sleep 3600; done"

docker run -d --name test2 busybox /bin/sh -c "while true; do sleep 3600; done"

1.2 檢視2個容器網路

docker exec -it test1 ip a
docker exec -it test2 ip a


我們可以看到test1和test2是兩個不同的網路環境。
1.3新增namespace

ip netns add test1
ip netns add test2

1.4檢視本機的namespace

ip netns exec test1 ip a
ip netns exec test2 ip a


namespace預設是DOWN的狀態

2.Veth裝置對

        Veth裝置對可以在不同的網路名稱空間之間通訊,用他們可以連線兩個網路名稱空間。一對veth裝置就像網線的兩頭一樣。

1.把namespace變成up狀態

ip netns exec test1 ip link set dev lo up

狀態變成了 unknown,為什麼是unknown呢,因為當前的test1沒有被連通。

2.建立並檢視link

ip link add veth-test1 type veth peer name veth-test2
檢視linkip link

3.新增veth-test1 到namespace

ip link set veth-test1 netns test1

4.新增並檢視veth-test2

ip link set veth-test2 netns test2
ip netns exec test2 ip link

3.網橋

        簡單來說,橋接就是把一臺機器上的若干個網路介面“連線”起來。其結果是,其中一個網口收到的報文會被複制給其他網口併發送出去。以使得網口之間的報文能夠互相轉發。類似交換機。

        linux核心支援網口的橋接與交換機有一點點不同不同,交換機只是一個二層裝置,對於接收到的報文,要麼轉發、要麼丟棄。而執行著linux核心的機器本身就是一臺主機,有可能就是網路報文的目的地。其收到的報文除了轉發和丟棄,還可能被送到網路協議棧的上層(網路層),從而被自己消化。

        在docker啟動時,會在主機上建立一個docker0網橋。通過docker0在同一個主機上的容器之間都可以通訊,外部的訊息也可以經過docker0進入容器。

1.為test1和test2分配IP地址

ip netns exec test1 ip addr add 192.168.1.1/24 dev veth-test1
ip netns exec test2 ip addr add 192.168.1.1/24 dev veth-test2

2.link並啟動

ip netns exec test1 ip link set dev veth-test1 up
ip netns exec test2 ip link set dev veth-test2 up

3.兩個namespace可以ping通了

ip netns exec test1 ping 192.168.1.2

二、網路建立過程

        Docker建立一個容器的時候,會具體執行如下操作:

  • 建立一對虛擬介面,分別放到本地主機和新容器的名稱空間中。
  • 本地主機一端的虛擬介面連線到預設的 docker0網橋或指定網橋上,並具有一個以veth開頭的唯一名字,如veth1234。
  • 容器一端的虛擬介面將放到新建立的容器中,並修改名字作為eth0。這個介面只在容器的名稱空間可見。
  • 從網橋可用地址段中獲取一個空閒地址分配給容器的eth0(例如172.17.0.2/16),並配置預設路由閘道器為 docker網絡卡的內部介面 docker的IP地址(例如172.17.42./16)。

        完成這些之後,容器就可以使用它所能看到的eth0虛擬網絡卡來連線其他容器和訪問外部網路。

三、埠對映

        在啟動容器的時候,如果不指定對應引數,在容器外部是無法通過網路來訪問容器內的網路應用和服務的。
        當容器中執行一些網路應用,要讓外部訪問這些應用時,可以通過-P或-p引數來指定埠對映。當使用-P標記時, Docker會隨機對映一個

我們先演示下沒有對映埠的情況:
1.啟動一個nginx容器

docker run --name web -d nginx

2.檢視橋接網路狀態

docker network inspect bridge


獲得IP:172.17.0.4

  1. 在容器內訪問

curl http://172.17.0.4

  1. 在容器外訪問

curl http://172.17.0.4

訪問被拒絕

現在我們新增埠演示:
1.先停止並刪除容器

docker stop web
docker rm web

2.重新建立容器,並指定埠對映

docker run --name web -d -p 80:80 nginx

3.再來測試外部訪問,為了能更好的感受到,我們使用瀏覽器訪問

四、預設網路


安裝Docker時,它會自動建立三個網路:bridge NetWork(橋接網路)、Host NetWork (主機網路)、None NetWork (無網路)

這三個網路都是用於單機。

        這三個網路內置於Docker中。執行容器時,可以使用 --network或者-- net標誌指定容器應連線到的網路。

        bridge網路代表docker0所有Docker安裝中存在的網路。除非你使用該docker run --network=<NETWORK>選項指定,否則Docker守護程式預設將容器連線到此網路。。

        我們可以使用docker network inspect <net> 來檢視某個網路資訊。

例:docker network inspect bridge

五、Docker網路模式

Docker有以下4種網路模式:

  • Bridge模式:使用–net=bridge指定,預設設定;
  • Host模式:使用–net=host指定;
  • Container模式:使用–net=container:NAME_or_ID指定;
  • None模式:使用–net=none指定。

你可以使用以docker network ls命令列出這些網路:

1.Bridge

        Bridge是Docker網路預設模式,相當於Vmware中的Nat模式,容器使用獨立network Namespace,並連線到docker0虛擬網絡卡(預設模式)。通過docker0網橋以及Iptables nat表配置與宿主機通訊;bridge模式是Docker預設的網路設定,此模式會為每一個容器分配Network Namespace、設定IP等,並將一個主機上的Docker容器連線到一個虛擬網橋上。

在Bridge模式下:

  • 主機上面會有一個docker0的網橋;
  • 每個容器都與docker0連通,所以同主機上的容器之間也連通;
  • 每個主機上容器的地址都是從172.17.0.2開始往後分。

安裝brctl

yum -y install brige-utils

檢視本機的veth

brctl show

2.Host

        相當於Vmware中的橋接模式,與宿主機在同一個網路中,但沒有獨立IP地址。如果啟動容器的時候使用host模式,那麼這個容器將不會獲得一個獨立的Network Namespace,而是和宿主機共用一個Network Namespace。容器將不會虛擬出自己的網絡卡,配置自己的IP等,而是使用宿主機的IP和埠。

3.None

        在這種模式下,Docker容器擁有自己的Network Namespace,但是,並不為Docker容器進行任何網路配置。也就是說,這個Docker容器沒有網絡卡、IP、路由等資訊。需要我們自己為Docker容器新增網絡卡、配置IP等。以下情況下是有用的:容器並不需要網路。

4.Container

        這個模式指定新建立的容器和已經存在的一個容器共享一個Network Namespace,而不是和宿主機共享。新建立的容器不會建立自己的網絡卡,配置自己的IP,而是和一個指定的容器共享IP、埠範圍等。同樣,兩個容器除了網路方面,其他的如檔案系統、程序列表等還是隔離的。