一、容器內部通訊python
Docker容器和服務如此強大的緣由之一是在經過網絡能夠將它們鏈接在一塊兒,或者將它們鏈接到非Docker工做負載。Docker容器和服務甚至不須要知道它們部署在Docker上,或者它們的對等體是否也是Docker工做負載。linux
Docker的網絡子系統是可插拔的,使用驅動程序。默認狀況下存在多個驅動程序,並提供核心網絡功能:nginx
bridge:默認網絡驅動程序。當你的應用程序在須要通訊的獨立容器中運行時,一般會使用橋接網絡。 host:對於獨立容器,刪除容器和Docker主機之間的網絡隔離,並直接使用主機的網絡。 container:能夠多個容器共用一個網絡。 overlay:覆蓋網絡將多個Docker守護程序鏈接在一塊兒,並使羣集服務可以相互通訊。還可使用覆蓋網絡來促進羣集服務和獨立容器之間的通訊,或者在不一樣Docker守護程序上的兩個獨立容器之間進行通訊。 macvlan:Macvlan網絡容許您爲容器分配MAC地址,使其顯示爲網絡上的物理設備。Docker守護程序經過其MAC地址將流量路由到容器。macvlan 在處理指望直接鏈接到物理網絡的傳統應用程序時,使用驅動程序有時是最佳選擇,而不是經過Docker主機的網絡堆疊進行路由。 none:對於此容器,禁用全部網絡。 network plugins:使用Docker安裝和使用第三方網絡插件。這些插件可從Docker Store或第三方供應商處得到。
bridge網絡docker
如圖,默認docker主機會存在三種類型的網絡。centos
如圖,docker主機會有一個默認使用的橋接網卡bridge0,它是在運行docker容器時,若是不指定網絡,默認使用的網絡。網絡
當運行一個容器時,咱們能夠看到在docker主機上多了一個網卡,並且master指向docker0架構
這時候咱們在查看該容器的網絡信息(ip地址和網關)。發現它的ip地址和docker0一個網段,網關則是docker0的地址
ide
bridge網絡的特色
工具
使用一個 linux bridge,默認爲 docker0 使用veth 對,一頭在容器的網絡 namespace中,一頭在docker0上 該模式下Docker Container不具備一個公有IP,由於宿主機的IP地址與veth pair的IP地址不在同一個網段內 Docker採用NAT方式,將容器內部的服務監聽的端口與宿主機的某一個端口進行「綁定」,使得宿主機之外的世界能夠主動將網絡報文發送至容器內部 外界訪問容器內的服務時,須要訪問宿主機的 IP 以及宿主機的端口 port NAT 模式因爲是在三層網絡上的實現手段,故確定會影響網絡的傳輸效率。 容器擁有獨立、隔離的網絡棧;讓容器和宿主機之外的世界經過NAT創建通訊
咱們查看iptables的nat表,能夠看到,在POSTROUTING鏈上作了一個MASQUERADE,源是172.17.0.0/16,目標是全部網段。這樣的轉換後,容器就能夠經過SNAT訪問到外網實現通訊了。oop
host網絡
Host模式並無爲容器建立一個隔離的網絡環境。該模式下的Docker容器會和host宿主機共享同一個網絡namespace,因此容器能夠和宿 主機同樣,使用宿主機的eth0,實現和外界的通訊。
特色:
這種模式下的容器沒有隔離的network namespace 容器的IP地址同 Docker主機的IP地址 須要注意容器中服務的端口號不能與Docker主機上已經使用的端口號相沖突 host模式可以和其它模式共存
首先我經過ss查看一下,個人docker主機80端口並無使用。當我啓動一個提供nginx應用的容器時,在查看發現個人主機使用了80端口。
咱們還能夠經過docker inspect nginx001查看它的網絡信息。發現IP地址和網關處根本沒有值。由於使用了host網絡,它是共用了docker主機的網絡。
None模式
網絡模式爲 none,即不爲Docker容器構造任何網絡環境,不會爲容器建立網絡接口,一旦Docker容器採用了none網絡模式,那麼容器內部就只能使用loop back網絡設備,不會再有其餘的網絡資源。
Container共享模式
這個模式指定新建立的容器和已經存在的一個容器共享一個 Network Namespace,而不是和宿主機共享。新建立的容器不會建立本身的網卡,配置本身的 IP,而是和一個指定的容器共享 IP、端口範圍等。一樣,兩個容器除了網絡方面,其餘的如文件系統、進程列表等仍是隔離的。兩個容器的進程能夠經過 lo 網卡設備通訊
首先我運行一個容器,執行ip a查看到ip地址爲172.17.0.2。
再運行一個容器,指定network類型爲container,共享centos01的網絡。
鏈接centos02,查看ip地址。發現centos02和centos01的地址是同樣的。
二、外部網絡訪問容器內應用
-P隨機指定一個docker主機端口給容器中的端口作映射
-p將docker主機的一個端口映射容器的一個端口
訪問網站測試(個人docker主機的地址爲192.168.44.131,記住要在docker主機上放行32768和8000端口)
首先訪問32768端口
訪問8000端口。(均可以正常提供服務)
三、用戶自定義網絡
經過docker network create --driver network_type network_name命令便可建立自定義網絡。其中--driver後面支持的類型有三種:bridge、macvlan、overlay。
經過docker network inspect network_name能夠查看該網絡的信息
[root@docker001 ~]# docker network inspect my_bridge [ { "Name": "my_bridge", "Id": "897ea2a24517f23144b0deab471ceefc6ee910840d2631d9429305036de075c6", "Created": "2018-08-19T15:16:25.49887066+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.19.0.0/16", "Gateway": "172.19.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": {}, "Options": {}, "Labels": {} } ]
並且經過ip addr能夠看到自動在docker主機上建立了一個網卡。
再次查看咱們nat表,也能夠看到在POSTROUTING上作的MASQUERADE
這樣咱們就能夠運行容器使用該網絡了。
四、docker network管理命令的使用
分別以下。
顯示一個網絡的信息(只截取了一部分)
五、跨主機docker容器通訊方案介紹
基於實現方式的分類
隧道方案(Overlay Networking): Weave:UDP廣播,本機創建新的BR,經過PCAP互通。 Open vSwitch(OVS):基於VxLAN和GRE協議,可是性能方面損失比較嚴重。 Flannel:UDP廣播,VxLan。
路由方案: Calico:基於BGP協議的路由方案,支持很細緻的ACL控制,對混合雲親和度比較 高。 Macvlan:從邏輯和Kernel層來看隔離性和性能最優的方案,基於二層隔離,因此 須要二層路由器支持,大多數雲服務商不支持,因此混合雲上比較難以實現。
基於網絡模型分類
Docker Libnetwork Container Network Model(CNM): Docker Swarm overlay Macvlan & IP network drivers Calico Contiv(from Cisco) ##Docker Libnetwork的優點就是原生,並且和Docker容器生命週期結合緊密;缺點也能夠理解爲是原生,被Docker「綁架」。
Container Network Interface(CNI): Kubernetes Weave Macvlan Flannel Calico Contiv Mesos CNI ##CNI的優點是兼容其餘容器技術(e.g. rkt)及上層編排系統(Kuberneres & Mesos),並且社區活 躍勢頭迅猛,Kubernetes加上CoreOS主推;缺點是非Docker原生。
詳解:
以Flannel方案爲例
Flannel以前的名字是Rudder,它是由CoreOS團隊針對Kubernetes設計的一個重載網絡工具,它的主要思路是:預先留出一個網段,每一個主機使用其中一部分,而後每一個容器被分配不一樣的ip;讓全部的容器認爲你們在同一個直連的網絡,底層經過UDP/VxLAN等進行報文的封裝和轉發
下面這張是Flannel網絡的經典架構圖(從網上找的)
1. 容器直接使用目標容器的ip訪問,默認經過容器內部的eth0發送出去。 2. 報文經過veth pair被髮送到vethXXX。 3. vethXXX是直接鏈接到虛擬交換機docker0的,報文經過虛擬bridge docker0發送出去。 4. 查找路由表,外部容器ip的報文都會轉發到flannel0虛擬網卡,這是一個P2P的虛擬網卡,而後報文就被轉發到監聽在另外一端的flanneld。 5. flanneld經過etcd維護了各個節點之間的路由表,把原來的報文UDP封裝一層,經過配置的iface發送出去。 6. 報文經過主機之間的網絡找到目標主機。 7. 報文繼續往上,到傳輸層,交給監聽在8285端口的flanneld程序處理。 8. 數據被解包,而後發送給flannel0虛擬網卡。 9. 查找路由表,發現對應容器的報文要交給docker0。 10. docker0找到連到本身的容器,把報文發送過去。