默認情況下,容器使用的ip是172.17.0.0/16網段的,外界的用戶只能訪問宿主機的192.168.32.0/24網段,無法訪問172.17.0.0/16網段。我們運行容器的目的:是希望運行在容器中的服務,能夠被外界訪問,這里就涉及到了外網192.168.32.0/24到容器內網172.17.0.0/16網段的轉換,所以需要做端口映射。
二、docker運行容器端口映射的方法
指定映射(docker 自動添加一條iptables規則實現端口映射) -p hostPort:containerPort -p ip:hostPort:containerPort -p ip::containerPort(隨機端口) -p hostPort:containerPort:udp -p 81:80 -p 443:443 可以指定多個-p 隨機映射 docker run -P (隨機端口) iptables [root@inode3 ~]# iptables -t nat -L -n Chain PREROUTING (policy ACCEPT) target prot opt source destination DOCKER all -- 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL Chain INPUT (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination DOCKER all -- 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCAL Chain POSTROUTING (policy ACCEPT) target prot opt source destination MASQUERADE all -- 172.17.0.0/16 0.0.0.0/0 MASQUERADE tcp -- 172.17.0.2 172.17.0.2 tcp dpt:80 Chain DOCKER (2 references) target prot opt source destination RETURN all -- 0.0.0.0/0 0.0.0.0/0 DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 to:172.17.0.2:80 #容器172.17.0.2的tcp80端口已經映射到了外網的80端口上
1、容器網絡配置命令
docker run --name 運行的容器名稱 --net=網絡參數選項 -p 容器端口映射 鏡像名稱:鏡像版本
--net=網絡參數選項
None:不為容器配置任何網絡功能,--net=none Container:與另一個運行中的容器共享Network Namespace,--net=container:containerID Host:與主機共享Network Namespace,--net=host Bridge:Docker設計的NAT網絡模型
docker網絡查看命令
[root@inode4 ~]#docker network ls NETWORK ID NAME DRIVER SCOPE a736b9bf0850 bridge bridge local db0ed8b2be23 host host local 0339ee737df3 mac1 macvlan local 90c917be552d none null local
docker容器的網絡通信原理:
1、 當Docker進程啟動時,會在主機上創建一個名為docker0的虛擬網橋,此主機上啟動的Docker容器會連接到這個虛擬網橋上,所以有默認地址172.17.0.0/16的地址。虛擬網橋的工作方式和物理交換機類似,這樣主機上的所有容器就通過交換機連在了一個二層網絡中。
[root@inode4 ~]# ifconfig docker0 docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255 inet6 fe80::42:8cff:fe57:ebf8 prefixlen 64 scopeid 0x20<link> ether 02:42:8c:57:eb:f8 txqueuelen 0 (Ethernet) RX packets 194130 bytes 20622371 (19.6 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 250033 bytes 780264041 (744.1 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
2、 從docker0子網中分配一個IP給容器使用,並設置docker0的IP地址為容器的默認網關。在主機上創建一對虛擬網卡veth pair設備,Docker將veth pair設備的一端放在新創建的容器中,並命名為eth0(容器的網卡),另一端放在主機中,以vethxxx這樣類似的名字命名,並將這個網絡設備加入到docker0網橋中。可以通過brctl show命令查看。
yum install -y bridge-utils-1.5-9.el7.x86_64 [root@inode4 ~]# brctl show bridge name bridge id STP enabled interfaces docker0 8000.02428c57ebf8 no veth16bb7cf #宿主機中docker0的網卡 vethccb0469 #容器的網卡(在容器中eth0)
bridge模式是docker的默認網絡模式,不寫--net參數,就是bridge模式。使用docker run -p時,docker實際是在iptables做了DNAT規則,實現端口轉發功能。可以使用iptables -t nat -vnL查看。
[root@inode3 ~]# iptables -t nat -L -n Chain PREROUTING (policy ACCEPT) target prot opt source destination DOCKER all -- 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL Chain INPUT (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination DOCKER all -- 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCAL Chain POSTROUTING (policy ACCEPT) target prot opt source destination MASQUERADE all -- 172.17.0.0/16 0.0.0.0/0 MASQUERADE tcp -- 172.17.0.2 172.17.0.2 tcp dpt:80 Chain DOCKER (2 references) target prot opt source destination RETURN all -- 0.0.0.0/0 0.0.0.0/0 DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 to:172.17.0.2:80 #容器172.17.0.2的tcp80端口已經映射到了外網的80端口上
docker bridge原理圖
bridge案例
[root@inode3 ~]# docker run --net=bridge -it centos:6.9 /bin/bash [root@b796f4521c28 /]# ifconfig eth0 eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:03 inet addr:172.17.0.3 Bcast:172.17.255.255 Mask:255.255.0.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:6 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:508 (508.0 b) TX bytes:0 (0.0 b) [root@b796f4521c28 /]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 172.17.0.1 0.0.0.0 UG 0 0 0 eth0 172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
如果啟動容器的時候使用host模式,那么這個容器將不會獲得一個獨立的Network Namespace,而是和宿主機共用一個Network Namespace。容器將不會虛擬出自己的網卡,配置自己的IP等,而是使用宿主機的IP和端口。但是,容器的其他方面,如文件系統、進程列表等還是和宿主機隔離的。
docker host原理圖
host案例
[root@inode3 ~]# docker run -it --net=host centos:6.9 /bin/bash [root@inode3 /]# ifconfig eth0 eth0 Link encap:Ethernet HWaddr 00:0C:29:E2:7B:77 inet addr:192.168.32.103 Bcast:192.168.32.255 Mask:255.255.255.0 inet6 addr: fe80::dceb:89ad:3d37:bebe/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:603672 errors:361 dropped:444 overruns:0 frame:0 TX packets:245020 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:795145514 (758.3 MiB) TX bytes:20746259 (19.7 MiB)
發現ip與宿主機的ip一樣
第三種模式:Container 網絡模式
這個模式指定新創建的容器和已經存在的一個容器共享一個 Network Namespace,而不是和宿主機共享。新創建的容器不會創建自己的網卡,配置自己的 IP,而是和一個指定的容器共享 IP、端口范圍等。同樣,兩個容器除了網絡方面,其他的如文件系統、進程列表等還是隔離的。兩個容器的進程可以通過 lo 網卡設備通信。
docker container原理圖
命令格式
docker run --name 運行容器名稱 -d -p 容器的端口影身 --network container:共享網絡的容器名 鏡像:鏡像版本
container案例
現有運行容器web1
[root@inode3 ~]# docker inspect web1 |grep -i "ipaddress" "SecondaryIPAddresses": null, "IPAddress": "172.17.0.2", "IPAddress": "172.17.0.2",
[root@inode3 ~]# docker run -it --name centos6.9 --network container:web1 centos:6.9 [root@7c5d1590be34 /]# ifconfig eth0 eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02 inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:17 errors:0 dropped:0 overruns:0 frame:0 TX packets:7 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:1280 (1.2 KiB) TX bytes:1272 (1.2 KiB)
[root@7c5d1590be34 tmp]# touch ywx.log [root@7c5d1590be34 tmp]# ls anaconda-post.log yum.log ywx.log
第四種模式:none
使用none模式,Docker容器擁有自己的Network Namespace,但是,並不為Docker容器進行任何網絡配置。也就是說,這個Docker容器沒有網卡、IP、路由等信息,只有lo 網絡接口。需要我們自己為Docker容器添加網卡、配置IP等。
不參與網絡通信,運行於此類容器中的進程僅能訪問本地回環接口;僅適用於進程無須網絡通信的場景中,例如:備份、進程診斷及各種離線任務等。
docker none原理圖
[root@inode3 ~]# docker run -it --name centos6.9 --network none centos:6.9 /bin/bash [root@9703a325d77f /]# ifconfig eth0 eth0: error fetching interface information: Device not found [root@9703a325d77f /]# ifconfig lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)