Iptables
容器所有到外部網路的連接,來源地址都會被NAT轉址成宿主機的IP,而其中的手腳就是來自於iptables
。
iptables的NAT Table
,透過此表來實行主機上的路由轉送的動作,重申在linux中IP並非專屬任一實體網卡,而是屬於linux內可被轉址,平時所用的軟體路由是基於linux內核iptables實現,使用NAT前需開啟轉發才能產生作用。
透過以下iptables程序鏈的封包過濾圖
並非每種表格都有所有鏈結,各功能內建鏈結對照如下:
一般如果不啟動NAT功能,只要使用filter table的INPUT,OUTPUT
鏈已足夠。
如需啟用NAT,除過濾功能本身外,最重要就是FORWARD轉送
功能,並用位址轉換表格的POSTROUTING,將封由內網私有 IP偽裝(MASQUERADE)
成NAT對外IP,才能連上Internet。
iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DOCKER all -- 0.0.0.0/0 0.0.0.0/0
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destinationMASQUERADE
all -- 172.17.0.0/16 0.0.0.0/0
Chain DOCKER (2 references)
target prot opt source destination
RETURN all -- 0.0.0.0/0 0.0.0.0/0
隨機執行一個CentOS容器並進入Bash對外存取解析均沒有問題
現在我們做個簡單實驗,透過ip addr檢視目前宿主機上面的實體網路介面僅有一組eth0
因為這台宿主機是在Azure上的一台VM,我們新增一張網卡
新增網卡需要關機,故新增網卡後開啟再檢視已經看到多一張eth1
透過以下簡單的指令把eth1新增到iptables上作為後續透過此NAT出去也能走eth1
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
docker0 Bridge
Docker服務預設會建立docker0
橋接器,透過核心層串接連通其實體與虛擬網路介面,故所有搭建的容器和宿主機都放到同一個實體網路上。
Docker透過docker0
介面讓主機和容器間透過橋接器相互連通外,同時還涵蓋MTU或宿主機網路路由上支援的預設。上述這些值都可以在服務啟動時進行設定。
PS:brctl如果沒有此命令模組,以Debian、Ubuntu為例,可透過sudo apt-get install bridge-utils
來安裝。
如果想要調整橋接器和連接埠間的連接可以透過修改DOCKER_OPTS
。使用者可以使用brctl show
來查看橋接器和連接埠連接訊息。DOCKER_OPTS設置不生效問題
隨著執行一個個容器啟動後,在docker0清單上也清楚看到容器綁定的虛擬橋接網路
每建立一個容器時,Docker都會從可用IP網段中分配一個未使用的IP給容器的eth0連接埠。使用宿主機上docker0介面的IP作為全部容器的Default Gateway
。
Custom Bridge
除了預設docker0外,用戶其實也可以指定橋接器來連接其他容器。在執行Docker服務時使用 -b BRIDGE或--bridge=BRIDGE來指定使用的橋接器。如服務已執行則要先服務停止並移除舊有橋接。
前置作業
service docker stop
ip link set dev docker0 down
brctl delbr docker0
建立一個橋接器bridge0
brctl addbr bridge0
ip addr add 10.100.1.0/24 dev bridge0
ip link set dev bridge0 up
查看確認橋接器建立並啟動
ip addr show bridge0
顯示狀態範例
bridge0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state UP group default
link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
inet 10.100.1.0/24 scope global bridge0
valid_lft forever preferred_lft forever
設定Docker服務,把建立的橋接器設為Default
$ echo 'DOCKER_OPTS="-b=bridge0"' >> /etc/default/docker
$ sudo service docker start
啟動Docker服務後,新建一個容器,應該就可以看到已經橋接到bridge0上了
用brctl show
查看橋接資訊外,容器中可以使用ip addr
和ip route
命令查看IP和路由訊息。