0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

精通Docker網(wǎng)絡(luò):Bridge驅(qū)動(dòng)深度解析

馬哥Linux運(yùn)維 ? 來源:cnblogs ? 2024-03-31 15:58 ? 次閱讀

dokcer0 網(wǎng)橋

在 Ubuntn 上安裝 docker 后,宿主機(jī)上默認(rèn)被創(chuàng)建了一個(gè)名為 docker0 的網(wǎng)卡,其 IP 為 172.17.0.1/16:

5c788c4e-eea3-11ee-a297-92fbcf53809c.png

有了這個(gè)網(wǎng)卡,宿主機(jī)還會(huì)在內(nèi)核的路由表中添加一條到達(dá)相應(yīng)網(wǎng)絡(luò)的靜態(tài)路由記錄:

5c87ca74-eea3-11ee-a297-92fbcf53809c.png

這條路由信息表示所有目的 IP 為 172.17.0.0/16 的數(shù)據(jù)包都會(huì)從 docker0 網(wǎng)卡發(fā)出。接下來我們創(chuàng)建一個(gè)名為 mycon 的容器,并觀察其網(wǎng)絡(luò)配置:

5c960cba-eea3-11ee-a297-92fbcf53809c.png

在 mycon 容器內(nèi)可以看到兩塊網(wǎng)卡:lo 和 eth0。其中 lo 是容器的回環(huán)網(wǎng)卡,eth0 是容器與外界通信的網(wǎng)卡,eth0 的 IP 信息為 172.17.0.2/16,和宿主機(jī)上的網(wǎng)卡 bridge0 在同一網(wǎng)段中。查看 mycon 的路由信息:

5ca8cc06-eea3-11ee-a297-92fbcf53809c.png

mycon 容器的默認(rèn)網(wǎng)關(guān)正是宿主機(jī)的 docker0 網(wǎng)卡。通過 ping 命令測(cè)試與外網(wǎng)的連通性,此時(shí)容器 mycon 是可以連通外網(wǎng)的,這就說明 mycon 的 eth0 網(wǎng)卡與宿主機(jī)的 docker0 網(wǎng)卡是連通的。

下面我們來查看宿主機(jī)的網(wǎng)絡(luò)設(shè)備:

5cb6c766-eea3-11ee-a297-92fbcf53809c.png

發(fā)現(xiàn)多了一個(gè)以 "veth" 開頭的網(wǎng)卡,這是一個(gè) veth 設(shè)備。而 veth 設(shè)備總是成對(duì)出現(xiàn)的,那么與 veth7537a16 配對(duì)的就應(yīng)該是 mycon 容器中的 eth0 了。既然 mycon 容器中的 eth0 是與 docker0 連通的,那么 veth7537a16 也應(yīng)該是與 docker0 連通的。因此docker0 并不是一個(gè)簡(jiǎn)單的網(wǎng)卡設(shè)備,而是一個(gè)網(wǎng)橋!下圖展示了 docker bridge 網(wǎng)絡(luò)模式的拓?fù)鋱D:

5cd3f322-eea3-11ee-a297-92fbcf53809c.png

事實(shí)上,docker 創(chuàng)建了 docker0 網(wǎng)橋,并以 veth pair 連接各個(gè)容器的網(wǎng)絡(luò),容器中的數(shù)據(jù)通過 eth0 發(fā)送到 docker0 網(wǎng)橋上,并由 docker0 網(wǎng)橋完成轉(zhuǎn)發(fā)。這里網(wǎng)橋的概念等同于交換機(jī),為連在其上的設(shè)備轉(zhuǎn)發(fā)數(shù)據(jù)幀。網(wǎng)橋上的 veth 網(wǎng)卡設(shè)備相當(dāng)于交換機(jī)上的端口,可以將多個(gè)容器連接在它們上面,這些端口工作在二層,所以是不需要配置 IP 信息的。上圖中的 docker0 網(wǎng)橋就為連在其上的容器轉(zhuǎn)發(fā)數(shù)據(jù)幀,使得同一臺(tái)宿主機(jī)上的 docker 容器之間可以相互通信。既然 docker0 是二層設(shè)備,那么它為什么還需要 IP 呢?其實(shí),docker0 是一個(gè)普通的 linux 網(wǎng)橋,是可以為它配置 IP 的,我們可以認(rèn)為它的內(nèi)部有一個(gè)可以用于配置 IP 的網(wǎng)卡。Docker0 的 IP 地址作為所連接的容器的默認(rèn)網(wǎng)關(guān)地址!

docker0 網(wǎng)橋是在 docker daemon 啟動(dòng)時(shí)自動(dòng)創(chuàng)建的,其默認(rèn) IP 為 172.17.0.1/16,之后通過 bridge 驅(qū)動(dòng)創(chuàng)建的容器都會(huì)在 docker0 的子網(wǎng)范圍內(nèi)選取一個(gè)未占用的 IP 使用,并連接到 docker0 網(wǎng)橋上。Docker daemon 提供了如下參數(shù)可以幫助用戶自定義 docker0 的設(shè)置。

--bip=CIDR:設(shè)置 docker0 的 IP 地址和子網(wǎng)范圍,使用 CIDR 格式,如 192.168.1.0/24。這個(gè)參數(shù)僅僅是配置 docker0 的,對(duì)用戶自定義的網(wǎng)橋無效。

--fixed-cidr=CIDR:限制 docker 容器可以獲取的 IP 地址范圍。Docker 容器默認(rèn)可以獲取的 IP 范圍為 docker 網(wǎng)橋的整個(gè)子網(wǎng)范圍,此參數(shù)可以將其縮小到某個(gè)子網(wǎng)范圍內(nèi),所以這個(gè)參數(shù)必須在 docker 網(wǎng)橋的子網(wǎng)范圍內(nèi)。

--mtu=BYTES:指定 docker0 網(wǎng)橋的最大傳輸單元(MTU)。

除了使用 docker0 網(wǎng)橋外,用戶還可以使用自定義的網(wǎng)橋,然后通過 --bridge=BRIDGE 參數(shù)傳遞給 docker daemon。比如我們可以創(chuàng)建一個(gè)自定義網(wǎng)橋 br0:

$ sudo ip link add name br0 type bridge
$ sudo ifconfig br0 188.18.0.1

5cdf794a-eea3-11ee-a297-92fbcf53809c.png

然后在啟動(dòng) docker daemon 時(shí)設(shè)置參數(shù) --bridge=br0 即可。

iptables 規(guī)則

在安裝 docker 時(shí),會(huì)默認(rèn)在宿主機(jī)中添加一些 iptables 規(guī)則,用于 docker 容器之間已經(jīng)容器與外界的通信。我們可以通過 iptables-save 命令查看到 nat 表上 POSTROUTING 鏈上的有這么一條規(guī)則:

-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
這條規(guī)則關(guān)系著 docker 容器與外界的通信,其含義是將不是從網(wǎng)卡 docker0 發(fā)出的且源地址為 172.17.0.0/16 的數(shù)據(jù)包(容器中發(fā)出的數(shù)據(jù)包)做 SNAT。這樣一來,從 docker 容器中訪問外網(wǎng)的流量,在外部看來就是從宿主機(jī)上發(fā)出的,外部感覺不到 docker 容器的存在。

當(dāng)外界想要訪問 docker 容器運(yùn)行的服務(wù)時(shí)該怎么辦呢?接下來我們將啟動(dòng)一個(gè)簡(jiǎn)單的 web 服務(wù)器:

$ docker run -d -p 3000:3000 --name=myweb ljfpower/nodedemo
然后觀察 iptables 規(guī)則的變化:
$ sudo iptables-save
…
*nat
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 3000 -j DNAT --to-destination 172.17.0.3:3000
…
*filter
-A DOCKER -d 172.17.0.3/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 3000 -j ACCEPT
…

可以看到,在 nat 表和 filter 表中的 DOCKER 鏈中分別增加來一條規(guī)則,這兩條規(guī)則將訪問宿主機(jī) 3000 端口的請(qǐng)求轉(zhuǎn)發(fā)到 172.17.0.3 的 3000 端口上(提供服務(wù)的 docker 容器的 IP 和端口),所以外界訪問 docker 容器是通過 iptables 做 DNAT 實(shí)現(xiàn)的。

Docker 默認(rèn)的 forward 規(guī)則允許所有的外部 IP 訪問容器,我們可以通過在 filter 的 DOCKER 鏈上添加規(guī)則來對(duì)外部的 IP 訪問做出限制,比如只允許源 IP 為 192.168.21.212(筆者是在局域網(wǎng)內(nèi)演示的)的數(shù)據(jù)包訪問容器,添加的規(guī)則如下:

$ sudo iptables -I DOCKER -i docker0 ! -s 192.168.21.212 -j DROP

不僅僅是與外界通信,docker 容器之間相互通信也受到 iptables 規(guī)則的限制。同一臺(tái)宿主機(jī)上的 docker 容器默認(rèn)都連在 docker0 網(wǎng)橋上,它們屬于同一個(gè)子網(wǎng),這是滿足通信的第一步。同時(shí),docker daemon 會(huì)在 filter 表的 FORWARD 鏈中增加一條 ACCEPT 的規(guī)則(--icc=true):
-A FORWARD -i docker0 -o docker0 -j ACCEPT
這是滿足容器間相互通信的第二步。當(dāng) docker daemon 的啟動(dòng)參數(shù) -icc(icc 參數(shù)表示是否允許容器間相互通信) 設(shè)置為 false 時(shí),上面的規(guī)則被設(shè)置為 DROP,容器間的相互通信就被禁止了,這時(shí)如果想讓兩個(gè)容器通信就需要在 docker run 命令中使用 --link 選項(xiàng)。

在 docker 容器和外界的通信過程中,還涉及了數(shù)據(jù)包在多個(gè)網(wǎng)卡之間的轉(zhuǎn)發(fā)(比如從 docker0 網(wǎng)卡到宿主機(jī) eth0 網(wǎng)卡),這需要內(nèi)核將 ip forward 功能打開,就是把內(nèi)核參數(shù) ip_forward 設(shè)置為 1。Docker daemon 在啟動(dòng)的時(shí)候會(huì)執(zhí)行這個(gè)操作,我們可以通過下面的命令進(jìn)行檢查:

$ cat /proc/sys/net/ipv4/ip_forward


5cef6170-eea3-11ee-a297-92fbcf53809c.png

返回的結(jié)果為 1,表示內(nèi)核的 ip forward 功能已經(jīng)打開。

容器的 DNS 和主機(jī)名(hostname)

使用同一個(gè) docker 鏡像可以創(chuàng)建很多個(gè) docker 容器,但是這些容器的 hostname 并不相同,也就是說 hostname 并沒有被寫入到鏡像中。實(shí)際上容器中的 /etc 目錄下有 3 個(gè)文件是在容器啟動(dòng)后被虛擬文件覆蓋掉的,分別是 /etc/hostname、/etc/hosts 和 /etc/resolv.conf,通過在容器中運(yùn)行 mount 命令可以看到它們:

# mount
…
/dev/mapper/ubuntu--vg-root on /etc/resolv.conf type ext4 (rw,relatime,errors=remount-ro,data=ordered)
/dev/mapper/ubuntu--vg-root on /etc/hostname type ext4 (rw,relatime,errors=remount-ro,data=ordered)
/dev/mapper/ubuntu--vg-root on /etc/hosts type ext4 (rw,relatime,errors=remount-ro,data=ordered)
…

這種方式既能解決主機(jī)名的問題,同時(shí)也能讓 DNS 及時(shí)更新(改變 resolv.conf)。由于這些文件的維護(hù)方法會(huì)隨著 docker 版本的升級(jí)而不斷變化,所以盡量不要修改這些文件,而是通過 docker 提供的相關(guān)參數(shù)進(jìn)行設(shè)置,其參數(shù)配置方式如下。

-h HOSTNAME 或者 --hostname=HOSTNAME:設(shè)置容器的 hostname,此名稱會(huì)寫入到 /etc/hostname 和 /etc/hosts 文件中,也可以在容器的 bash 提示符中看到。

--dns=IP_ADDRESS…:為容器配置 DNS,會(huì)被寫入到 /etc/resolv.conf 文件中。

這兩個(gè)參數(shù)都是針對(duì)容器的需要在創(chuàng)建容器時(shí)進(jìn)行設(shè)置。比如下面的 demo:

$ docker run -it --name mycon -h lion --dns=8.8.8.8 ubuntu:14.04


5cfcecf0-eea3-11ee-a297-92fbcf53809c.png

總結(jié)

本文主要通過演示 docker0 網(wǎng)橋相關(guān)的功能來探索 docker 網(wǎng)絡(luò)中的 bridge 驅(qū)動(dòng)的實(shí)現(xiàn)機(jī)制。從本文中不難看出,linux 系統(tǒng)中,docker 的 bridge 驅(qū)動(dòng)是依賴于系統(tǒng)的 ip forward 以及 iptables 等核心功能的。因此在學(xué)習(xí) docker 的過程中,適當(dāng)?shù)难a(bǔ)充 linux 相關(guān)的知識(shí)也是十分必要的!

審核編輯:黃飛

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 網(wǎng)橋
    +關(guān)注

    關(guān)注

    0

    文章

    129

    瀏覽量

    16923
  • 容器
    +關(guān)注

    關(guān)注

    0

    文章

    490

    瀏覽量

    22013
  • Bridge
    +關(guān)注

    關(guān)注

    0

    文章

    15

    瀏覽量

    11867
  • Docker
    +關(guān)注

    關(guān)注

    0

    文章

    446

    瀏覽量

    11773

原文標(biāo)題:拿捏Docker 網(wǎng)絡(luò) bridge 驅(qū)動(dòng)

文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Docker網(wǎng)絡(luò)選型和日志監(jiān)控選型

    Docker容器化網(wǎng)絡(luò)和日志的選型和落地
    發(fā)表于 05-06 07:58

    docker的四種網(wǎng)絡(luò)模式

    docker網(wǎng)絡(luò)模式
    發(fā)表于 10-16 08:11

    解析深度學(xué)習(xí):卷積神經(jīng)網(wǎng)絡(luò)原理與視覺實(shí)踐

    解析深度學(xué)習(xí):卷積神經(jīng)網(wǎng)絡(luò)原理與視覺實(shí)踐
    發(fā)表于 06-14 22:21

    AUTOSAR架構(gòu)深度解析 精選資料推薦

    AUTOSAR架構(gòu)深度解析本文轉(zhuǎn)載于:AUTOSAR架構(gòu)深度解析目錄AUTOSAR架構(gòu)深度解析A
    發(fā)表于 07-28 07:40

    AUTOSAR架構(gòu)深度解析 精選資料分享

    AUTOSAR架構(gòu)深度解析本文轉(zhuǎn)載于:AUTOSAR架構(gòu)深度解析AUTOSAR的分層式設(shè)計(jì),用于支持完整的軟件和硬件模塊的獨(dú)立性(Independence),中間RTE(Runtime
    發(fā)表于 07-28 07:02

    C語言深度解析

    C語言深度解析,本資料來源于網(wǎng)絡(luò),對(duì)C語言的學(xué)習(xí)有很大的幫助,有著較為深刻的解析,可能會(huì)對(duì)讀者有一定的幫助。
    發(fā)表于 09-28 07:00

    Docker五種存儲(chǔ)驅(qū)動(dòng)原理詳解

    問題,在Docker 0.7版本中引入了存儲(chǔ)驅(qū)動(dòng), 目前,Docker支持AUFS、Btrfs、Device mapper、OverlayFS、ZFS五種存儲(chǔ)驅(qū)動(dòng)。
    發(fā)表于 05-13 10:33 ?2675次閱讀
    <b class='flag-5'>Docker</b>五種存儲(chǔ)<b class='flag-5'>驅(qū)動(dòng)</b>原理詳解

    docker存儲(chǔ)驅(qū)動(dòng)的工作原理

    Docker的存儲(chǔ)驅(qū)動(dòng)官方有介紹其工作原理,這里只是簡(jiǎn)單概括一下。Docker使用了層的概念,docker在構(gòu)建鏡像的時(shí)候,會(huì)逐行執(zhí)行我們的Dockerfile中的每一行,每執(zhí)行一行的
    的頭像 發(fā)表于 06-26 11:49 ?4529次閱讀

    嵌入式Linux與物聯(lián)網(wǎng)軟件開發(fā)C語言內(nèi)核深度解析書籍的介紹

    嵌入式Linux與物聯(lián)網(wǎng)軟件開發(fā)——C語言內(nèi)核深度解析 C語言是嵌入式Linux領(lǐng)域的主要開發(fā)語言。對(duì)于學(xué)習(xí)嵌入式、單片機(jī)、Linux驅(qū)動(dòng)開發(fā)等技術(shù)來說,C語言是必須要過的一關(guān)。C語言學(xué)習(xí)的特點(diǎn)是入門容易、深入理解難、
    發(fā)表于 05-15 18:10 ?8次下載
    嵌入式Linux與物聯(lián)網(wǎng)軟件開發(fā)C語言內(nèi)核<b class='flag-5'>深度</b><b class='flag-5'>解析</b>書籍的介紹

    詳解docker的四種網(wǎng)絡(luò)模式

    使用none模式,Docker容器擁有自己的Network Namespace,但是,并不為Docker容器進(jìn)行任何網(wǎng)絡(luò)配置。也就是說,這個(gè)Docker容器沒有網(wǎng)卡、IP、路由等信息,
    的頭像 發(fā)表于 01-21 09:21 ?6545次閱讀

    docker的4種網(wǎng)絡(luò)模式

    Docker 使用 Linux 橋接,在宿主機(jī)虛擬一個(gè) Docker 容器網(wǎng)橋(docker0),Docker 啟動(dòng)一個(gè)容器時(shí)會(huì)根據(jù) Docker
    的頭像 發(fā)表于 08-14 11:50 ?1708次閱讀

    Docker容器的四種網(wǎng)絡(luò)模式

    Docker 在安裝后自動(dòng)提供 3 種網(wǎng)絡(luò),可以使用 docker network ls 命令查看。
    的頭像 發(fā)表于 10-17 14:53 ?1565次閱讀

    Docker容器網(wǎng)絡(luò)的數(shù)據(jù)鏈路是什么

    單主機(jī)容器網(wǎng)絡(luò)可能存在多個(gè)docker,分屬于不同的bridge,它們之間有通信的需求。
    的頭像 發(fā)表于 02-15 09:56 ?839次閱讀
    <b class='flag-5'>Docker</b>容器<b class='flag-5'>網(wǎng)絡(luò)</b>的數(shù)據(jù)鏈路是什么

    docker常用基礎(chǔ)命令

    作為嵌入式開發(fā)工程師,需要用到的docker命令基礎(chǔ)解析與使用。
    發(fā)表于 09-18 17:54 ?2次下載

    Docker網(wǎng)絡(luò)的基本概念和原理與用法

    橋接網(wǎng)絡(luò)Bridge Network):這是 Docker 容器默認(rèn)使用的網(wǎng)絡(luò)類型。每個(gè)獨(dú)立的容器都會(huì)連接到一個(gè)內(nèi)部網(wǎng)絡(luò)的私有網(wǎng)橋。
    發(fā)表于 03-18 12:26 ?641次閱讀
    <b class='flag-5'>Docker</b><b class='flag-5'>網(wǎng)絡(luò)</b>的基本概念和原理與用法