docker基礎篇(一)補

  通過一個星期的加班到9點,終於將docker的網絡部分小小的總結了一下,小編在這以前也發佈過關於docker的內容,原本想就此結束,可是總感受少了些什麼,只會docker的命令,彷彿不能深刻的理解docker強大之處,因此小編決定在補充一下關於docker的網絡部分,包括docker的網絡模式、容器通訊、以及相應的實戰操做。雖然這部分有些難以理解,可是細細研讀以後,必定會有所收穫。git

1.docker的網絡模式

  安裝Docker時,它會自動建立三個網絡,bridge(建立容器默認鏈接到此網絡,也就是在不使用--network參數時)、 none 、host。還有之後一種自定義模式,自定義模式有三種:bridge、overlay、macvlan。
咱們可使用一下命令,查看本機容器間通訊的幾種方式:github

docker network ls

docker基礎篇(一)補
  咱們能夠在docker run的時候使用--net= none/ host/ bridge來設置容器具體使用哪一種模式。web

(1)默認網絡通訊模式bridge網橋

  默認狀況下docker運行容器時,宿主機會建立一個bridge網橋,是一個名叫docker 0的虛擬網橋 ,默認docker 0 IP爲172.17.0.1,網橋再給容器分配虛擬子網IP,而且以網橋IP做爲網關。在不指定網絡的狀況下,容器之間的通訊都是經過bridge網橋進行通訊。而後網橋在與宿主機鏡像進行IP轉換,端口映射等通訊。
  這種bridge網橋與容器,與宿主機之間的通訊,有點相似與三層路由交換:
    docker基礎篇(一)補docker

(2) host宿主機模式

  若是容器指定網絡模式爲host,容器不會有本身的network namespace,而是和宿主機共用一個network網絡及IP,容器不會有虛擬出本身的網卡、IP等,固然除了網絡通訊這一塊和宿主機綁定了,其他的容器內容仍是和宿主機安全隔離了。這種在作容器遷移時,很不方便,不推薦使用。
docker基礎篇(一)補apache

(3) none模式

  容器指定網絡模式-net爲none時,docker容器再也不擁有本身的network namespace,可是全部網絡配置都得自行配置,如IP、網卡等,這種方式很麻煩。(關閉了容器的網絡功能)
docker基礎篇(一)補
這裏補充兩個docker服務運行時參數
-b BRIDGE or--bridge=BRIDGE ——指定容器掛載的網橋;
--fixed-cidr=10.200.55.64/26 #定製容器的IP地址範圍編程

2.單機間的容器通訊

  單機間的通訊,就是同一宿主機中的不一樣容器之間的通訊,容器之間可經過 IP,Docker DNS Server 和joined 容器三種方式通訊。ubuntu

(1)IP通訊

  兩個容器要能通訊,必需要有屬於同一個網絡的網卡。知足這個條件後,容器就能夠經過 IP 交互了。這也是默認的方式,咱們在使用--net= bridge,docker虛擬出來的一個docker0網橋,會給每個容器在docker0網橋的網段中分配一個IP,這樣同主機中的容器的IP是同一網段的天然能夠經過IP相互訪問。
演示:vim

[root@zzy ~]# ifconfig

docker基礎篇(一)補
這裏看到個人這臺機器中的docker0的網橋的地址爲172.17.0.1,這臺機器中啓動的全部的docker的容器的IP都是這個網段的。安全

[root@zy ~]# docker ps  #查看正在運行的docker容器

docker基礎篇(一)補
我這裏有兩個一個是registry一個是MySQL。bash

[root@zy ~]# docker inspect 28b2c91d4be4|grep -i ipaddress #查看容器的IP

docker基礎篇(一)補

[root@zy ~]# docker inspect 5708c1dcbdd7|grep -i ipaddress #查看容器的IP

docker基礎篇(一)補
能夠發現這兩個容器的IP地址果真都是172.17.0.1網段的。

(2)docker DNS server

  經過 IP 訪問容器雖然知足了通訊的需求,但仍是不夠靈活。由於咱們在部署服務以前可能不能肯定IP。好比:如今部署一個Nginx web服務,可是每次容器啓動分配的IP地址都會改變,咱們沒法經過固定的IIP地址去訪問web服務,這樣每次訪問時都要查看IP,很是麻煩,對於這個問題,能夠經過 docker 自帶的 DNS 服務解決。
  從 Docker 1.10 版本開始,docker daemon 實現了一個內嵌的 DNS server,使容器能夠直接經過"容器名"通訊。方法很簡單,只要在啓動時用 --name 爲容器命名就能夠了。
演示:

#下面在同主機啓動兩個Ubuntu系統並指定--name:
[root@zy ~]#docker run -it --network=brideg2 --name box1 ubuntu:net /bin/bash
[root@zy ~]#docker run -it --name --network= brideg2 box2 ubuntu:net /bin/bash

docker基礎篇(一)補
咱們發現使用--name,的容器名稱能夠ping通其餘容器。
注意:使用 docker DNS 有個限制:只能在 user-defined 網絡中使用。也就是說,默認的 bridge 網絡是沒法使用 DNS 的。

(3) joined 容器

  joined 容器是另外一種實現容器間通訊的方式。它可使兩個或多個容器共享一個網絡棧,共享網卡和配置信息,joined 容器之間能夠經過 127.0.0.1 直接通訊。
演示:

#啓動一個http服務
[root@zy ~]# docker run -dit --name my-apache-app  -p 8099:80 -v "/http":/usr/local/apache2/htdocs/ httpd
#建立一個Ubuntu容器容器並經過 --network=container: my-apache-app指定 jointed 容器爲 my-apache-app
[root@zy ~]# docker run -it --network=container:my-apache-app ubuntu:net /bin/bash
#使用命令去訪問my-apache-app容器中的web頁面
root@ec745e2fbf4a:/# curl 127.0.0.1

docker基礎篇(一)補
此時咱們發現訪問成功!緣由是:咱們分別查看着兩個容器的IP:
Ubuntu:
docker基礎篇(一)補
http:
docker基礎篇(一)補
咱們發現兩個容器的網卡 mac 地址與 IP 徹底同樣,它們共享了相同的網絡棧。因此Ubuntu容器可使用127.0.0.1直接訪問http容器的web服務。

(4) 補充

docker run 命令的參數介紹:

-h 運行容器時指定主機名,這樣咱們可使用主機名去與容器通訊。
    --link=容器名 別名  ,這樣使用--link鏈接的容器間就可使用主機名進行通訊。
    -p host_port:container_port 端口映射,容器的服務端口映射到宿主機。
    -P  container_port    端口映射,映射到宿主機的任意空閒端口。

容器的訪問控制
容器訪問外部網絡:兩種方法:
  - sysctl -w net.ipv4.ip_forward=1 (設置宿主機的開啓數據轉發)
  - 啓動Docker服務的時候設定--ip-forward=true,docker會自動打開宿主機系統的轉發服務
外部訪問容器:這裏很簡單,經過docker run -h hostname -p 端口映射,來實現外部訪問容器。

3.跨主機間的容器通訊

(1)Docker網橋實現跨主機容器鏈接

  在同一宿主機下docker容器之間是能夠相同連通的。這是由於默認的docker容器在同一宿主機下,全部容器分配的IP處於同一個地址段的,相互之間能夠ping通;當咱們使用ifconfig命令查看IP時會發現,其中有一個docker0的網橋,docker容器經過docker0 網橋實現同一主機間中,容器的IP地址分配和訪問,這就保證了全部的容器在同一地址段。
  雖然這些IP地址在同一宿主機中是處於同一網段而且相互之間能夠通訊,可是若是在不一樣宿主機之間,若是網橋的網段不一樣,容器之間仍是不可能實現跨住進的通訊,那麼咱們能夠將每一個主機下的容器的網段都處於同一網段,這樣,就能夠實現跨主機的訪問啦,這也是Docker容器默認跨主機之間的鏈接方法的第一種:網橋實現。
docker基礎篇(一)補
  上圖就是網橋方式實現跨主機的鏈接,可是缺點也很明顯,宿主機和容器的IP處於同一網段,若是在局域網下,IP地址是有限的,那麼一個容器佔據一個IP地址,IP地址很快就會被用光,這就是個不友好的現象,因此這種方式僅僅只用來學習測試使用。
實戰操做:
實驗環境:

主機名 IP Gateway Netmask
Host1 192.168.130.130 192.168.130.2 255.255.255.0
Host2 192.168.130.131 192.168.130.2 255.255.255.0

① 下載網橋管理工具

yum install -y bridge-utils

② 分別在docker主機上創建網橋

Host1: $ sudo brctl addbr br0
Host2: $ sudo brctl addbr br0

③ 爲網橋分配一個同網段IP

Host1: $ sudo ifconfig br0 192.168.130.10 netmask 255.255.255.0
Host2: $ sudo ifconfig br0 192.168.130.20 netmask 255.255.255.0

④ 橋接本地網卡

Host1: $ brctl addif br0 eth0
Host2: $ brctl addif br0 eth0

⑤ 修改docker配置文件

$ Host1 vim /etc/default/docker
$ Host2 vim /etc/default/docker

改爲:Host1: DOCKER_OPTS=」 -b=br0 –fixed-cidr=‘192.168.130.64/26「
Host2: DOCKER_OPTS=」 -b=br1 –fixed-cidr=‘192.168.130.128/26「
這裏的:
-b :用來指定容器鏈接的網橋的名字。
--fixed-cidr :用來限定容器分配的IP地址的範圍。
⑥重啓docker

$ Host1 systemctl daemon-reload
$ Host1 systemctl restart docker 
$ Host2 systemctl daemon-reload
$ Host2 systemctl restart docker

⑦ 測試
這裏在host1和host2中各啓動一個容器,而後相互ping對方容器IP,若是能夠ping桶表示配置成功。

(2)Open vSwitch 實現跨主機容器通訊

  Open vSwitch是一個高質量、多層虛擬交換機。使用Apache2.0許可協議,旨在經過編程擴展,使龐大的網絡自動化(配置、管理、維護),同時還支持標準的管理接口和協議。
docker基礎篇(一)補
實戰操做:

實驗環境:

主機名 IP Gateway Netmask
Host1 192.168.130.130 192.168.130.2 255.255.255.0
Host2 192.168.130.131 192.168.130.2 255.255.255.0

虛擬機網段:

主機名 網段
Host1 192.168.1.1
Host2 192.168.2.1

操做步驟:

  • 在虛擬機中創建ovs網橋
  • 添加gre鏈接
  • 配置docker容器虛擬網橋接
  • 爲虛擬網橋添加ovs接口
  • 添加不一樣Docker容器網段路由
    ① 安裝Open vSwitch並啓動

    [root@ Host1~]#yum install -y openvswitch.x86_64
    [root@ Host1~]#systemctl start openvswitch

② 安裝網橋

[root@ Host1~]# yum install -y bridge-utils

③ 創建ovs網橋並添加GRE接口

[root@ Host1~]# ovs-vsctl add-br obr0
[root@ Host1~]# ovs-vsctl add-port obr0 gre0

④ 設置遠程的網橋鏈接

[root@ Host1~]#ovs-vsctl set interface gre0 type=gre options:remote_ip=192.168.130.131
#查看osv網橋配置
[root@ Host1~]#ovs-vsctl show

⑤ 設置docker的虛擬網橋

[root@ Host1~]#brctl addbr br0
[root@ Host1~]#ifconfig br0 192.168.1.1 netmask 255.255.255.0
[root@ Host1~]#brctl addif br0 obr0
[root@ Host1~]#brctl show

⑥ 設置路由規則

[root@ Host1~]#ip route add 192.168.2.0/24 via 192.168.130.131 dev ens33

同理host2也須要按照上述方式配置。最後兩個容器之間就能夠通訊。

(3)Weave實現跨主機容器通訊

   Weave是由weaveworks公司開發的解決Docker跨主機網絡的解決方案,它可以建立一個虛擬網絡,用於鏈接部署在多臺主機上的Docker容器,這樣容器就像被接入了同一個網絡交換機,那些使用網絡的應用程序沒必要去配置端口映射和連接等信息。
  外部設備可以訪問Weave網絡上的應用程序容器所提供的服務,同時已有的內部系統也可以暴露到應用程序容器上。Weave可以穿透防火牆並運行在部分鏈接的網絡上,另外,Weave的通訊支持加密,因此用戶能夠從一個不受信任的網絡鏈接到主機。
原理:

docker基礎篇(一)補
  Weave會在主機上建立一個網橋,每個容器經過 veth pair 鏈接到該網橋上,同時網橋上有個 Weave router 的容器與之鏈接,該router會經過鏈接在網橋上的接口來抓取網絡包(該接口工做在Promiscuous模式)。
  在每個部署Docker的主機(多是物理機也多是虛擬機)上都部署有一個W(即Weave router),它自己也能夠一個容器的形式部署。Weave run的時候就能夠給每一個veth的容器端分配一個ip和相應的掩碼。veth的網橋這端就是Weave router容器,並在Weave launch的時候分配好ip和掩碼。
  Weave網絡是由這些weave routers組成的對等端點(peer)構成,每一個對等的一端都有本身的名字,其中包括一個可讀性好的名字用於表示狀態和日誌的輸出,一個惟一標識符用於運行中相互區別,即便重啓Docker主機名字也保持不變,這些名字默認是mac地址。
  每一個部署了Weave router的主機都須要將TCP和UDP的6783端口的防火牆設置打開,保證Weave router之間控制面流量和數據面流量的經過。控制面由weave routers之間創建的TCP鏈接構成,經過它進行握手和拓撲關係信息的交換通訊。 這個通訊能夠被配置爲加密通訊。而數據面由Weave routers之間創建的UDP鏈接構成,這些鏈接大部分都會加密。這些鏈接都是全雙工的,而且能夠穿越防火牆。
實戰操做:
實驗環境:

主機名 IP Gateway Netmask
Host1 192.168.130.130 192.168.130.2 255.255.255.0
Host2 192.168.130.131 192.168.130.2 255.255.255.0

① 下載複製weave二進制執行文件

[root@ Host1~]#git clone https://github.com/weaveworks/weave
[root@ Host1~]#cp -p /root/weave/weave  /usr/bin/
[root@ Host1~]#cd /usr/bin/
#查看weave版本
[root@ Host1~]#weave version

docker基礎篇(一)補
② 啓動weave服務

[root@ Host1~]# weave launch --no-detect-tls  #注意第一次啓動會在docker中拉取相應的鏡像

③ 運行一個容器

[root@ Host1~]#docker run -it ubuntu:net /bin/bash

而後Ctrl+p+q退出容器,而且讓容器後臺運行
④ 進入容器

[root@ Host1~]#weave attach 192.168.2.1/24 c45932ef7da4

注意:這裏的192.168.2.1/24 是默認的給當前容器分配的一個weaveIP
docker基礎篇(一)補
以後再host2宿主機中也執行以上的命令,而且在「weave attach 192.168.2.1/24 容器ID」 這裏分配一相同網段的不一樣IP。
docker基礎篇(一)補
此時經過這個ethwe中的IP,去相同ping對方容器,這裏就能夠相同訪問:
docker基礎篇(一)補

相關文章
相關標籤/搜索