docker容器的互聯

     http://xiaorenwutest.blog.51cto.com     git

                 docker容器面向對象的應用github

在前面咱們有講過docker容器的運行的4種模式:web

host模式、容器模式、網橋模式以及none模式,各有各的特色,今天主要實現docker容器的互聯以及經過pipework工具建立自定義網橋,經過自定義網橋爲咱們的容器分配ip地址,另外也可讓docker容器本身經過自定義ip地址能夠在互聯網上進行通訊,(這裏知道即可,生產環境下沒有必要)不安全。docker

還有個知識點是將源碼包轉換爲rpm包,減小工做的繁瑣流程,提升工做效率。shell

最後咱們能夠將docker容器劃分到不一樣的vlan做用區域中阻隔它們之間的通訊,減小網絡風暴。數據庫

 

容器互聯ubuntu

使用--link參數可讓容器之間安全的進行交互。安全

下面先建立一個新的數據庫容器。bash

docker run -dit --name dbserver鏡像id網絡

wKiom1kdpQrCcdzAAABH2wXYyi4570.png-wh_50 

而後建立一個新的 web 容器,並將它鏈接到 db 容器

wKiom1kdpS7gU5m4AAAcyLE8zSo031.png-wh_50 

--link 標記的格式: --link name:alias name 是咱們要連接的容器的名稱, alias 是這個連接的別名。

使用docker ps來查看容器的鏈接

wKioL1kdpTih-fB8AABQibGVIyI416.png-wh_50 

咱們能夠看到咱們命名的容器, dbserver web dbserver 容器的 names 列有 dbserver 也有 web/dbserver 。這表示 web 容器連接到 db 容器,他們是一個父子關係。在這個 link 中, 2 個容器中有一對父子關係。 docker 2 個容器之間建立了一個安全的鏈接,並且不用映射dbserver容器的端口到宿主主機上。因此在啓動 db 容器的時候也不用 -p -P 標記。使用 link 以後咱們就能夠不用暴露數據庫端口到網絡上。

 

注意:你能夠連接多個子容器到父容器,好比咱們能夠連接多個 web db 容器上。

 

Docker 會添加子容器的 host 信息到父容器的  /etc/hosts  的文件。

下面是父容器 web hosts 文件

wKiom1kdpVXz6rmXAAA5ME7Mfw4136.png-wh_50 

這裏有 2 hosts,第一個是 web 容器,web 容器用 id 做爲他的主機名,第二個是 dbserver 容器的 ip 和主機名。能夠在 web 容器中安裝 ping 命令來測試跟dbserver容器的連通。

注意:官方的鏡像默認沒有安裝 ping,須要自行安裝,軟件包名iputils

wKioL1kdpWzh8I7oAAAaq2YlDxk393.png-wh_50 

ping 來測試db容器,

wKioL1kdqEbAvji9AABThThhLvY202.png-wh_50 

 

附:bridge模式下,連在同一網橋上的容器能夠相互通訊(若出於安全考慮,也能夠禁止它們之間通訊,方法是在DOCKER_OPTS變量中設置--icc=false,這樣只有使用--link才能使兩個容器通訊)。

 

多臺物理主機之間的容器互聯(暴露容器到真實網絡中)

wKioL1kdqF-zESRBAABoWojuRbY545.png-wh_50 

docker  默認的橋接網卡是 docker0 。它只會在本機橋接全部的容器網卡,舉例來講容器的虛擬網卡在主機上看通常叫作 vethxxx,而 docker 只是把全部這些網卡橋接在一塊兒,以下:

wKiom1kdqHjjK4IOAAAk1Df09ik966.png-wh_50 

這樣就能夠把這個網絡當作是一個私有的網絡,經過 nat  鏈接外網,若是要讓外網鏈接到容器中,就須要作端口映射,即 -p 參數。

若是在企業內部應用,或則作多個物理主機的集羣,可能須要將多個物理主機的容器組到一個物理網絡中來,那麼就須要將這個網橋橋接到咱們指定的網卡上。

 

wKiom1kdqJWySfLoAAB_7DzAQGw692.png-wh_50 

主機 A 和主機 B 的網卡一都連着物理交換機的同一個 vlan 101, 這樣網橋一和網橋三就至關於在同一個物理網絡中了,而容器1、容器3、容器四也在同一物理網絡中了,他們之間能夠相互通訊,並且能夠跟同一 vlan 中的其餘物理機器互聯。

這樣就直接把容器暴露到物理網絡上了,多臺物理主機的容器也能夠相互聯網了。須要注意的是,這樣就須要本身來保證容器的網絡安全了。

不一樣容器之間的通訊能夠藉助於 pipework 這個工具

pipework是由Docker的工程師Jérme Petazzoni開發的一個Docker網絡配置工具,由200多行shell實現,方便易用。

下載地址:wgethttps://github.com/jpetazzo/pipework.git

unzip  pipework-master.zip

cp  -p  /root/pipework-master/pipework  /usr/local/bin/

安裝相應依賴軟件

yum install bridge-utils -y

配置橋接網絡

wKioL1kdqLOg21noAAANfTpeX0U178.png-wh_50 

wKioL1kdqM2RqEm3AABXhYGEKyw483.png-wh_50 

wKioL1kdqOPRuHiSAAAEgGBgQ6Q569.png-wh_50 

wKiom1kdqPjADDRYAAAfAKoNO3o342.png-wh_50 

重啓network服務

wKioL1kdqQziMVX7AAAIYP6BUdo006.png-wh_50 

wKioL1kdqSGwvfvUAADFFY_Jemk510.png-wh_50 

wKioL1kdqTTTfGrhAAAcXacmFZw102.png-wh_50 

docker 的橋接指定爲 br0,這樣跨主機不一樣容器之間經過 pipework 新建 docker 容器的網卡橋接到 br0,這樣跨主機容器之間就能夠通訊了。

CentOS 7/RHEL 7系統

#systemctl stop docker

修改/etc/sysconfig/docker

wKioL1kdqUiCvHwbAAAM_rJ1XLc794.png-wh_50 

#systemctl start docker

pipework

docker 默認橋接指定到了 br0,則最好在建立容器的時候加上--net=none,防止自動分配的 IP 在局域網中有衝突。

 wKiom1kdqWnTar4xAABARH628-0484.png-wh_50

使用鏡像運行一個容器

wKiom1kdqXzTD_sEAAA_LxHV1AA983.png-wh_50 

注:默認不指定網卡設備名,則默認添加爲 eth1

wKiom1kdqazCju3oAAARxBOTSZw211.png-wh_50

注:另外 pipework 不能添加靜態路由,若是有需求則能夠在 run 的時候加上 --privileged=true 權限在容器中手動添加,但這種安全性有缺陷,能夠經過 ip netns 操做

 

wKioL1kdqcOBcSBTAAD_qbSjB5k248.png-wh_50 

 route -n查看路由信息:

wKioL1kdqe_RPWUkAAAk6kzDG94538.png-wh_50 

訪問容器提供的web服務:

wKioL1kdqgbQUqr9AAETovFaYL8031.png-wh_50 

使用ip netns添加靜態路由,避免建立容器使用--privileged=true選項形成一些沒必要要的安全問題:

wKiom1kdr3nTVmBBAABj10QJCZ4353.png-wh_50 

進入容器查看路由記錄:

wKioL1kdr47SI_-FAAA5iUnhqkE085.png-wh_50 

在其它宿主機進行相應的配置,新建容器並使用 pipework 添加虛擬網卡橋接到 br0,測試通訊狀況便可。

注:能夠刪除 docker0,直接把 docker 的橋接指定爲 br0。也能夠保留使用默認的配置,這樣單主機容器之間的通訊能夠經過 docker0,而跨主機不一樣容器之間經過 pipework 新建docker 容器的網卡橋接到 br0,這樣跨主機容器之間就能夠通訊了。

 

擴展:

pipework能夠在下面用三個場景來使用和工做原理。
1 Docker容器配置到本地網絡環境中
爲了使本地網絡中的機器和Docker容器更方便的通訊,咱們常常會有將Docker容器配置到和主機同一網段的需求。這個需求其實很容易實現,咱們只要將Docker容器和主機的網卡橋接起來,再給Docker容器配上IP就能夠了。
下面咱們來操做一下,我主機A地址爲192.168.1.102/24,網關爲192.168.1.1,須要給Docker容器的地址配置爲192.168.1.150/24。在主機A上作以下操做:
安裝pipework
下載地址:wgethttps://github.com/jpetazzo/pipework.git

unzip  pipework-master.zip

cp  -p  /root/pipework-master/pipework  /usr/local/bin/
啓動Docker容器。
docker run -itd --name test1 鏡像 /bin/bash
配置容器網絡,並連到網橋br0上。網關在IP地址後面加@指定。
pipework br0 test1 192.168.1.150/24@192.168.1.1
將主機enp0s3橋接到br0上,並把enp0s3IP配置在br0上。

ip addr add 192.168.1.102/24 dev br0

ip addr del 192.168.1.102/24 dev enp0s3

brctl addif br0 enp0s3

ip route del default

ip route add default via192.168.1.1 dev br0 

注:若是是遠程操做,中間網絡會斷掉,因此放在一條命令中執行。
ip addr add 192.168.1.102/24 dev br0; \ ip addr del 192.168.1.102/24 dev enp0s3; \ brctl addif br0 enp0s3; \ ip route del default; \ ip route add default via192.168.1.1 dev br0 
完成上述步驟後,咱們發現Docker容器已經可使用新的IP和主機網絡裏的機器相互通訊了。

進入容器內部查看容器的地址:

wKiom1kdr7GAqdENAAC-ByZZ1fc441.png-wh_50pipework工做原理分析
那麼容器到底發生了哪些變化呢?咱們docker attachtest1上,發現容器中多了一塊eth1的網卡,而且配置了192.168.1.150/24IP,並且默認路由也改成了192.168.1.1。這些都是pipework幫咱們配置的。

·首先pipework檢查是否存在br0網橋,若不存在,就本身建立。
   

·建立veth pair設備,用於爲容器提供網卡並鏈接到br0網橋。
   

·使用docker inspect找到容器在主機中的PID,而後經過PID將容器的網絡命名空間連接到/var/run/netns/目錄下。這麼作的目的是,方便在主機上使用ip netns命令配置容器的網絡。由於,在Docker容器中,咱們沒有權限配置網絡環境。
   

·將以前建立的veth pair設備分別加入容器和網橋中。在容器中的名稱默認爲eth1,能夠經過pipework-i參數修改該名稱。
   

·而後就是配置新網卡的IP。若在IP地址的後面加上網關地址,那麼pipework會從新配置默認路由。這樣容器通往外網的流量會經由新配置的eth1出去,而不是經過eth0docker0(若想徹底拋棄自帶的網絡設置,在啓動容器的時候能夠指定--net=none)
以上就是pipework配置Docker網絡的過程,這和Dockerbridge模式有着類似的步驟。事實上,Docker在實現上也採用了相同的底層機制。
經過源代碼,能夠看出,pipework經過封裝Linux上的ipbrctl等命令,簡化了在複雜場景下對容器鏈接的操做命令,爲咱們配置複雜的網絡拓撲提供了一個強有力的工具。固然,若是想了解底層的操做,咱們也能夠直接使用這些Linux命令來完成工做,甚至能夠根據本身的需求,添加額外的功能。


2 單主機Docker容器VLAN劃分
pipework不只可使用Linux bridge鏈接Docker容器,還能夠與OpenVswitch結合,實現Docker容器的VLAN劃分。下面,就來簡單演示一下,在單機環境下,如何實現Docker容器間的二層隔離。
爲了演示隔離效果,咱們將4個容器放在了同一個IP網段中。但實際他們是二層隔離的兩個網絡,有不一樣的廣播域。

安裝openvswitch

安裝基礎環境

  

wKiom1kdr83w4nStAAAYu9Sydgk981.png-wh_50 

下載openvswitch的包

wgethttp://openvswitch.org/releases/openvswitch-2.3.1.tar.gz

wKioL1kdr-WgqplkAAAPENRTxDg851.png-wh_50 

解壓與打包

tar zxvf openvswitch-2.3.1.tar.gz

mkdir -p ~/rpmbuild/SOURCES

cp openvswitch-2.3.1.tar.gz ~/rpmbuild/SOURCES/

sed's/openvswitch-kmod, //g' openvswitch-2.3.1/rhel/openvswitch.spec > openvswitch-2.3.1/rhel/openvswitch_no_kmod.spec

rpmbuild -bb --without check openvswitch-2.3.1/rhel/openvswitch_no_kmod.spec

wKioL1kdr_zQn25SAABWGvBIXYU044.png-wh_50 

 

以後會在~/rpmbuild/RPMS/x86_64/裏有2個文件

wKiom1kdsBPBS-jOAAA6kFMYsPI670.png-wh_50 

安裝第一個就行

wKioL1kdsCfTF3xNAAAUpBmxKM4695.png-wh_50 

啓動

wKioL1kdsEGxG_6dAAAjsLHYHUU090.png-wh_50 

systemctl start openvswitch

 

查看狀態

wKiom1kdsFWR_o0aAAAVx-hDKnU655.png-wh_50 

wKiom1kdsGiBzK9oAAFC-Fha3Vs818.png-wh_50 

能夠看到是正常運行狀態

安裝pipework過程略,參考前面的操做

 

建立交換機,把物理網卡加入ovs1

wKioL1kdsH7R6Wu_AAAgCy7wbVE039.png-wh_50 

wKiom1kdsJLj9ZEwAAFdiAPahjk032.png-wh_50 


在主機A上建立4Docker容器,test1test2test3test4
docker run -itd --name test1 ubuntu /bin/bash

docker run -itd --name test2 ubuntu /bin/bash

docker run -itd --name test3 ubuntu /bin/bash

docker run -itd --name test4 ubuntu /bin/bash
test1test2劃分到一個vlan中,vlanmac地址後加@指定,此處mac地址省略。
pipework ovs1 test1 192.168.1.1/24 @100(注:有空格)

pipework ovs1 test2 192.168.1.2/24 @100(注:有空格)
test3test4劃分到另外一個vlan
pipework ovs1 test3 192.168.1.3/24 @200(注:有空格)

pipework ovs1 test4 192.168.1.4/24 @200(注:有空格)
完成上述操做後,使用docker attach連到容器中,而後用ping命令測試連通性,發現test1test2能夠相互通訊,但與test3test4隔離。這樣,一個簡單的VLAN隔離容器網絡就已經完成。
因爲OpenVswitch自己支持VLAN功能,因此這裏pipework所作的工做和以前介紹的基本同樣,只不過將Linux bridge替換成了OpenVswitch,在將veth pair的一端加入ovs0網橋時,指定了tag。底層操做以下:
ovs-vsctl add-port ovs0 veth* tag=100


3 多主機Docker容器的VLAN劃分
上面介紹完了單主機上VLAN的隔離,下面咱們將狀況延伸到多主機的狀況。有了前面兩個例子作鋪墊,這個也就不難了。爲了實現這個目的,咱們把宿主機上的網卡橋接到各自的OVS網橋上,而後再爲容器配置IPVLAN就能夠了。咱們實驗環境以下,主機AB各有一塊網卡enp0s3IP地址分別爲10.10.101.105/2410.10.101.106/24。在主機A上建立兩個容器test1test2,分別在VLAN 100VLAN 200上。在主機B上建立test3test4,分別在VLAN 100VLAN 200 上。最終,test1能夠和test3通訊,test2能夠和test4通訊。

拓撲圖以下所示
wKiom1kdsKrwi8CSAACBcyi4RNs990.png-wh_50

在主機A
建立Docker容器
docker run -itd --name test1 ubuntu /bin/bash

docker run -itd --name test2 ubuntu /bin/bash
劃分VLAN
pipework ovs0 test1 192.168.0.1/24 @100

pipework ovs0 test2 192.168.0.2/24 @200
eth0橋接到ovs0
ip addr add 10.10.101.105/24 dev ovs0

ip addr del 10.10.101.105/24 dev eth0;

ovs-vsctl add-port ovs0 eth0
ip route del default

ip route add default gw 10.10.101.254 dev ovs0
在主機B
建立Docker容器
docker run -itd --name test3 ubuntu /bin/bash

docker run -itd --name test4 ubuntu /bin/bash
劃分VLAN
pipework ovs0 test1 192.168.0.3/24 @100

pipework ovs0 test2 192.168.0.4/24 @200
eth0橋接到ovs0
ip addr add 10.10.101.106/24 dev ovs0

ip addr del 10.10.101.106/24 dev eth0;

ovs-vsctl add-port ovs0 eth0

ip route del default

ip route add default gw 10.10.101.254 dev ovs0
完成上面的步驟後,主機A上的test1和主機B上的test3容器就劃分到了一個VLAN中,而且與主機A上的test2和主機B上的test4隔離(主機eth0網卡須要設置爲混雜模式,鏈接主機的交換機端口應設置爲trunk模式,即容許VLAN 100VLAN 200的包經過)。

注:除此以外,pipework還支持使用macvlan設備、設置網卡MAC地址等功能。不過,pipework有一個缺陷,就是配置的容器在關掉重啓後,以前的設置會丟失。


wKiom1kdsMKRsM80AABmaunPSms841.png-wh_50

其中promisc表示網卡混雜模式

其餘參數的含義:

UP: 表示網卡開啓狀態;
BROADCAST: 表示支持廣播;
promisc: 表示網卡混雜模式;
RUNNING: 表示網卡的網線被接上;
MULTICAST: 表示支持組播;
MTU: 表示MaximumTrasmission Unit 最大傳輸單元(字節),即此接口一次所能傳輸的最大封包;
RX: 表示網絡由激活到目前爲止接收的數據包;
TX: 表示網絡由激活到目前爲止發送的數據包;
collisions: 表示網絡信號衝突的狀況;
txqueuelen: 表示傳輸緩衝區長度大小;

 

設置網卡工做模式

#ifconfig 網卡名 promisc 設置混雜

#ifconfig 網卡名 -promisc 取消混雜

wKioL1kdsNjgh8ibAABpuYqKbAE308.png-wh_50 

 

網卡工做模式有4種,分別是:
廣播(Broadcast)模式
多播(Multicast)模式
單播模式(Unicast
混雜模式(Promiscuous
在混雜模式下的網卡可以接收一切經過它的數據,而無論該數據目的地址是不是它。若是經過程序將網卡的工做模式設置爲「混雜模式」,那麼網卡將接受全部流經它的數據幀,這實際上就是Sniffer工做的基本原理:讓網卡接收一切他所能接收的數據。Sniffer就是一種能將本地網卡狀態設成混雜(promiscuous)狀態的軟件,當網卡處於這種"混雜"方式時,它對全部遇到的每個數據幀都產生一個硬件中斷以便提醒操做系統處理流經該物理媒體上的每個報文包。可見,Sniffer工做在網絡環境中的底層,它會攔截全部的正在網絡上傳送的數據,而且經過相應的軟件處理,能夠實時分析這些數據的內容,進而分析所處的網絡狀態和總體佈局。

相關文章
相關標籤/搜索