1. 程式人生 > >關於docker容器網路的一些理解

關於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卷積層的線