關於docker容器網路的一些理解
開啟微信掃一掃,關注微信公眾號【資料與演算法聯盟】
轉載請註明出處:http://blog.csdn.net/gamer_gyt
博主微博:http://weibo.com/234654758
Github:https://github.com/thinkgamer
參考資料
寫在前邊的話
突然發現好久沒有更新部落格了,像我這種頻繁發表部落格的人竟然也會放慢了更新的速度,其實不是說自己不去寫,不去更新,只是不願意去將就,去發表一些讓別人看了沒有多大幫助的文章,作為2017年的開篇部落格,我想和你們一起學習下docker容器網路的知識,首先宣告,以下內容大部分都是來源網路,按照我對docker網路的理解,整理的一篇文章,一起學習。
docker容器網路概述
1:預設網路
在預設情況下會看到三個網路,它們是Docker Deamon程序建立的。它們實際上分別對應了Docker過去的三種『網路模式』,可以使用docker network ls來檢視
[email protected]:~$ sudo docker network ls
NETWORK ID NAME DRIVER SCOPE
18d934794c74 bridge bridge local
f7a7b763f013 host host local
697354257ae3 none null local
這 3 個網路包含在 Docker 實現中。執行一個容器時,可以使用 the –net標誌指定您希望在哪個網路上執行該容器。您仍然可以使用這 3 個網路。
- bridge 網路表示所有 Docker 安裝中都存在的 docker0 網路。除非使用 docker run –net=選項另行指定,否則 Docker 守護程序預設情況下會將容器連線到此網路。在主機上使用 ifconfig命令,可以看到此網橋是主機的網路堆疊的一部分。
- none 網路在一個特定於容器的網路堆疊上添加了一個容器。該容器缺少網路介面。
- host 網路在主機網路堆疊上新增一個容器。您可以發現,容器中的網路配置與主機相同。
2:自定義網路
當然你也可以自定義網路來更好的隔離容器,Docker 提供了一些預設網路驅動程式來建立這些網路。您可以建立一個新 bridge 網路或覆蓋一個網路。也可以建立一個網路外掛或遠端網路並寫入您自己的規範中。您可以建立多個網路。可以將容器新增到多個網路。容器僅能在網路內通訊,不能跨網路進行通訊。一個連線到兩個網路的容器可與每個網路中的成員容器進行通訊。當一個容器連線到多個網路時,外部連線通過第一個(按詞典順序)非內部網路提供。
(1):docker network 命令
執行 sudo docker network –help
[email protected]:~$ sudo docker network --help
Usage: docker network COMMAND
Manage Docker networks
Options:
--help Print usage
Commands:
connect Connect a container to a network
create Create a network
disconnect Disconnect a container from a network
inspect Display detailed information on one or more networks
ls List networks
rm Remove one or more networks
Run 'docker network COMMAND --help' for more information on a command.
(2):建立test-network網路
執行命令: sudo docker network create test-network
檢視: sudo docker network ls
[email protected]:~$ sudo docker network ls
NETWORK ID NAME DRIVER SCOPE
18d934794c74 bridge bridge local
f7a7b763f013 host host local
697354257ae3 none null local
c4f6d347c8b4 test-network bridge local
檢視自己建立的網路的資訊
master@ubuntu:~$ sudo docker network inspect test-network
[
{
"Name": "test-network",
"Id": "c4f6d347c8b47471b97e1b5621dd2e90aff303bb7db632db86b0bbec6ffb91d4",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1/16"
}
]
},
"Internal": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
另外,還可以採用其他一些選項,比如 –subnet、–gateway和 –ip-range。
(3):啟動容器連線到test-network
sudo docker run -itd –name=test –net=test-network lt:1.0 /bin/bash
master@ubuntu:~$ sudo docker run -itd --name=test --net=test-network lt:1.0 /bin/bash
09a9d7a9c37d691e0fc0f7cfdf3c9470b77f410592f9bf624fe90bff2b17e315
再次檢視資訊,可以看到掛載的容器
master@ubuntu:~$ sudo docker network inspect test-network
[
{
"Name": "test-network",
"Id": "c4f6d347c8b47471b97e1b5621dd2e90aff303bb7db632db86b0bbec6ffb91d4",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1/16"
}
]
},
"Internal": false,
"Containers": {
"09a9d7a9c37d691e0fc0f7cfdf3c9470b77f410592f9bf624fe90bff2b17e315": {
"Name": "test",
"EndpointID": "7d1d57418a8ebde2d5404f37e27de68be41a917979fd74f394bc5fccc2601e08",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
當然也可以動態的將容器掛載到某個網路上
master@ubuntu:~$ sudo docker run -itd --name=test1 lt:1.0 /bin/bash
b2aba703c5180819542d26e7bda784774ca87b896e8df612dd1b727218dde334
master@ubuntu:~$ sudo docker network connect test-network test1
master@ubuntu:~$ sudo docker network inspect test-network
[
{
"Name": "test-network",
"Id": "c4f6d347c8b47471b97e1b5621dd2e90aff303bb7db632db86b0bbec6ffb91d4",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1/16"
}
]
},
"Internal": false,
"Containers": {
"09a9d7a9c37d691e0fc0f7cfdf3c9470b77f410592f9bf624fe90bff2b17e315": {
"Name": "test",
"EndpointID": "7d1d57418a8ebde2d5404f37e27de68be41a917979fd74f394bc5fccc2601e08",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
},
"b2aba703c5180819542d26e7bda784774ca87b896e8df612dd1b727218dde334": {
"Name": "test1",
"EndpointID": "5d18b876b62312698d4ce253e33b52552c9a3b1237bed90ec565d4cbd9f5710d",
"MacAddress": "02:42:ac:12:00:03",
"IPv4Address": "172.18.0.3/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
“石器時代”的容器網路模型
目前對於剛起步接觸docker容器的筒子們(當然也包括我),大部分使用網路的方式應該是這樣的,把需要暴漏的埠做埠對映(docker run -itd -p 81:80 …),例如一個主機內有很多Apache容器,每一個Apache要往外拋80的埠,那我怎麼辦?我需要針對第一個容器和主機80埠做對映,第二個和主機81埠做對映,依此類推,到最後發現非常混亂,沒辦法管理。這樣的容器網路模型對於企業來說是基本沒辦法被採用。
這是石器時代網路模型,它是Docker1.9之前的容器網路,實現方式是隻針對單臺主機進行IPAM管理,所有主機上的容器都會連線到主機內部的一個Linux Bridge,叫Docker0,主機的IP它預設會分配172.17網段中的一個IP,因為有Docker0,所以在一個主機上的容器可以實現互聯互通。但是因為IP分配的範圍是基於單主機的,所以你會發現在其他主機上,也會出現完全相同的IP地址。很明顯,這兩個地址肯定沒辦法直接通訊。為了解決這個問題,在石器時代我們會用埠對映,實際上就是NAT的方法。比如說我有一個應用,它有Web和Mysql,分別在不同的主機上,Web需要去訪問Mysql,我們會把這個Mysql的3306埠對映到主機上的3306這個埠,然後這個服務實際上是去訪問主機IP 10.10.10.3 的3306埠,這是過去的石器時代的一個做法。
總結一下它的典型技術特徵:基於單主機的IPAM;主機之內容器通訊實際上通過一個docker0的Linux Bridge;如果服務想要暴露到外部的話需要做NAT,會導致埠爭搶非常嚴重;當然它有一個好處,對大網IP消耗比較少。
docker容器的單主機通訊
docker容器的單主機通訊使用的是容器互聯技術,即 –link,對映網路埠不是吧container彼此連線起來的唯一方法。Docker的linking系統允許你吧多個 container連線起來, 讓他們彼此互動資訊。Docker的linking會建立一種父子級別的關係。 父container可以看到他的子container提供的資訊。
建立一個數據庫容器:
sudo docker run -d –name db training/postgres
然後建立一個新的 web 容器,並將它連線到 db 容器
sudo docker run -d -P –name web –link db:db training/webapp python app.py
此時,db 容器和 web 容器建立互聯關係。
–link 引數的格式為 –link name:alias,其中 name 是要連結的容器的名稱,alias 是這個連線的別名。
docker容器的跨主機通訊
早期大家的跨主機通訊方案主要有以下幾種:
- 容器使用host模式:容器直接使用宿主機的網路,這樣天生就可以支援跨主機通訊。雖然可以解決跨主機通訊問題,但這種方式應用場景很有限,容易出現埠衝突,也無法做到隔離網路環境,一個容器崩潰很可能引起整個宿主機的崩潰。
- 埠繫結:通過繫結容器埠到宿主機埠,跨主機通訊時,使用主機IP+埠的方式訪問容器中的服務。顯而易見,這種方式僅能支援網路棧的四層及以上的應用,並且容器與宿主機緊耦合,很難靈活的處理,可擴充套件性不佳。
- docker外定製容器網路:在容器通過docker建立完成後,然後再通過修改容器的網路名稱空間來定義容器網路。典型的就是很久以前的pipework,容器以none模式建立,pipework通過進入容器的網路名稱空間為容器重新配置網路,這樣容器網路可以是靜態IP、vxlan網路等各種方式,非常靈活,容器啟動的一段時間內會沒有IP,明顯無法在大規模場景下使用,只能在實驗室中測試使用。
- 第三方SDN定義容器網路:使用Open vSwitch或Flannel等第三方SDN工具,為容器構建可以跨主機通訊的網路環境。這些方案一般要求各個主機上的docker0網橋的cidr不同,以避免出現IP衝突的問題,限制了容器在宿主機上的可獲取IP範圍。並且在容器需要對叢集外提供服務時,需要比較複雜的配置,對部署實施人員的網路技能要求比較高。
上面這些方案有各種各樣的缺陷,同時也因為跨主機通訊的迫切需求,docker 1.9版本時,官方提出了基於vxlan的overlay網路實現,原生支援容器的跨主機通訊。同時,還支援通過libnetwork的plugin機制擴充套件各種第三方實現,從而以不同的方式實現跨主機通訊。就目前社群比較流行的方案來說,跨主機通訊的基本實現方案有以下幾種:
- 基於隧道的overlay網路:按隧道型別來說,不同的公司或者組織有不同的實現方案。docker原生的overlay網路就是基於vxlan隧道實現的。ovn則需要通過geneve或者stt隧道來實現的。flannel最新版本也開始預設基於vxlan實現overlay網路。
- 基於包封裝的overlay網路:基於UDP封裝等資料包包裝方式,在docker叢集上實現跨主機網路。典型實現方案有weave、flannel的早期版本。
- 基於三層實現SDN網路:基於三層協議和路由,直接在三層上實現跨主機網路,並且通過iptables實現網路的安全隔離。典型的方案為Project Calico。同時對不支援三層路由的環境,Project Calico還提供了基於IPIP封裝的跨主機網路實現。
docker容器的CNI模型和CNM模型
目前圍繞著docker的網路,目前有兩種比較主流的聲音,docker主導的Container network model(CNM)和社群主導的Container network interface(CNI)。
1:CNI
(1) 概述
Container Networking Interface(CNI)提供了一種linux的應用容器的外掛化網路解決方案。最初是由rkt Networking Proposal發展而來。也就是說,CNI本身並不完全針對docker的容器,而是提供一種普適的容器網路解決方案。因此他的模型只涉及兩個概念:
容器(container) : 容器是擁有獨立linux網路名稱空間的獨立單元。比如rkt/docker創建出來的容器。
這裡很關鍵的是容器需要擁有自己的linux網路名稱空間。這也是加入網路的必要條件。
網路(network): 網路指代了可以相互聯絡的一組實體。這些實體擁有各自獨立唯一的ip。這些實體可以是容器,是物理機,或者其他網路裝置(比如路由器)等。
(2) 介面及實現
CNI的介面設計的非常簡潔,只有兩個介面ADD/DELETE。
以 ADD介面為例
Add container to network
引數主要包括:
- Version. CNI版本號
- Container ID. 這是一個可選的引數,提供容器的id
- Network namespace path. 容器的名稱空間的路徑,比如 /proc/[pid]/ns/net。
- Network configuration. 這是一個json的文件,具體可以參看network-configuration
- Extra arguments. 其他引數
- Name of the interface inside the container. 容器內的網絡卡名
返回值:
- IPs assigned to the interface. ipv4或者ipv6地址
- DNS information. DNS相關資訊
2:CNM
相較於CNI,CNM是docker公司力推的網路模型。其主要模型如下圖:
Sandbox
Sandbox包含了一個容器的網路棧。包括了管理容器的網絡卡,路由表以及DNS設定。一種Sandbox的實現是通過linux的網路名稱空間,一個FreeBSD Jail 或者其他類似的概念。一個Sandbox可以包含多個endpoints。
Endpoint
一個endpoint將Sandbox連線到network上。一個endpoint的實現可以通過veth pair,Open vSwitch internal port 或者其他的方式。一個endpoint只能屬於一個network,也只能屬於一個sandbox。
Network
一個network是一組可以相互通訊的endpoints組成。一個network的實現可以是linux bridge,vlan或者其他方式。一個網路中可以包含很多個endpoints。
介面
CNM的介面相較於CNI模型,較為複雜。其提供了remote plugin的方式,進行外掛化開發。remote plugin相較與CNI的命令列,更加友好一些,是通過http請求進行的。remote plugin監聽一個指定的埠,docker daemon直接通過這個埠與remote plugin進行互動。
鑑於CNM的介面較多,這裡就不一一展開解釋了。這裡主要介紹下在進行docker的操作中,docker daemon是如何同CNM外掛繁盛互動。
呼叫過程
- Create Network
這一系列呼叫發生在使用docker network create的過程中。
/IpamDriver.RequestPool: 建立subnetpool用於分配IP
/IpamDriver.RequestAddress: 為gateway獲取IP
/NetworkDriver.CreateNetwork: 建立neutron network和subnet
- Create Container
這一系列呼叫發生在使用docker run,建立一個contain的過程中。當然,也可以通過docker network connect觸發。
/IpamDriver.RequestAddress: 為容器獲取IP
/NetworkDriver.CreateEndpoint: 建立neutron port
/NetworkDriver.Join: 為容器和port繫結
/NetworkDriver.ProgramExternalConnectivity:
/NetworkDriver.EndpointOperInfo
- Delete Container
這一系列呼叫發生在使用docker delete,刪除一個contain的過程中。當然,也可以通過docker network disconnect觸發。
/NetworkDriver.RevokeExternalConnectivity
/NetworkDriver.Leave: 容器和port解綁
/NetworkDriver.DeleteEndpoint
/IpamDriver.ReleaseAddress: 刪除port並釋放IP
- Delete Network
這一系列呼叫發生在使用docker network delete的過程中。
/NetworkDriver.DeleteNetwork: 刪除network
/IpamDriver.ReleaseAddress: 釋放gateway的IP
/IpamDriver.ReleasePool: 刪除subnetpool
3:CNI與CNM的轉化
CNI和CNM並非是完全不可調和的兩個模型。二者可以進行轉化。比如calico專案就是直接支援兩種介面模型。
從模型中來看,CNI中的container應與CNM的sandbox概念一致,CNI中的network與CNM中的network一致。在CNI中,CNM中的endpoint被隱含在了ADD/DELETE的操作中。CNI介面更加簡潔,把更多的工作託管給了容器的管理者和網路的管理者。從這個角度來說,CNI的ADD/DELETE介面其實只是實現了docker network connect和docker network disconnect兩個命令。
kubernetes/contrib專案提供了一種從CNI向CNM轉化的過程。其中原理很簡單,就是直接通過shell指令碼執行了docker network connect和docker network disconnect命令,來實現從CNI到CNM的轉化。
相關推薦
關於docker容器網路的一些理解
開啟微信掃一掃,關注微信公眾號【資料與演算法聯盟】 轉載請註明出處:http://blog.csdn.net/gamer_gyt 博主微博:http://weibo.com/234654758 Github:https://github.c
Kubernetes & Docker 容器網路終極之戰
與 Docker 預設的網路模型不同,Kubernetes 形成了一套自己的網路模型,該網路模型更加適應傳統的網路模式,應用能夠平滑的從非容器環境遷移到 Kubernetes 環境中。 自從 Docker 容器出現,容器的網路通訊一直是眾人關注的焦點,而容器的網路方案又可以分為兩大部分: 單主機的容
使用 Docker 容器網路
Docker 容器網路概述 要構建具有安全的一致行為的 Web 應用程式,可以使用 Docker 網路特性。根據定義,網路為容器實現了完全隔離。因此,控制您的應用程式所在的網路很重要。Docker 容器網路為您提供了這種控制能力。 本文將概述 Docker 引擎交付原生的
Kubernetes & Docker 容器網路終極之戰(十四)
目錄 一、單主機 Docker 網路通訊 1.1、host 模式 1.2 Bridge 模式 1.3 Container 模式 1.4、None 模式 二、跨主機 Docker 網路通訊分類 2.1 通訊方案 2.2、容器網路規範
Docker網路體系結構:設計可擴充套件、可移植的Docker容器網路
原文地址譯者:本人翻譯水平有限,目的僅是為了學好Docker,如有錯誤請見諒。翻譯版本:v1.01(將不斷優化翻譯質量)本文包含以下內容Docker容器就是將應用及其所依賴執行環境的完整檔案系統打成一個包:包括所需程式碼,執行庫,系統工具,系統庫等。如此來保證應用和應用的執行
docker學習(五)—— docker容器網路
ip netns管理網路名稱空間 檢視幫助: [[email protected] ~]# ip netns help Usage: ip netns list ip netns add NAME ip netns set
docker容器網路通訊原理分析
文/ 天雲軟體 雲平臺開發工程師 馮建建 馮建建現主要負責天雲軟體SkyForm CMP的設計和開發工作,熟悉CloudStack,OpenStack等開源雲平臺軟體,同時對docker有一定研究積累和經驗。 概述 自從docker容器出現以來,容器的網路通訊就一直是大家關
初學Docker容器網路不得不看的學習筆記
一、關於Docker Docker 是一個開源的應用容器引擎,基於 Go 語言 並遵從Apache2.0協議開源。 Docker 可以讓開發者打包他們的應用以及依賴包到一個輕量級、可移植的容器中,然後釋出到任何流行的 Linux 機器上,也可以實現虛擬化。容器是完全使用沙箱機制,相互之間不會有任何介面(類
Docker容器網路-實現篇
> 通常,Linux容器的網路是被隔離在它自己的Network Namespace中,其中就包括:網絡卡(Network Interface)、迴環裝置(Loopback Device)、路由表(Routing Table)和iptables規則。對於一個程序來說,這些要素,就構成了它發起和響應網路請求
理解Docker跨多主機容器網路
在Docker 1.9 出世前,跨多主機的容器通訊方案大致有如下三種: 1、埠對映 將宿主機A的埠P對映到容器C的網路空間監聽的埠P’上,僅提供四層及以上應用和服務使用。這樣其他主機上的容器通過訪問宿主機A的埠P實 現與容器C的通訊。顯然這個方案的應用場景很有侷限。 2、將物理網絡卡橋接到虛擬網橋,使得容
理解docker部署springboot-容器網路使用(三)
這篇主要是學習了docker網路相關的知識,主要參考以下三篇文章:容器預設網路bridge,使用 Docker 容器網,Docker網路詳解及pipework原始碼解讀與實踐,最後一篇原理更清楚一些。要構建具有安全的一致行為的 Web 應用程式,可以使用 Docker
理解容器之間的連通性 - 每天5分鐘玩轉 Docker 容器技術(34)
docker 教程 容器 通過前面小節的實踐,當前 docker host 的網絡拓撲結構如下圖所示,今天我們將討論這幾個容器之間的連通性。兩個 busybox 容器都掛在 my_net2 上,應該能夠互通,我們驗證一下:可見同一網絡中的容器、網關之間都是可以通信的。my_net2 與默認 bri
10張圖帶你深入理解Docker容器和鏡像-轉
轉換 AS pos run IT tree 很難 的區別 write 轉載:http://dockone.io/article/783 這篇文章希望能夠幫助讀者深入理解Docker的命令,還有容器(container)和鏡像(image)之間的區別,並深入探討容器和運行
docker 容器和鏡像理解
文本文 inux 新的 理解 docker -- 開始 str 查找 1、鏡像是Docker容器的基石,容器是鏡像的運行實例,有了鏡像才能啟動容器。容器和鏡像是一對一的,一個容器裏就運行一個鏡像。 1、base鏡像----提供了一個基本的操作系統環境,用戶可以根據需要安
理解Docker(4):Docker 容器使用 cgroups 限制資源使用
來源:http://www.cnblogs.com/sammyliu/p/5886833.html 上一篇文章將到 Docker 容器使用 linux namespace 來隔離其執行環境,使得容器中的程序看起來就像愛一個獨立環境中執行一樣。但是,光有執行環境隔離還不夠,因為這些程序還是可以不受
docker容器二探—docker網路、儲存卷和Dockerfile
docker容器二探—docker網路、儲存卷和Dockerfile ----------------------------------------------------
對GAN網路公式推導的一些理解
詳見https://blog.csdn.net/mr_tyting/article/details/79336802 這段公式表示,首先固定生成器,也就是G的網路引數,然後判別器D要使V的值儘可能大,也就是真實樣本和造假樣本的區別要儘可能大(故意找茬)。然後關於這個V函式的構造其實也挺好理解的,
docker容器技術之虛擬化網路概述(四)
前一篇文章連結:Docker容器技術之映象管理基礎(三) 目錄 一、docker網路簡介 1、 虛擬網路通訊的三種方式 1.1、橋接網路: 什麼是MAC: 1.2、NAT網路: 1.3、Overlay Network 2、
docker管理應用程式資料、容器網路
管理應用程式資料 Docker提供三種方式將資料從宿主機掛載到容器中: • volumes:Docker管理宿主機檔案系統的一部分(/var/lib/docker/volumes)。儲存資料的最佳方式。 • bind mounts:將宿主機上的任意位置的檔案或者目錄掛載到容器中。 • tmp
對CNN網路卷積層的一些理解
關於CNN的全連線層可以看這篇文章:https://blog.csdn.net/zgcr654321/article/details/84894860 CNN網路的卷積層的組成和全連線層類似,它也由線性部分和非線性部分組成。但是CNN卷積層的線性部分計算與全連線層不同。 CNN卷積層的線