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網絡
而後建立一個新的 web 容器,並將它鏈接到 db 容器
--link 標記的格式: --link name:alias , name 是咱們要連接的容器的名稱, alias 是這個連接的別名。
使用docker ps來查看容器的鏈接
咱們能夠看到咱們命名的容器, 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 文件
這裏有 2 個 hosts,第一個是 web 容器,web 容器用 id 做爲他的主機名,第二個是 dbserver 容器的 ip 和主機名。能夠在 web 容器中安裝 ping 命令來測試跟dbserver容器的連通。
注意:官方的鏡像默認沒有安裝 ping,須要自行安裝,軟件包名iputils
用 ping 來測試db容器,
附:在bridge模式下,連在同一網橋上的容器能夠相互通訊(若出於安全考慮,也能夠禁止它們之間通訊,方法是在DOCKER_OPTS變量中設置--icc=false,這樣只有使用--link才能使兩個容器通訊)。
docker 默認的橋接網卡是 docker0 。它只會在本機橋接全部的容器網卡,舉例來講容器的虛擬網卡在主機上看通常叫作 vethxxx,而 docker 只是把全部這些網卡橋接在一塊兒,以下:
這樣就能夠把這個網絡當作是一個私有的網絡,經過 nat 鏈接外網,若是要讓外網鏈接到容器中,就須要作端口映射,即 -p 參數。
若是在企業內部應用,或則作多個物理主機的集羣,可能須要將多個物理主機的容器組到一個物理網絡中來,那麼就須要將這個網橋橋接到咱們指定的網卡上。
主機 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
配置橋接網絡
重啓network服務
把 docker 的橋接指定爲 br0,這樣跨主機不一樣容器之間經過 pipework 新建 docker 容器的網卡橋接到 br0,這樣跨主機容器之間就能夠通訊了。
CentOS 7/RHEL 7系統
#systemctl stop docker
修改/etc/sysconfig/docker
#systemctl start docker
pipework
把 docker 默認橋接指定到了 br0,則最好在建立容器的時候加上--net=none,防止自動分配的 IP 在局域網中有衝突。
使用鏡像運行一個容器
注:默認不指定網卡設備名,則默認添加爲 eth1
注:另外 pipework 不能添加靜態路由,若是有需求則能夠在 run 的時候加上 --privileged=true 權限在容器中手動添加,但這種安全性有缺陷,能夠經過 ip netns 操做
route -n查看路由信息:
訪問容器提供的web服務:
使用ip netns添加靜態路由,避免建立容器使用--privileged=true選項形成一些沒必要要的安全問題:
進入容器查看路由記錄:
在其它宿主機進行相應的配置,新建容器並使用 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上,並把enp0s3的IP配置在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和主機網絡裏的機器相互通訊了。
進入容器內部查看容器的地址:
pipework工做原理分析
那麼容器到底發生了哪些變化呢?咱們docker attach到test1上,發現容器中多了一塊eth1的網卡,而且配置了192.168.1.150/24的IP,並且默認路由也改成了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出去,而不是經過eth0和docker0。(若想徹底拋棄自帶的網絡設置,在啓動容器的時候能夠指定--net=none)
以上就是pipework配置Docker網絡的過程,這和Docker的bridge模式有着類似的步驟。事實上,Docker在實現上也採用了相同的底層機制。
經過源代碼,能夠看出,pipework經過封裝Linux上的ip、brctl等命令,簡化了在複雜場景下對容器鏈接的操做命令,爲咱們配置複雜的網絡拓撲提供了一個強有力的工具。固然,若是想了解底層的操做,咱們也能夠直接使用這些Linux命令來完成工做,甚至能夠根據本身的需求,添加額外的功能。
2 單主機Docker容器VLAN劃分
pipework不只可使用Linux bridge鏈接Docker容器,還能夠與OpenVswitch結合,實現Docker容器的VLAN劃分。下面,就來簡單演示一下,在單機環境下,如何實現Docker容器間的二層隔離。
爲了演示隔離效果,咱們將4個容器放在了同一個IP網段中。但實際他們是二層隔離的兩個網絡,有不一樣的廣播域。
安裝openvswitch
安裝基礎環境
下載openvswitch的包
wgethttp://openvswitch.org/releases/openvswitch-2.3.1.tar.gz
解壓與打包
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
以後會在~/rpmbuild/RPMS/x86_64/裏有2個文件
安裝第一個就行
啓動
或
systemctl start openvswitch
查看狀態
或
能夠看到是正常運行狀態
安裝pipework過程略,參考前面的操做
建立交換機,把物理網卡加入ovs1
在主機A上建立4個Docker容器,test1、test2、test3、test4
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
將test1,test2劃分到一個vlan中,vlan在mac地址後加@指定,此處mac地址省略。
pipework ovs1 test1 192.168.1.1/24 @100(注:有空格)
pipework ovs1 test2 192.168.1.2/24 @100(注:有空格)
將test3,test4劃分到另外一個vlan中
pipework ovs1 test3 192.168.1.3/24 @200(注:有空格)
pipework ovs1 test4 192.168.1.4/24 @200(注:有空格)
完成上述操做後,使用docker attach連到容器中,而後用ping命令測試連通性,發現test1和test2能夠相互通訊,但與test3和test4隔離。這樣,一個簡單的VLAN隔離容器網絡就已經完成。
因爲OpenVswitch自己支持VLAN功能,因此這裏pipework所作的工做和以前介紹的基本同樣,只不過將Linux bridge替換成了OpenVswitch,在將veth pair的一端加入ovs0網橋時,指定了tag。底層操做以下:
ovs-vsctl add-port ovs0 veth* tag=100
3 多主機Docker容器的VLAN劃分
上面介紹完了單主機上VLAN的隔離,下面咱們將狀況延伸到多主機的狀況。有了前面兩個例子作鋪墊,這個也就不難了。爲了實現這個目的,咱們把宿主機上的網卡橋接到各自的OVS網橋上,而後再爲容器配置IP和VLAN就能夠了。咱們實驗環境以下,主機A和B各有一塊網卡enp0s3,IP地址分別爲10.10.101.105/24、10.10.101.106/24。在主機A上建立兩個容器test1、test2,分別在VLAN 100和VLAN 200上。在主機B上建立test3、test4,分別在VLAN 100和VLAN 200 上。最終,test1能夠和test3通訊,test2能夠和test4通訊。
在主機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 100和VLAN 200的包經過)。
注:除此以外,pipework還支持使用macvlan設備、設置網卡MAC地址等功能。不過,pipework有一個缺陷,就是配置的容器在關掉重啓後,以前的設置會丟失。
其中promisc表示網卡混雜模式
其餘參數的含義:
UP: 表示網卡開啓狀態;
BROADCAST: 表示支持廣播;
promisc: 表示網卡混雜模式;
RUNNING: 表示網卡的網線被接上;
MULTICAST: 表示支持組播;
MTU: 表示MaximumTrasmission Unit 最大傳輸單元(字節),即此接口一次所能傳輸的最大封包;
RX: 表示網絡由激活到目前爲止接收的數據包;
TX: 表示網絡由激活到目前爲止發送的數據包;
collisions: 表示網絡信號衝突的狀況;
txqueuelen: 表示傳輸緩衝區長度大小;
設置網卡工做模式
#ifconfig 網卡名 promisc 設置混雜
#ifconfig 網卡名 -promisc 取消混雜
網卡工做模式有4種,分別是:
廣播(Broadcast)模式
多播(Multicast)模式
單播模式(Unicast)
混雜模式(Promiscuous)
在混雜模式下的網卡可以接收一切經過它的數據,而無論該數據目的地址是不是它。若是經過程序將網卡的工做模式設置爲「混雜模式」,那麼網卡將接受全部流經它的數據幀,這實際上就是Sniffer工做的基本原理:讓網卡接收一切他所能接收的數據。Sniffer就是一種能將本地網卡狀態設成混雜(promiscuous)狀態的軟件,當網卡處於這種"混雜"方式時,它對全部遇到的每個數據幀都產生一個硬件中斷以便提醒操做系統處理流經該物理媒體上的每個報文包。可見,Sniffer工做在網絡環境中的底層,它會攔截全部的正在網絡上傳送的數據,而且經過相應的軟件處理,能夠實時分析這些數據的內容,進而分析所處的網絡狀態和總體佈局。