Docker網絡

  • docker0網橋
    當在一臺未經過特殊網絡配置的centos 或 ubuntu機器上安裝完docker之后泣懊,在宿主機上通過ifconfig命令可以看到多了一塊名為docker0的網卡砸彬,假設IP為 172.17.0.1/16瓤帚。有了這樣一塊網卡,宿主機也會在內核路由表上添加一條到達相應網絡的靜態(tài)路由醇王,可通過route -n查看:

    # route -n
    Kernel IP routing table
    Destination     Gateway         Genmask         Flags   Metric   Ref         Use Iface
    ...
    172.17.0.0      0.0.0.0         255.255.0.0          U           0      0        0         docker0
    ...
    

    此條路由表示所有目的IP地址為172.17.0.0/16的數據包從docker0網卡轉發(fā)敌卓。

然后使用docker run命令創(chuàng)建一個執(zhí)行shell(/bin/bash)的Docker容器遂黍,假設容器名稱為con1俐填。
?在con1容器中可以看到它有兩個網卡lo和eth0安接。lo設備不必多說,是容器的回環(huán)網卡英融;eth0即為容器與外界通信的網卡盏檐,eth0的ip 為 172.17.0.2/16歇式,和宿主機上的網橋docker0在同一個網段。

查看con1的路由表胡野,可以發(fā)現(xiàn)con1的默認網關正是宿主機的docker0網卡材失,通過測試, con1可以順利訪問外網和宿主機網絡给涕,因此表明con1的eth0網卡與宿主機的docker0網卡是相互連通的豺憔。

這時在來查看(ifconfig)宿主機的網絡設備额获,會發(fā)現(xiàn)有一塊以“veth”開頭的網卡够庙,如veth60b16bd,我們可以大膽猜測這塊網卡肯定是veth設備了抄邀,而veth pair總是成對出現(xiàn)的耘眨。veth pair通常用來連接兩個network namespace,那么另一個應該是Docker容器con1中的eth0了境肾。之前已經判斷con1容器的eth0和宿主機的docker0是相連的剔难,那么veth60b16bd也應該是與docker0相連的,不難想到奥喻,docker0就不只是一個簡單的網卡設備了偶宫,而是一個網橋。

真實情況正是如此环鲤,下圖即為Docker默認網絡模式(bridge模式)下的網絡環(huán)境拓撲圖纯趋,創(chuàng)建了docker0網橋,并以eth pair連接各容器的網絡冷离,容器中的數據通過docker0網橋轉發(fā)到eth0網卡上吵冒。


“深入淺出”來解讀Docker網絡核心原理

這里的網橋概念等同于交換機,為連在其上的設備轉發(fā)數據幀西剥。網橋上的veth網卡設備相當于交換機上的端口痹栖,可以將多個容器或虛擬機連接在上面,這些端口工作在二層瞭空,所以是不需要配置IP信息的揪阿。圖中docker0網橋就為連在其上的容器轉發(fā)數據幀,使得同一臺宿主機上的Docker容器之間可以相互通信咆畏。
?大家應該注意到docker0既然是二層設備南捂,它上面怎么設置了IP呢?docker0是普通的linux網橋鳖眼,它是可以在上面配置IP的黑毅,可以認為其內部有一個可以用于配置IP信息的網卡接口(如同每一個Open vSwitch網橋都有一個同名的內部接口一樣)。在Docker的橋接網絡模式中钦讳,docker0的IP地址作為連于之上的容器的默認網關地址存在矿瘦。

在Linux中枕面,可以使用brctl命令查看和管理網橋(需要安裝bridge-utils軟件包),比如查看本機上的Linux網橋以及其上的端口:

# brctl show
bridge   name   bridge id                       STP enabled        interfaces
docker0          8000.02420b69b449        no                    veth1b11267

更多關于brctl命令的功能和用法缚去,大家通過man brctl或brctl --help查閱潮秘。

docker0網橋是在Docker daemon啟動時自動創(chuàng)建的,其IP默認為172.17.0.1/16易结,之后創(chuàng)建的Docker容器都會在docker0子網的范圍內選取一個未占用的IP使用枕荞,并連接到docker0網橋上。

除了使用docker0網橋外搞动,還可以使用自己創(chuàng)建的網橋躏精,比如創(chuàng)建一個名為br0的網橋,配置IP:

# brctl  addbr br0
# ifconfig  br0 18.18.0.1
  • iptables規(guī)則
    ?Docker安裝完成后鹦肿,將默認在宿主機系統(tǒng)上增加一些iptables規(guī)則矗烛,以用于Docker容器和容器之間以及和外界的通信,可以使用iptables-save命令查看箩溃。其中nat表中的POSTROUTING鏈有這么一條規(guī)則:

    -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
    

    參數說明:
    -s :源地址172.17.0.0/16
    -o:指定數據報文流出接口為docker0
    -j :動作為MASQUERADE(地址偽裝)

上面這條規(guī)則關系著Docker容器和外界的通信瞭吃,含義是:將源地址為172.17.0.0/16的數據包(即Docker容器發(fā)出的數據),當不是從docker0網卡發(fā)出時做SNAT涣旨。這樣一來歪架,從Docker容器訪問外網的流量,在外部看來就是從宿主機上發(fā)出的霹陡,外部感覺不到Docker容器的存在和蚪。
?那么,外界想到訪問Docker容器的服務時該怎么辦呢穆律?我們啟動一個簡單的web服務容器惠呼,觀察iptables規(guī)則有何變化。

1峦耘、首先啟動一個 tomcat容器剔蹋,將其8080端口映射到宿主機上的8080端口上:

#docker run -itd --name  tomcat01 -p 8080:8080 tomcat:latest 

2、然后查看iptabels規(guī)則辅髓,省略部分無用信息:

#iptables-save
*nat
-A POSTROUTING -s 172.17.0.4/32 -d 172.17.0.4/32 -p tcp -m tcp --dport 8080 -j MASQUERADE
...

*filter
-A DOCKER -d 172.17.0.4/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 8080 -j ACCEPT

可以看到泣崩,在nat、filter的Docker鏈中分別增加了一條規(guī)則洛口,這兩條規(guī)則將訪問宿主機8080端口的流量轉發(fā)到了172.17.0.4的8080端口上(真正提供服務的Docker容器IP和端口)矫付,所以外界訪問Docker容器是通過iptables做DNAT(目的地址轉換)實現(xiàn)的。
?此外第焰,Docker的forward規(guī)則默認允許所有的外部IP訪問容器买优,可以通過在filter的DOCKER鏈上添加規(guī)則來對外部的IP訪問做出限制,比如只允許源IP192.168.0.0/16的數據包訪問容器,需要添加如下規(guī)則:

iptables -I DOCKER -i docker0 ! -s 192.168.0.0/16 -j DROP

不僅僅是與外界間通信杀赢,Docker容器之間互個通信也受到iptables規(guī)則限制烘跺。同一臺宿主機上的Docker容器默認都連在docker0網橋上,它們屬于一個子網脂崔,這是滿足相互通信的第一步滤淳。同時,Docker daemon會在filter的FORWARD鏈中增加一條ACCEPT的規(guī)則(--icc=true):

-A FORWARD -i docker0 -o docker0 -j ACCEPT

這是滿足相互通信的第二步砌左。當Docker datemon啟動參數--icc(icc參數表示是否允許容器間相互通信)設置為false時脖咐,以上規(guī)則會被設置為DROP,Docker容器間的相互通信就被禁止汇歹,這種情況下屁擅,想讓兩個容器通信就需要在docker run時使用 --link選項。

在Docker容器和外界通信的過程中煤蹭,還涉及了數據包在多個網卡間的轉發(fā)(如從docker0網卡轉發(fā)到宿主機ens160網卡)笔喉,這需要內核將ip-forward功能打開,即將ip_forward系統(tǒng)參數設1常挚。Docker daemon啟動的時候默認會將其設為1(--ip-forward=true),也可以通過命令手動設置:

# echo 1 > /proc/sys/net/ipv4/ip_forward
# cat /proc/sys/net/ipv4/ip_forward
1
  • Docker容器的DNS和主機名
    ?同一個Docker鏡像可以啟動很多Docker容器奄毡,通過查看折欠,它們的主機名并不一樣吼过,也即是說主機名并非是被寫入鏡像中的。實際上容器中/etc/目錄下有3個文件是容器啟動后被虛擬文件覆蓋的盗忱,分別是/etc/hostname、/etc/hosts趟佃、/etc/resolv.conf,通過在容器中運行mount命令可以查看:

    # docker exec -it tomcat01 bash
    root@3d95d30c69d3:/usr/local/tomcat# mount
    ...
    /dev/mapper/centos-root on /etc/resolv.conf type xfs (rw,relatime,attr2,inode64,noquota)
    /dev/mapper/centos-root on /etc/hostname type xfs (rw,relatime,attr2,inode64,noquota)
    /dev/mapper/centos-root on /etc/hosts type xfs (rw,relatime,attr2,inode64,noquota)
    ...
    

    這樣能解決主機名的問題闲昭,同時也能讓DNS及時更新(改變resolv.conf)。由于這些文件的維護方法隨著Docker版本演進而不斷變化序矩,因此盡量不修改這些文件鸯绿,而是通過Docker提供的參數進行相關設置,配置方式如下:

  • -h HOSTNAME 或 --hostname=HOSTNAME:設置容器的主機名瓶蝴,此名稱會寫在/etc/hostname和/etc/hosts文件中幔烛,也會在容器的bash提示符看到。但是在外部囊蓝,容器的主機名是無法查看的饿悬,不會出現(xiàn)在其他容器的hosts文件中,即使使用docker ps命令也查看不到聚霜。此參數是docker run命令的參數狡恬,而非docker daemon的啟動參數。

  • --dns=IP_ADDRESS...:為容器配置DNS蝎宇,寫在/etc/resolv.conf中弟劲。該參數即可以在docker daemon 啟動的時候設置,也可以在docker run時設置姥芥,默認為8.8.8或8.8.4.4兔乞。

注意:對以上3個文件的修改不會被docker commit保存,也就是不會保存在鏡像中凉唐,重啟容器也會導致修改失效庸追。另外,在不穩(wěn)定的網絡環(huán)境下使用需要特別注意DNS的設置台囱。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末淡溯,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子簿训,更是在濱河造成了極大的恐慌咱娶,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,451評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件强品,死亡現(xiàn)場離奇詭異膘侮,居然都是意外死亡,警方通過查閱死者的電腦和手機的榛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評論 3 394
  • 文/潘曉璐 我一進店門琼了,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人困曙,你說我怎么就攤上這事表伦。” “怎么了慷丽?”我有些...
    開封第一講書人閱讀 164,782評論 0 354
  • 文/不壞的土叔 我叫張陵蹦哼,是天一觀的道長。 經常有香客問我要糊,道長纲熏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,709評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮局劲,結果婚禮上勺拣,老公的妹妹穿的比我還像新娘。我一直安慰自己鱼填,他們只是感情好药有,可當我...
    茶點故事閱讀 67,733評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著愤惰,像睡著了一般赘理。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上奠旺,一...
    開封第一講書人閱讀 51,578評論 1 305
  • 那天响疚,我揣著相機與錄音嫂沉,去河邊找鬼。 笑死,一個胖子當著我的面吹牛慎王,可吹牛的內容都是我干的。 我是一名探鬼主播蜀漆,決...
    沈念sama閱讀 40,320評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼确丢,長吁一口氣:“原來是場噩夢啊……” “哼吐限!你這毒婦竟也來了?” 一聲冷哼從身側響起描函,我...
    開封第一講書人閱讀 39,241評論 0 276
  • 序言:老撾萬榮一對情侶失蹤舀寓,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后互墓,有當地人在樹林里發(fā)現(xiàn)了一具尸體篡撵,經...
    沈念sama閱讀 45,686評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,878評論 3 336
  • 正文 我和宋清朗相戀三年骂租,在試婚紗的時候發(fā)現(xiàn)自己被綠了斑司。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,992評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡互站,死狀恐怖僵缺,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情磕潮,我是刑警寧澤,帶...
    沈念sama閱讀 35,715評論 5 346
  • 正文 年R本政府宣布之景,位于F島的核電站,受9級特大地震影響锻狗,放射性物質發(fā)生泄漏焕参。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,336評論 3 330
  • 文/蒙蒙 一刻帚、第九天 我趴在偏房一處隱蔽的房頂上張望我擂。 院中可真熱鬧衬以,春花似錦看峻、人聲如沸衙吩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽摹芙。三九已至,卻和暖如春浮禾,著一層夾襖步出監(jiān)牢的瞬間盈电,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評論 1 270
  • 我被黑心中介騙來泰國打工熬词, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人互拾。 一個月前我還...
    沈念sama閱讀 48,173評論 3 370
  • 正文 我出身青樓摩幔,卻偏偏與公主長得像鞭铆,于是被迫代替她去往敵國和親焦影。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,947評論 2 355

推薦閱讀更多精彩內容

  • 【編者的話】當你在一臺主機上成功運行Docker容器后,信心滿滿地打算將其擴展到多臺主機時彬呻,卻發(fā)現(xiàn)前面的嘗試只相當...
    SDNLAB閱讀 1,032評論 0 6
  • docker之容器通信 這節(jié)屬于了解學習,算是爛尾授翻,最后我也沒找到合適的方式去固定容器ip,然后作為正式環(huán)境去跑堪唐,...
    道無虛閱讀 5,485評論 1 7
  • 概述 自從docker容器出現(xiàn)以來淮菠,容器的網絡通信就一直是大家關注的焦點荤堪,也是生產環(huán)境的迫切需求合陵。而容器的網絡通信...
    糙老爺們兒吃什么櫻桃閱讀 3,623評論 1 5
  • http://blog.51cto.com/ganbing/2088899 前言 在上一篇文章中 《“深入淺出”來...
    lifesmily閱讀 711評論 1 1
  • 雖然說丑到家了但我相信還是會有一大堆人買! 如果喬布斯在世又會怎么想呢揩抡?
    科技音浪閱讀 273評論 0 0