Docker網絡配置進階

Docker啓動會默認創建docker0虛擬網橋,是Linux的一個bridge,可以理解成一個軟件交換機。它會在掛載到它的網口之間進行轉發。

 

之後所有容器都是在172.17.0.x的網段上,並且可以相互通訊,包括和宿主主機通訊。

當創建一個Docker容器的時候,同時會創建一對veth pair(虛擬設備接口)

(https://www.cnblogs.com/bakari/p/10613710.html)

接口(當數據包發送到一個接口時,另外一個接口也可以收到相同的數據包)。這對接口一端在容器內,即eth0;另一端在本地並被掛載到docker0 網橋,名稱以veth開頭。通過這種方式,主機可以跟容器通信,容器之間也可以相互通信。Docker就創建了在主機和所有容器之間一個虛擬共享網絡。

大概就是書上的這個圖:

 

一些docker網絡相關的命令列表

-b BRIDGE  或  --bridge=BRIDGE  指定容器掛載的網橋

--bip=CIDR  定製 docker0 的掩碼

-H SOCKET...  或  --host=SOCKET...  Docker 服務端接收命令的通道

--icc=true|false  是否支持容器之間進行通信

--iptables=true|false  是否允許 Docker 添加 iptables 規則

--mtu=BYTES  容器網絡中的 MTU(最大傳輸單元)

下面2個命令選項既可以在啓動服務時指定,也可以在啓動容器時指定。在 Docker服務啓動的時候指定則會成爲默認值,後面執行  docker run  時可以覆蓋設置的默認值

--dns=IP_ADDRESS...  使用指定的DNS服務器

--dns-search=DOMAIN...  指定DNS搜索域

 

最後這些選項只有在  docker run  執行時使用,因爲它是針對容器的特性內容。

-h HOSTNAME  或  --hostname=HOSTNAME  配置容器主機名

--link=CONTAINER_NAME:ALIAS  添加到另一個容器的連接

--net=bridge|none|container:NAME_or_ID|host  配置容器的橋接模式

-p SPEC  或  --publish=SPEC  映射容器端口到宿主主機

-P or --publish-all=true|false  映射容器所有端口到宿主主機

 

容器訪問控制

容器訪問控制,主要通過Linux上的iptables防火牆來進行管理和實現。

容器想要訪問外部網絡,需要本地系統的轉發支持。在Linux系統中,檢查轉發是否打開。

sysctl net.ipv4.ip_forward

結果net.ipv4.ip_forward = 1中1是打開,如果是0就是沒打開,沒打開則用

sysctl -w net.ipv4.ip_forward=1命令設置成打開。

如果在啓動 Docker 服務的時候設定  --ip-forward=true  , Docker 就會自動設定系統的  ip_forward  參數爲 1

 

容器之間的訪問

    容器之間的訪問,需要兩方面的支持。

    1.容器的網絡拓撲是否已經互聯。默認情況下,所有容器都會被連接到docker0網橋上。

    2.本地系統的防火牆軟件--iptables是否允許通過。

 

訪問所有端口

當啓動Docker服務(dockerd)的時候,默認會添加一條轉發策略到本地主機iptables的FORWARD鏈上。策略爲通過(ACCEPT)還是禁止(DROP)取決於配置 --icc=true(缺省值)還是--icc=false。如果手動指定--iptables=false則不會添加iptables規則。

所以說在默認情況下,不同容器之間是允許網絡互通的。如果爲了安全考慮,可以在

/etc/docker/daemon.json文件中配置{"icc": false}來禁止。

訪問指定端口

在通過--icc關閉網絡訪問後,可以通過link選項來訪問容器的開放端口。

link=CONTAINER_NAME:ALIAS

例:

    在啓動 Docker 服務時,可以同時使用 icc=false --iptables=true  參數來關閉允許相互的網絡訪問,並讓 Docker 可以修改系統中的  iptables  規則。

PS:    --link=CONTAINER_NAME:ALIAS  中的  CONTAINER_NAME  目前必須是Docker 分配的名字,或使用  --name  參數指定的名字。主機名則不會被識別。

 

映射容器端口到宿主主機的實現

    默認情況容器可以主動訪問到外部網絡,但是外部網絡無法訪問到容器。

容器訪問外部實現

容器所有到外部網絡的鏈接,源地址都會被NAT成本地系統的IP地址。這是使用iptables的源地址僞裝操作實現的。

查看主機NAT規則sudo iptables -t nat -nL

上面是所有源地址在172.17.0.0/16網段,目標地址是所有0.0.0.0/0,的流量動態僞裝成從系統網卡發出。MASQUERADE 跟傳統 SNAT的好處是它能動態從網卡獲取地址。

 

外部訪問容器實現

容器允許外部訪問,可以在docker run 時候通過 -p 或 -P 參數來啓用。原理是在本地iptable的net表中添加相應的規則。

比如-p 80:80可能會這樣

上面是所有地址的80都指向了容器裏面的80,如果想鎖定地址可以

-p IP:host_port:container_port  或  -p IP::port

也可以直接配置/etc/docker/daemon.json 中 {"ip": "0.0.0.0"}

配置docker0網橋

Docker服務默認創建docker0 網橋,默認指定了docker0接口的IP地址和子網掩碼,讓主機和容器之間可以通過網橋相互通信,還給出了MTU(接口允許接收的做大傳輸單元),或宿主主機網絡路由上支持的默認值。

--bip=CIDR  IP 地址加掩碼格式,例如 192.168.1.5/24

--mtu=BYTES  覆蓋默認的 Docker mtu 配置

也可以在配置文件中配置 DOCKER_OPTS,然後重啓服務。

可以通過brctl show來查看網橋和端口連接信息。

 

每次創建一個新容器的時候,Docker從可用的地址段中選擇一個空閒的IP地址分配給容器的eth0端口。使用本地主機上docker0接口的IP作爲所有容器的默認網關

 

自定義網橋

除了默認的docker0網橋,用戶也可以指定網橋來鏈接各個容器。

啓動docker服務的時候使用  -b BRIDGE  或 --bridge=BRIDGE  來指定使用的網橋。如果服務已經運行,就停掉服務,刪除就網橋。

sudo systemctl stop docker

sudo ip link set dev docker0 down

sudo brctl delbr docker0

然後創建網橋

sudo brctl addbr bridge0

sudo ip addr add 192.168.5.1/24 dev bridge0

sudo ip link set dev bridge0 up

查看確認網橋創建並啓動

ip addr show bridge0

在 Docker 配置文件  /etc/docker/daemon.json  中添加如下內容,即可將Docker 默認橋接到創建的網橋上{"bridge": "bridge0",}

啓動 Docker 服務systemctl start docker

新建一個服務

docker run -d -P training/webapp python app.py

創建一個點到點的連接

默認情況下Docker會將所有容器鏈接到由docker0提供的虛擬子網中。但是有的時候可能需要兩個容器直接通訊,而不是通過主機網橋進行橋接。方法是創建一對peer接口,分別放在兩個容器中,配置成點到點鏈路類型。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章