Docker網絡
I. Docer的通信方式
默認情況下,Docker使用網橋(brige)+ NAT的通信模型.
Docker啟動時會自動創建網橋Docker0,并配置ip 172.17.0.1/16
ifconfig docker0
docker0 Link encap:Ethernet HWaddr 02:42:e0:31:ac:10inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1RX packets:1846 errors:0 dropped:0 overruns:0 frame:0TX packets:5562 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0RX bytes:168242 (168.2 KB) TX bytes:23550976 (23.5 MB)
Docker容器內容及容器與宿主機通信方式(Brige方式)
當Docker啟動容器時,會創建一對veth虛擬網絡設備:
- 一個附加到網橋上;
- 一個加入容器的網張命名空間并被改名為eth0
Docker容器與外部網張通信(NAT方式)
1)容器訪問外網
Docker通過創建如下MASQUERADE規則進行外部網絡訪問:
iptables -t nat -A POSTROUTING -s 172.17.0.0/16 !-o docker0 -j MASQUERADE
規則說明:獎所有從容器(172.17.0.0/16)發往外網的包的源地址都改為Host(宿主機)的IP。
2)外網訪問容器
當容器提供的服務需要暴露給外部網絡里,Docker啟動容器里,會創建SNAT規則。eg,啟動一個apache容器:
docker run -d -p 80:80 apache
在上述命令背后其實會創建如下SNAT規則:
iptables -t nat -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
iptables -t nat -A DOCKER !-i docker0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 172.17.0.2:80
II. Docker的網絡配置
Docker中很多網絡相關的參數主是有:
- Docker進程本身的,影響所有docker容器;
- Docker容器相關的,只影響當前容器;
1. 網絡配置參數
1)Docker進程的網絡配置
相關參數如下:
-b, --bridge="" ;//指定Docker使用的網絡設備。默認下,Docker會創建docker0網橋設備,通過該參數可以指定Docker使用已存在的網橋設備--bip="" ;//指定網橋設備的docker0的IP和掩碼,使用標準的CIDR形式,如192.168.1.5/24--dns=[] ;//強制docker使用指定的DNS servers--dns-search=[] ;//強制docker使用指定的DNS search domains--icc=true ;//打開inter-container溝通--ip="0.0.0.0" ;//綁定容器端口時的默認IP--ip-forward=true ;//打開 net.ipv4.ip_forward--iptables=true; //打開docker的iptables rules增加--mtu=0; //設置容器的網絡MTU,如果沒有設置任何值則默認route MTU ,當默認路由不存在時,使用1500
Note:
--dns/--dns-search: 配置容器的DNS,改參數可以在啟動Docker進程時指定(成為所有容器的默認值),也可以在啟動容器(docker run)時指定(覆蓋默認值)。
2)容器的網絡配置
下面是docker run時的一些網絡配置參數:
--net="bridge" //用于指定容器使用的網絡通信方式;
它有如下四個值:
- bridge : Docker容器的默認通信方式;
- none : 容器沒有網絡棧,此時容器無法與外界通信;
- container:<name|id> : 使用其他容器(name或id)的網絡棧。實際上,Docker會將該容器加到指定的容器network namespace, 這是一種非常有用的方式。
- host : 表示容器使用Host的網絡,沒有自己獨立的網絡棧。實際上,在這種情況下,Docker不會給容器創建單獨的網絡名字空間(newwork namespace).由于容器可以完全訪問Host的網絡,所以此方式也是不安全的。
2. 配置DNS
一般來說每個容器的hostname和DNS配置信息是不同的,我們不可能為每個容器都構建一個鏡像,并在鏡像中指定這些信息。實際上,Docker在啟動容器時,會使用bind mount動態掛載/etc/hostname,/etc/hosts,/etc/resolv.conf幾個文件,覆蓋鏡像中原來的文件。通過如下命令我們可以在容器內看到這個信息:
docker exec -it {容器} /bin/bash
mount/dev/vda1 on /etc/resolv.conf type ext4 (rw,relatime,errors=remount-ro,data=ordered)
/dev/vda1 on /etc/hostname type ext4 (rw,relatime,errors=remount-ro,data=ordered)
/dev/vda1 on /etc/hosts type ext4 (rw,relatime,errors=remount-ro,data=ordered)
所以,我們可以通過命令行參數在啟動Doker時指定DNS
3. Docker網絡相關的一些參考
關于docker網絡的概念:理解Docker容器網絡之Linux Network Namespace
關于源地址和目地地址的轉換關系:iptables中DNAT、SNAT和MASQUERADE的理解
Docker相關的網絡詳解:Docker網絡詳解
iptables命令詳解:iptables命令詳解