五、docker的網絡

(這裏只考慮單機通信,不考慮集羣跨宿主通信)

網絡模式

Docker支持的五種網絡模式
查看docker支持的網絡模式
docker network ps

Brige
這個是默認網絡 , docker的主進程會默認創建一個docker0的網卡,docker0與宿主機的網卡是橋接的,容器的默認網段是172.0.0.1/ 因此宿主機與容器可以互ping,但是外部不能直接訪問到。但是可以通過iptables規則轉發到裏面

host
容器不會獲得一個獨立的network namespace 而是與宿主機公用一個IP 。實際沒與網絡命名空間隔離,不需要做net轉發,跟直接在真機上跑服務沒有什麼區別。

none
獲取獨立的network namespace 但不爲容器進行任何配置

container
與指定的容器使用同一個network namespace 網卡配置也相同

自定義
自定義網橋 默認與brige網絡一樣

之前有一次公司某測試服務器上的規則全部失效,容器之間不能通信,於是重裝網橋
yum -y remove firewalld  >/dev/null 2>&1
echo "firewalld remove success"
yum -y install iptables-service > /dev/null 2>&1
echo "iptables install success"
yum install  bridge-utils > /dev/null 2>&1
echo "echo bridge-utils install success"
iptables -t nat -F
ifconfig docker0 down
brctl delbr docker0

默認的橋接模式其實就是弄明白兩個問題
1.容器如何與真機建立通信?
Countainer(eth0)->veth容器虛擬網卡->橋接網卡docker0(172.0.0.0/16)
docker0橋接到真機eth0上 到此解決了docker與真機的通信
2.外部請求如何到docker內部呢?
eth0 -> NAT ->docker0

容器網絡的訪問原理

Linux防火牆概述
Linux防火牆實際指的是Linux下的Netfilter/Iptables。
Linux內核集成的IP信息包過濾系統。
Netfilter/Iptables 信息包過濾系統可以當成一個整體,netfilter是內核的模塊實現,iptables是對上層操作工具。

Netfilter是Linux核心中的一個通用架構,工作於內核空間。

Netfilter支持一下方式對數據包進行分類:

源IP地址
目標IP地址
使用接口
使用協議
端口號
連接狀態
其提供了一系列的表(tables),每個表由若干個鏈(chains)組成,每條鏈可以由一條或若干條規則(rules)組成,其規則由一些信息包過濾表組成,這些表包含內核用來控制信息包過濾處理的規則集。

chain的本質是Netfilter定義的不同過濾點。總共定義了5個過濾點。INPUT,FORWARDING,OUTPUT,PREROUTING,POSTROUTIONG。

Table的本質是Netfilter定義的不同功能的劃分。

filter用於執行基本過濾。

nat是對數據IP進行修改。

mangle是對數據包進行高級修改。

不同的Table只能用於特定的Chain。

Iptables 是一個管理內核包過濾的工具,可以用來配置核心包過濾表格中的規則。運行於用戶空間。

1.1 Linux防火牆的應用
Linux防火牆在企業應用中非常有用,舉例如下:

中小企業與網吧裏有iptables作爲企業的NAT路由器,可以用來代替傳統路由器,而節約成本。
IDC機房一般沒有硬件防火牆,IDC機房的服務器可以用Linux防火牆代替硬件防火牆。
iptables可以結合squid作爲企業內部上網的透明代理。傳統代理需要在瀏覽器裏配置代理服務器信息,而iptables+squid的透明代理則可以把客戶端的請求重定向到代理服務器的端口。客戶端不要作任何設置,而感覺不到代理的存在。
將iptables作爲企業NAT路由器時,可以使用iptables的擴展模塊屏蔽P2P流量,還可以禁止非法網頁。
iptables可以用於外網IP向內網IP映射。
iptables可以輕鬆防止輕量級DOS攻擊,比如ping攻擊及SYN洪水攻擊。
綜述,Iptables有兩種應用模式:主機防火牆,NAT路由器。

參考:
http://www.cnblogs.com/shijiaqi1066/p/3812510.html

四表五鏈:
表: filter(過濾)

    nat(地址轉換)                
    mangle(拆包 改包 封裝)
    raw (數據包狀態跟蹤)

鏈(對應上表):
input output forword
prerouting postrouting outputing
input output prerouting postrouting output
prerouting output

docker能訪問到外部的原因:
iptables -t nat -A POSTROUTING -s 172.17.0.0/16 -j MASQUERADE
注意 MASQUERADE與snat的區別是可以動態的找到你的宿主機的網卡並且將請求轉發出去
同樣可以換一種寫法
iptables -t nat POSTROUTING -s 172.0.0.10/24 -j NAT --to 真機ip

容器橋接宿主機以及容器配置固定IP

1、容器默認網絡配置過程
先創建一個docker0的網橋,使用Veth pair創建一對虛擬網卡,一端放到新創建的容器中,並重命名eth0,另一端放到宿主機中,以veth+隨機7個字符串名字命名,並將這個網絡設備加入到docker0網橋中,網橋自動爲容器分配一個IP,並設置docker0的IP爲容器默認網關。同時在iptables添加SNAT轉換網橋段IP,以便容器訪問外網。
Veth par是用於不同network namespace間進行通信的方式,而network namespace是實現隔離網絡。

2、容器橋接宿主機網絡
關閉docker並設置橋接模式:
yum -y install bridge-utils
sudo service docker stop

關閉默認網橋

$ sudo ip link set dev docker0 down

刪除默認網橋

$ sudo brctl delbr docker0

創建橋接網卡:
$ sudo brctl addbr br0 #創建網橋
$ sudo vi /etc/network/interfaces #將原有宿主機IP配置到新創建的網橋上

auto eth0
iface eth0 inet manual
auto br0
iface br0 inet static

address 192.168.10.10   #宿主機IP
netmask 255.255.255.0
gateway 192.168.10.1
dns-nameservers 192.168.10.1

$ sudo /etc/init.d/networking restart
重啓網卡後,再通過ifconfig命令查看,多了br0網橋,並且IP地址也綁定在了上面。

修改docker橋接網橋,並重啓

sudo vi /etc/default/docker
DOCKER_OPTS="-b=br0"
sudo service docker restart
接下來啓動一個容器,先不配置網絡信息:
sudo docker run -itd --name=ubuntu_test --net=none ubuntu

不配置ip的原因是:容器啓動後自動隨機分配一個網橋段的IP,這個IP不管你宿主機網絡中是否已經分配,它都會根據自身的算法來分配IP,docker有自己的一套分配算法。
所以既然選擇橋接網絡,就要事先規劃好IP分配。

4、創建容器沒配置網絡,該怎麼配置呢?
pipework是一個LXC網絡管理工具,用shell寫的,有200多行代碼。可以給容器配置固定IP地址:
$ git clone https://github.com/jpetazzo/pipework.git
sudo cp pipework/pipework /usr/local/bin/
sudo pipework br0 ubuntu_test 192.168.18.29/[email protected]
Warning: arping not found; interface may not be immediately reachable
這一步是給配置容器網絡並連接網橋,@左邊是與宿主機同網段IP,右邊是網關。
提示arping命令沒發現,可以通過apt-get install arping來安裝。
sudo brctl show #查看虛擬網卡veth開頭的已加入網橋
sudo docker attach ubuntu_test

進入容器用ifconfig命令查看,IP信息已經配置上,通過ping百度及同網段IP是相通的,配置成功。

pipework工具怎麼實現配置的IP呢?
pipework是通過ip netns exec進入容器的net命名空間,來配置容器net命名空間的網絡參數。

博客地址:http://lizhenliang.blog.51cto.com

5、簡單講下怎麼SSH連接容器
根據上面的配置後,簡單配置下SSH服務即可實現SSH遠程登錄:

進入容器

$ sudo docker attach ID/NAME

安裝SSH

$ sudo apt-get update
$ sudo apt-get install openssh-server

修改SSH配置文件(/etc/ssh/sshd_config)

PermitRootLogin yes #運行root登錄
UsePAM no #不使用驗證模塊

啓動SSH

/etc/init.d/ssh restart

查看是否啓動成功

ps -ef |grep ssh
此時已經可以像連接虛擬機那樣SSH連接容器了!

在docker默認網絡模式情況下,由於容器是docker分配docker0網段的IP,這時又該怎麼SSH連接容器呢?
當創建新容器時有選項可以指定宿主機到容器端口,那就是-p選項。

例如:sudo docker run -itd --name=ubuntu_test -p 2222:22 ubuntu
2222是宿主機端口,22是容器內部ssh服務端口。這樣就可以通過"ssh -p 2222 root@宿主機IP"連接容器了。不但ssh服務可以這樣做,比如web、mysql等服務也同樣方式實現容器對外提供服務。
當使用-p時,docker實際是在iptables做了DNAT規則,實現端口轉發功能。可以使用iptables -t nat -vnL查看,出現最下面的一條記錄:

sudo iptables -t nat -A PREROUTING -d 192.168.18.231 -p tcp --dport 2222 -j DNAT --to 172.17.0.1:22

6、容器跨主機通信
由於docker自身還未支持跨主機容器通信,需要藉助docker網絡開源解決方案。這裏利用OpenVSwich即開放式虛擬交換機實現,簡稱OVS,OVS在雲計算領域應用廣泛,值得我們去學習使用。
什麼是OpenVSwich?
OpenVSwich是一種開源軟件,通過軟件的方式實現二層交換機功能,專門管理多租賃雲計算網絡環境,提供虛擬網絡中的訪問策略、網絡隔離、流量監控等。
既然是虛擬交換機,自然與傳統的物理交換機有着相同的特性,操作中可以按照理解物理交換機的方式去操作,有助於對虛擬交換機的認識。
實驗環境:
操作系統:ubuntu14.04_x64
宿主機1:192.168.18.16 容器網段:172.17.1.0/24
宿主機2:192.168.18.17 容器網段:172.17.2.0/24
開始創建網絡環境(兩臺宿主機做相同的操作,部分要適當修改,已註明):

安裝openvswitch

$ sudo apt-get install openvswitch-switch bridge-utils

添加網橋obr0(理解爲添加了一個交換機)

$ sudo ovs-vsctl add-br obr0

將gre0接口加入到網橋obr0, 遠程IP寫對端IP(創建一個GRE隧道並添加到網橋中)

$ sudo ovs-vsctl add-port obr0 gre0 -- set Interface gre0 type=gre options:remote_ip=192.168.18.17

查看ovs信息

$ sudo ovs-vsctl show

添加docker網橋

$ sudo brctl addbr kbr0

將obr0網橋加入kbr0網橋,並啓動

$ sudo brctl addif kbr0 obr0
$ sudo ip link set dev kbr0 up

查看網橋信息

$ sudo brctl show

添加docker網橋配置信息(18.17宿主機按照這種方式配置自己)

$ vi /etc/network/interfaces
auto eth0
iface eth0 inet static

address 192.168.18.16
netmask 255.255.255.0
gateway 192.168.18.1
dns-nameservers 192.168.18.1

auto kbr0
iface kbr0 inet static

address 172.17.1.1
netmask 255.255.255.0
gateway 172.17.1.0

刪除默認docker網橋

sudo ip link set dev docker0 down
sudo ip link delete dev docker0

關鍵一點,添加路由條目,否則無法通訊(同樣在18.17上面這樣添加路由,寫對端IP)

via從哪個網關出去,寫對端IP。dev由哪個設備出去

$ sudo ip route add 172.17.2.0/24 via 192.168.18.17 dev eth0

至此容器跨主機通信配置完成,兩邊各創建一個容器來驗證吧!

裏面涉及到一個GRE隧道,什麼是GRE隧道呢?
GRE即通用路由協議封裝,隧道技術是一種封裝技術,將網絡層協議(如IP)的數據報文進行封裝,使這些封裝的數據報文能夠在另一個網絡層協議中傳輸。可以看作是一個虛擬點到點連接,所以建立隧道時,要配置好隧道源地址和目的地址。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章