Docker系列(8) Docker网络(3)-- 单机Docker网络配置
1. 默认网络当你安装了docker,自动创建了3个网络,可以使用docker network命令来查看dd@ubuntu04:~$ docker network lsNETWORK IDNAMEDRIVERSCOPE61848f3f9e62bridgebridge ...
1. 默认网络
当你安装了docker,自动创建了3个网络,可以使用docker network命令来查看
dd@ubuntu04:~$ docker network ls
NETWORK ID NAME DRIVER SCOPE
61848f3f9e62 bridge bridge local
6211ead1d40a host host local
47771891e708 none null local
1.1 bridge网络
根据上篇所述,默认情况下,新建的docker会连接到docker0这个网桥上
dd@ubuntu04:~$ ip addr show docker0
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:bc:71:fe:b6 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
dd@ubuntu04:~$ brctl show docker0
bridge name bridge id STP enabled interfaces
docker0 8000.0242bc71feb6 no
启动并运行一个容器
dd@ubuntu04:~$ docker run -itd --name dd-test01 ubuntu:18.04 /bin/bash
ce65c0e400e0a7f6b6f10b62d3359ea0ac59abbb6e4ba8f7c938d420b27e65bf
dd@ubuntu04:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ce65c0e400e0 ubuntu:18.04 "/bin/bash" 37 seconds ago Up 33 seconds dd-test01
进入容器
dd@ubuntu04:~$ docker exec -it dd-tes01 /bin/bash
查看ip 信息
root@ce65c0e400e0:/# ifconfig
报错:
bash: ifconfig: command not found
解决:
root@ce65c0e400e0:/# apt-get update
root@ce65c0e400e0:/# apt-get install net-tools
查看ip
root@ce65c0e400e0:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet)
RX packets 2008 bytes 18182532 (18.1 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1853 bytes 104451 (104.4 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
查看网关:
root@ce65c0e400e0:/# 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
可以看到test1容器已经获取了一个地址172.17.0.2,和主机的docker0接口地址在同一网络,并将主机的docker0接口地址设置为了网关。
在物理主机上,查看网桥docker0,可以看到已经多了一个接口
dd@ubuntu04:~$ brctl show docker0
bridge name bridge id STP enabled interfaces
docker0 8000.0242bc71feb6 no veth891c3fa
Docker 容器默认使用 bridge 模式的网络特点如下:
- 使用一个 linux bridge,默认为 docker0
- 使用 veth 对,一头在容器的网络 namespace 中,一头在 docker0 上
- 该模式下Docker Container不具有一个公有IP,因为宿主机的IP地址与vethpair的 IP地址不在同一个网段内
- Docker采用 NAT 方式,将容器内部的服务监听的端口与宿主机的某一个端口port进行“绑定”,使得宿主机以外的世界可以主动将网络报文发送至容器内部
- 外界访问容器内的服务时,需要访问宿主机的 IP 以及宿主机的端口 port
- NAT 模式由于是在三层网络上的实现手段,故肯定会影响网络的传输效率。
- 容器拥有独立、隔离的网络栈;让容器和宿主机以外的世界通过NAT建立通信
效果是这样的:
示意图如下:
在物理主机上查看iptables的nat表,可以看到在POSTROUTING链中做了地址伪装:MASQUERADE动作,这样容器就可以通过源地址转换NAT访问外部网络了。
dd@ubuntu04:~$ sudo iptables -t nat -vnL
Chain PREROUTING (policy ACCEPT 78 packets, 6004 bytes)
pkts bytes target prot opt in out source destination
4 1781 DOCKER all -- * * 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL
Chain INPUT (policy ACCEPT 44 packets, 3501 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 430 packets, 32478 bytes)
pkts bytes target prot opt in out source destination
0 0 DOCKER all -- * * 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT 430 packets, 32478 bytes)
pkts bytes target prot opt in out source destination
9 553 MASQUERADE all -- * !docker0 172.17.0.0/16 0.0.0.0/0
Chain DOCKER (2 references)
pkts bytes target prot opt in out source destination
0 0 RETURN all -- docker0 * 0.0.0.0/0 0.0.0.0/0
可以使用docker network inspect bridge命令来查看bridge网络情况:
dd@ubuntu04:~$ docker network inspect bridge
[
{
"Name": "bridge",
"Id": "61848f3f9e629985880ed98d0293d14b20169e31ef9ed25ffe165439c915042a",
"Created": "2020-05-07T10:15:11.014764859Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"ce65c0e400e0a7f6b6f10b62d3359ea0ac59abbb6e4ba8f7c938d420b27e65bf": {
"Name": "dd-test01",
"EndpointID": "14e910d3cc8fbae5820e2a5c1418bffe9d46434ba1688209113ca8323d8b5e3e",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
},
"Labels": {}
}
]
1.2 none网络模式
网络模式为 none,即不为Docker容器构造任何网络环境,不会为容器创建网络接口,一旦Docker容器采用了none网络模式,那么容器内部就只能使用loopback网络设备,不会再有其他的网络资源。Docker Container的none网络模式意味着不给该容器创建任何网络环境,容器只能使用127.0.0.1的本机网络。
启动一个容器,设为none网络
dd@ubuntu04:~$ docker run -itd --name dd-test02 --network none ubuntu:18.04 /bin/bash
7ae6efef02cfd25bd82c31c94322edfb34c007a741497c85f96e33cbe0cda1b1
进入容器,查看网络情况,发现由于none模式无法联网,导致ipconfig命令无法使用,正好可以复习下前面的命令,我们把bridge模式下的容器导出为image,再以此image创建none模式的container
dd@ubuntu04:~$ docker export ce65c0e400e0 > dd-ubuntu02.tar
dd@ubuntu04:~$ cat dd-ubuntu02.tar | docker import - dd/ubuntu:test
sha256:c332c9fe03b398405c72bc3214a86395853c20c969532074752487ac6d8cb232
dd@ubuntu04:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
dd/ubuntu test c332c9fe03b3 6 minutes ago 92.3MB
dd/centos 6.7 c6519f975a25 12 hours ago 191MB
dd/centos dev c6519f975a25 12 hours ago 191MB
dd/ubuntu v2 5b51178018cd 13 hours ago 137MB
dd/ubuntu v1 63cf4e1dfe43 13 hours ago 73.9MB
ubuntu latest 1d622ef86b13 13 days ago 73.9MB
ubuntu 18.04 c3c304cb4f22 13 days ago 64.2MB
httpd latest b2c2ab6dcf2e 2 weeks ago 166MB
ubuntu 14.04 6e4f1fe62ff1 4 months ago 197MB
centos 6.7 9f1de3c6ad53 13 months ago 191MB
ubuntu 15.10 9b9cb95443b5 3 years ago 137MB
training/webapp latest 6fae60ef3446 4 years ago 349MB
ubuntu 13.10 7f020f7bf345 5 years ago 185MB
dd@ubuntu04:~$ docker run -itd --network none --name dd-test03 dd/ubuntu:test /bin/bash
2d85c15b3bd8a52c2c9974f4020aa4f4c3ed01d8c5d841fa52b58b44d658d112
dd@ubuntu04:~$ docker exec -it dd-test03 /bin/bash
root@2d85c15b3bd8:/# ifconfig
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
root@2d85c15b3bd8:/# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
root@2d85c15b3bd8:/# cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
1.3 host网络模式
Host模式并没有为容器创建一个隔离的网络环境。而之所以称之为host模式,是因为该模式下的Docker 容器会和host宿主机共享同一个网络namespace,故Docker Container可以和宿主机一样,使用宿主机的eth0,实现和外界的通信。换言之,Docker Container的IP地址即为宿主机 eth0的IP地址。
其特点包括:
- 这种模式下的容器没有隔离的 network namespace
- 容器的 IP 地址同 Docker host 的 IP 地址
- 需要注意容器中服务的端口号不能与 Docker host 上已经使用的端口号相冲突
- host 模式能够和其它模式共存
示意图:
例如,我们在ubuntu04 的机器上用 host 模式启动一个含有 web 应用的Docker容器,监听 tcp 80 端口。当我们在容器中执行任何类似 ifconfig 命令查看网络环境时,看到的都是宿主机上的信息。而外界访问容器中的应用,则直接使用192.168.31.204:80 即可,不用任何 NAT 转换,就如直接跑在宿主机中一样。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。
启动容器前,查看物理主机的httpd进程
root@2d85c15b3bd8:/# pgrep httpd
root@2d85c15b3bd8:/#
启动一个容器
dd@ubuntu04:~$ docker run -itd --name dd-net-host --network host dd/ubuntu:test /bin/bash
a96b5b451de7d7df306ff4902f16afb8748fb4e0db808163ba07351088a945fc
进入容器,查看基本信息
dd@ubuntu04:~$ docker exec -it dd-nt-host /bin/bash
root@ubuntu04:/# ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:0a:fd:54:16 txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.31.204 netmask 255.255.255.0 broadcast 192.168.31.255
inet6 fe80::20c:29ff:fed0:84b3 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:d0:84:b3 txqueuelen 1000 (Ethernet)
RX packets 701 bytes 80060 (80.0 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 402 bytes 51006 (51.0 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 183 bytes 13887 (13.8 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 183 bytes 13887 (13.8 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
root@ubuntu04:/# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.31.2 0.0.0.0 UG 0 0 0 ens33
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
192.168.31.0 0.0.0.0 255.255.255.0 U 0 0 0 ens33
安装httpd服务,报错:
root@ubuntu04:/# apt-get install httpd
Reading package lists... Done
Building dependency tree
Reading state information... Done
Package httpd is a virtual package provided by:
nginx-light 1.14.0-0ubuntu1.7
nginx-full 1.14.0-0ubuntu1.7
nginx-extras 1.14.0-0ubuntu1.7
lighttpd 1.4.45-1ubuntu3.18.04
nginx-core 1.14.0-0ubuntu1.7
apache2 2.4.29-1ubuntu4.13
yaws 2.0.4+dfsg-2
webfs 1.21+ds1-12
tntnet 2.2.1-3build1
mini-httpd 1.23-1.2build1
micro-httpd 20051212-15.1
ebhttpd 1:1.0.dfsg.1-4.3build1
aolserver4-daemon 4.5.1-18.1
aolserver4-core 4.5.1-18.1
You should explicitly select one to install.
E: Package 'httpd' has no installation candidate
改装apache2
root@ubuntu04:/# apt-get install apache2
#启动apache2
root@ubuntu04:/# /etc/init.d/apache2 start
root@ubuntu04:/# echo "dd test docker host network" > /var/www/html/index.html
root@ubuntu04:/# exit
退出容器,查看apache2进程
dd@ubuntu04:~$ pgrep apache2
2807
2810
2811
访问主机的80端口,可以访问到容器中的网站服务:
1.4 container 模式
这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。
Container 网络模式是 Docker 中一种较为特别的网络的模式。这两个容器之间不存在网络隔离,而这两个容器又与宿主机以及除此之外其他的容器存在网络隔离。
注意:因为此时两个容器要共享一个network namespace,因此需要注意端口冲突情况,否则第二个容器将无法被启动。
示意图:
运行一个容器:查看容器的IP
dd@ubuntu04:~$ docker run -itd --name dd-nt-container01 dd/ubuntu:test /bin/bash
b7de375ff9f423768a70f8eebe9bb93525fb12d8d99f47850da765ebacc6d005
dd@ubuntu04:~$ docker exec -it dd-nt-container01 /bin/bash
root@b7de375ff9f4:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet)
RX packets 18 bytes 1452 (1.4 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
root@b7de375ff9f4:/# exit
启动另外一个容器,使用dd-nt-container01容器的网络
dd@ubuntu04:~$ docker run -itd --name dd-nt-container02 --network container:dd-nt-container01 dd/ubuntu:test /bin/bash
cfe50ae62a35d5b1d0b9b36ce6180690e024ccd68a1d03925f6c96a199191f8f
进入容器dd-nt-container02,查看网络情况,可以看到两个容器地址信息相同,是共享的
dd@ubuntu04:~$ docker exec -it dd-nt-container02 /bin/bash
root@b7de375ff9f4:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet)
RX packets 21 bytes 1662 (1.6 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
2. 用户定义网络(User-defined networks)
用户也可以自定义自己的网络。建议使用用户定义的桥接网络来控制容器之间彼此通信,并启用容器名称和IP地址的自动DNS解析,docker默认提供了用于创建这些网络的默认网络驱动程序,可以创建:
- bridge network
- overlay network
- MACVLAN network
- network plugin
- remote network
可以根据需要创建尽可能多的网络,并且可以在任何给定的时间将容器连接到0个或多个网络。此外,还可以在不重新启动容器的情况下连接和断开网络中的运行容器。当容器连接到多个网络时,它的外部连接是通过第一个非内部网络提供的。
2.2 新建网络(bridge networks)
下面先创建一个新的 Docker 网络。
dd@ubuntu04:~$ docker network create -d bridge dd-test-net
dd@ubuntu04:~$ docker network ls
NETWORK ID NAME DRIVER SCOPE
db7104d5ad7e bridge bridge local
74a4ffa1c72e dd-test-net bridge local
6211ead1d40a host host local
47771891e708 none null local
参数说明:
- -d:参数指定 Docker 网络类型,有 bridge、overlay。
- 其中 overlay 网络类型用于 Swarm mode,在本节中你可以忽略它。
2.3 连接容器
运行一个容器并连接到新建的 dd-test-net 网络:
dd@ubuntu04:~$ docker run -itd --name test1 --network dd-test-net ubuntu /bin/bash
再运行一个容器并加入到 dd-test-net 网络:
dd@ubuntu04:~$ docker run -itd --name test2 --network dd-test-net ubuntu /bin/bash
查看容器
dd@ubuntu04:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
133b92b9a360 ubuntu "/bin/bash" 2 minutes ago Up 2 minutes test2
ba1dc600a19b ubuntu "/bin/bash" 2 minutes ago Up 2 minutes test1
cfe50ae62a35 dd/ubuntu:test "/bin/bash" 13 minutes ago Up 13 minutes dd-nt-container02
b7de375ff9f4 dd/ubuntu:test "/bin/bash" 15 minutes ago Up 14 minutes dd-nt-container01
733e69a6a919 dd/ubuntu:test "/bin/bash" 37 minutes ago Up 37 minutes dd-nt-host
下面通过 ping 来证明 test1 容器和 test2 容器建立了互联关系。
如果 test1、test2 容器内中无 ping 命令,则在容器内执行以下命令安装 ping
test1:
dd@ubuntu04:~$ docker exec -it test1 /bin/bash
root@ba1dc600a19b:/# ping
bash: ping: command not found
root@ba1dc600a19b:/# apt-get update
root@ba1dc600a19b:/# apt install iputils-ping
root@ba1dc600a19b:/# ping test2
PING test2 (172.18.0.3) 56(84) bytes of data.
64 bytes from test2.dd-test-net (172.18.0.3): icmp_seq=1 ttl=64 time=0.196 ms
64 bytes from test2.dd-test-net (172.18.0.3): icmp_seq=2 ttl=64 time=0.094 ms
64 bytes from test2.dd-test-net (172.18.0.3): icmp_seq=3 ttl=64 time=0.055 ms
64 bytes from test2.dd-test-net (172.18.0.3): icmp_seq=4 ttl=64 time=0.067 ms
test2:
dd@ubuntu04:~$ docker exec -it test2 /bin/bash
root@ba1dc600a19b:/# ping
bash: ping: command not found
root@ba1dc600a19b:/# apt-get update
root@ba1dc600a19b:/# apt install iputils-ping
root@ba1dc600a19b:/# ping test1
PING test2 (172.18.0.3) 56(84) bytes of data.
64 bytes from test1.dd-test-net (172.18.0.2): icmp_seq=1 ttl=64 time=0.079 ms
64 bytes from test1.dd-test-net (172.18.0.2): icmp_seq=2 ttl=64 time=0.080 ms
64 bytes from test1.dd-test-net (172.18.0.2): icmp_seq=3 ttl=64 time=0.061 ms
64 bytes from test1.dd-test-net (172.18.0.2): icmp_seq=4 ttl=64 time=0.128 ms
这样,test1 容器和 test2 容器建立了互联关系。
查看网络情况:
dd@ubuntu04:~$ docker network inspect dd-test-net
[
{
"Name": "dd-test-net",
"Id": "74a4ffa1c72e8da7f19bf921a97f3c1ac8fd5c74dce3c386c67f21d68dce0470",
"Created": "2020-05-07T15:17:21.854079137Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"133b92b9a36053c7dd14003a2d1c2bf709b75ce7f01a46dba484f8118dcf5803": {
"Name": "test2",
"EndpointID": "743cc1fdbb4dd0edbcc5f8003bedc934c66cb563374373399f8b7ee5355b28f8",
"MacAddress": "02:42:ac:12:00:03",
"IPv4Address": "172.18.0.3/16",
"IPv6Address": ""
},
"ba1dc600a19b428d23bfc3031a454bdd6641fd1be2335d79e555a31bb956ff45": {
"Name": "test1",
"EndpointID": "71f41de3865893a3ea300490f2899d4ad6013bb99d38a12a9085234a243cd12b",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
如果有多个容器之间需要互相连接,推荐使用 Docker Compose,后面会介绍
需要注意创建的网络中的容器必须在同一个HOST主机上,网络中的每个容器都可以立即与网络中的其他容器通信。然而,网络本身将容器与外部网络隔离开来。
在用户定义的网桥网络中,不支持linking。可以在这个网络中公开和发布容器端口,也就是expose and publish
如果你想在单一主机上运行一个相对小的网络,使用桥接网络是有效果的。
然而你想创建一个大网络,可以通过overlay 网络来实现。
3. 外部访问容器
容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P 或 -p 参数来指定端口映射。
当使用–P(大写)标记时,Docker 会随机映射一个随机的端口到内部容器开放的网络端口。
注:-P使用时需要指定–expose选项或dockerfile中用expose指令容器要暴露的端口,指定需要对外提供服务的端口
从docker hub下载一个httpd镜像
dd@ubuntu04:~$ docker pull httpd
dd@ubuntu04:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
dd/ubuntu test c332c9fe03b3 2 hours ago 92.3MB
dd/centos 6.7 c6519f975a25 14 hours ago 191MB
dd/centos dev c6519f975a25 14 hours ago 191MB
dd/ubuntu v2 5b51178018cd 14 hours ago 137MB
dd/ubuntu v1 63cf4e1dfe43 15 hours ago 73.9MB
ubuntu latest 1d622ef86b13 13 days ago 73.9MB
ubuntu 18.04 c3c304cb4f22 13 days ago 64.2MB
httpd latest b2c2ab6dcf2e 2 weeks ago 166MB
ubuntu 14.04 6e4f1fe62ff1 4 months ago 197MB
centos 6.7 9f1de3c6ad53 13 months ago 191MB
ubuntu 15.10 9b9cb95443b5 3 years ago 137MB
training/webapp latest 6fae60ef3446 4 years ago 349MB
ubuntu 13.10 7f020f7bf345 5 years ago 185MB
3.1 -P
使用这个下载的镜像启动一个容器:
dd@ubuntu04:~$ docker run -d -P --name dd-web-test01 httpd
dd@ubuntu04:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d181fd5b896b httpd "httpd-foreground" 9 seconds ago Up 7 seconds 0.0.0.0:32768->80/tcp dd-web-test01
133b92b9a360 ubuntu "/bin/bash" 30 minutes ago Up 30 minutes test2
ba1dc600a19b ubuntu "/bin/bash" 30 minutes ago Up 30 minutes test1
cfe50ae62a35 dd/ubuntu:test "/bin/bash" 41 minutes ago Up 41 minutes dd-nt-container02
b7de375ff9f4 dd/ubuntu:test "/bin/bash" 42 minutes ago Up 42 minutes dd-nt-container01
733e69a6a919 dd/ubuntu:test "/bin/bash" About an hour ago Up About an hour dd-nt-host
可以看到容器的80端口被随机映射到主机的32768端口
访问主机IP地址的32768端口,就可以访问到容器的httpd服务
3.2 -p
-p(小写)则可以指定要映射的端口,并且,在一个指定端口上只可以绑定一个容器。支持的格式有ip:hostPort:containerPort | ip::containerPort |
hostPort:containerPort
3.2.1 hostPort:containerPort
注意:
- 容器有自己的内部网络和 ip 地址(使用 docker inspect 可以获取所有的变量。)
- -p 标记可以多次使用来绑定多个端口
dd@ubuntu04:~$ docker run -d -p 8000:80 --name dd-web-test02 httpd
18b2ff2e1448aa2af0868fb3671f2ea0247229b1f74b5aaecd42f3eaa3dcf31c
dd@ubuntu04:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
18b2ff2e1448 httpd "httpd-foreground" 11 seconds ago Up 10 seconds 0.0.0.0:8000->80/tcp dd-web-test02
d181fd5b896b httpd "httpd-foreground" 6 minutes ago Up 6 minutes 0.0.0.0:32768->80/tcp dd-web-test01
133b92b9a360 ubuntu "/bin/bash" 36 minutes ago Up 36 minutes test2
ba1dc600a19b ubuntu "/bin/bash" 37 minutes ago Up 37 minutes test1
cfe50ae62a35 dd/ubuntu:test "/bin/bash" 47 minutes ago Up 47 minutes dd-nt-container02
b7de375ff9f4 dd/ubuntu:test "/bin/bash" 49 minutes ago Up 49 minutes dd-nt-container01
733e69a6a919 dd/ubuntu:test "/bin/bash" About an hour ago Up About an hour dd-nt-host
可以看到主机的8000端口已经和容器dd-web-test002的80端口做了映射
访问主机的8000端口
3.2.2 ip:hostPort:containerPort
映射到指定地址的指定端口
可以使用 ip:hostPort:containerPort 格式,指定映射使用一个特定地址,比如宿主机网卡
配置的一个地址192.168.31.204
dd@ubuntu04:~$ docker run -d -p 192.168.31.204:18000:80 --name dd-web-test03 httpd
a6f4f1fcf8e535c4c6c6150a44282ff6c3913f42fcaaf117dc56e4c5c2dbdb58
dd@ubuntu04:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a6f4f1fcf8e5 httpd "httpd-foreground" 39 seconds ago Up 38 seconds 192.168.31.204:18000->80/tcp dd-web-test03
18b2ff2e1448 httpd "httpd-foreground" 7 minutes ago Up 7 minutes 0.0.0.0:8000->80/tcp dd-web-test02
d181fd5b896b httpd "httpd-foreground" 13 minutes ago Up 13 minutes 0.0.0.0:32768->80/tcp dd-web-test01
133b92b9a360 ubuntu "/bin/bash" 43 minutes ago Up 43 minutes test2
ba1dc600a19b ubuntu "/bin/bash" 44 minutes ago Up 44 minutes test1
cfe50ae62a35 dd/ubuntu:test "/bin/bash" 54 minutes ago Up 54 minutes dd-nt-container02
b7de375ff9f4 dd/ubuntu:test "/bin/bash" 56 minutes ago Up 56 minutes dd-nt-container01
733e69a6a919 dd/ubuntu:test "/bin/bash" About an hour ago Up About an hour dd-nt-host
3.2.3 ip::containerPort
使用 ip::containerPort 绑定192.168.31.204的任意端口到容器的80端口,本地主机会自动分配一个口。这里就不再掩饰
注:还可以使用 udp 标记来指定 udp 端口
dd@ubuntu04:~$ docker run -d -p 192.168.31.204::80/udp --name dd-web-test04 httpd
df4d8a3e3ac16d4e5474fe110fe340ec2edc4f0d8dd997404ed81181dc326a70
dd@ubuntu04:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
df4d8a3e3ac1 httpd "httpd-foreground" 7 seconds ago Up 6 seconds 80/tcp, 192.168.31.204:32768->80/udp dd-web-test04
a6f4f1fcf8e5 httpd "httpd-foreground" 3 minutes ago Up 3 minutes 192.168.31.204:18000->80/tcp dd-web-test03
18b2ff2e1448 httpd "httpd-foreground" 10 minutes ago Up 10 minutes 0.0.0.0:8000->80/tcp dd-web-test02
d181fd5b896b httpd "httpd-foreground" 16 minutes ago Up 16 minutes 0.0.0.0:32768->80/tcp dd-web-test01
133b92b9a360 ubuntu "/bin/bash" 46 minutes ago Up 46 minutes test2
ba1dc600a19b ubuntu "/bin/bash" 47 minutes ago Up 47 minutes test1
cfe50ae62a35 dd/ubuntu:test "/bin/bash" 57 minutes ago Up 57 minutes dd-nt-container02
b7de375ff9f4 dd/ubuntu:test "/bin/bash" 59 minutes ago Up 59 minutes dd-nt-container01
733e69a6a919 dd/ubuntu:test "/bin/bash" About an hour ago Up About an hour dd-nt-host
查看映射端口配置
使用 docker port 来查看当前映射的端口配置,也可以查看到绑定的地址
dd@ubuntu04:~$ docker port dd-web-test04
80/udp -> 192.168.31.204:32768
3.3 端口映射与iptables
docker端口映射实质上是在iptables 的nat表中添加了DNAT规则
dd@ubuntu04:~$ sudo iptables -t nat -nvL
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
27 1693 DOCKER all -- * * 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 6 packets, 441 bytes)
pkts bytes target prot opt in out source destination
0 0 DOCKER all -- * * 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT 6 packets, 441 bytes)
pkts bytes target prot opt in out source destination
14 866 MASQUERADE all -- * !br-74a4ffa1c72e 172.18.0.0/16 0.0.0.0/0
0 0 MASQUERADE all -- * !docker0 172.17.0.0/16 0.0.0.0/0
0 0 MASQUERADE tcp -- * * 172.17.0.3 172.17.0.3 tcp dpt:80
0 0 MASQUERADE tcp -- * * 172.17.0.4 172.17.0.4 tcp dpt:80
0 0 MASQUERADE tcp -- * * 172.17.0.5 172.17.0.5 tcp dpt:80
0 0 MASQUERADE udp -- * * 172.17.0.6 172.17.0.6 udp dpt:80
Chain DOCKER (2 references)
pkts bytes target prot opt in out source destination
0 0 RETURN all -- br-74a4ffa1c72e * 0.0.0.0/0 0.0.0.0/0
0 0 RETURN all -- docker0 * 0.0.0.0/0 0.0.0.0/0
4 240 DNAT tcp -- !docker0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:32768 to:172.17.0.3:80
2 120 DNAT tcp -- !docker0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:8000 to:172.17.0.4:80
0 0 DNAT tcp -- !docker0 * 0.0.0.0/0 192.168.31.204 tcp dpt:18000 to:172.17.0.5:80
0 0 DNAT udp -- !docker0 * 0.0.0.0/0 192.168.31.204 udp dpt:32768 to:172.17.0.6:80
4. 参考文献
[1] docker 网络配置
[2] Docker系列之七:Docker网络
[3] Docker基础 :网络配置详解
[4] Docker 学习 | 第六篇:容器网络配置
[5] Docker的网络配置
[6] 使用 Docker 容器网络
[7] docker 之网络配置
[8] Docker网络详解
[9] docker网络模型之—Container模式
[10] Ubuntu下apache2启动、停止、重启、配置
[11] Ubuntu16.04安装httpd
[12] Ubuntu下解决ifconfig command not found的办法
更多推荐
所有评论(0)