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 docker03: 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:ffinet 172.17.0.1/16 brd 172.17.255.255 scope global docker0valid_lft forever preferred_lft forever
dd@ubuntu04:~$ brctl show docker0bridge 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 1500inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255ether 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 0TX packets 1853  bytes 104451 (104.4 KB)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536inet 127.0.0.1  netmask 255.0.0.0loop  txqueuelen 1000  (Local Loopback)RX packets 0  bytes 0 (0.0 B)RX errors 0  dropped 0  overruns 0  frame 0TX 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 LOCALChain 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 LOCALChain 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         185MBdd@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:/# ifconfiglo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536inet 127.0.0.1  netmask 255.0.0.0loop  txqueuelen 1000  (Local Loopback)RX packets 0  bytes 0 (0.0 B)RX errors 0  dropped 0  overruns 0  frame 0TX packets 0  bytes 0 (0.0 B)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0root@2d85c15b3bd8:/# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Ifaceroot@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 1500inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255ether 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 0TX packets 0  bytes 0 (0.0 B)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500inet 192.168.31.204  netmask 255.255.255.0  broadcast 192.168.31.255inet6 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 0TX packets 402  bytes 51006 (51.0 KB)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536inet 127.0.0.1  netmask 255.0.0.0inet6 ::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 0TX 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.7nginx-full 1.14.0-0ubuntu1.7nginx-extras 1.14.0-0ubuntu1.7lighttpd 1.4.45-1ubuntu3.18.04nginx-core 1.14.0-0ubuntu1.7apache2 2.4.29-1ubuntu4.13yaws 2.0.4+dfsg-2webfs 1.21+ds1-12tntnet 2.2.1-3build1mini-httpd 1.23-1.2build1micro-httpd 20051212-15.1ebhttpd 1:1.0.dfsg.1-4.3build1aolserver4-daemon 4.5.1-18.1aolserver4-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
b7de375ff9f423768a70f8eebe9bb93525fb12d8d99f47850da765ebacc6d005dd@ubuntu04:~$ docker exec -it dd-nt-container01 /bin/bash
root@b7de375ff9f4:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255ether 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 0TX packets 0  bytes 0 (0.0 B)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536inet 127.0.0.1  netmask 255.0.0.0loop  txqueuelen 1000  (Local Loopback)RX packets 0  bytes 0 (0.0 B)RX errors 0  dropped 0  overruns 0  frame 0TX packets 0  bytes 0 (0.0 B)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0root@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 1500inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255ether 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 0TX packets 0  bytes 0 (0.0 B)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536inet 127.0.0.1  netmask 255.0.0.0loop  txqueuelen 1000  (Local Loopback)RX packets 0  bytes 0 (0.0 B)RX errors 0  dropped 0  overruns 0  frame 0TX 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 LOCALChain 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 LOCALChain 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:800     0 MASQUERADE  tcp  --  *      *       172.17.0.4           172.17.0.4           tcp dpt:800     0 MASQUERADE  tcp  --  *      *       172.17.0.5           172.17.0.5           tcp dpt:800     0 MASQUERADE  udp  --  *      *       172.17.0.6           172.17.0.6           udp dpt:80Chain 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:802   120 DNAT       tcp  --  !docker0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:8000 to:172.17.0.4:800     0 DNAT       tcp  --  !docker0 *       0.0.0.0/0            192.168.31.204       tcp dpt:18000 to:172.17.0.5:800     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的办法

Docker系列(8) Docker网络(3)-- 单机Docker网络配置相关推荐

  1. Docker系列(二十四)——Docker实例六Docker安装Redis实例

    < Docker实例三Docker安装Redis实例 > 前言 在前面一篇文章种,完成了 < Docker安装MongoDB实例 >,本篇将继续镜像安装教程,并完成Docker ...

  2. docker系列之在win7上安装docker

    当VS Code上出现sql server连接成功的提示,我像是完成了一件大事一样. 前一阵,她让我装个sql server玩玩,我心想,这还不是小意思么,恰好那会我又在看docker,docker里 ...

  3. Docker系列之八:在Dockerfile中使用多段构建Muti-stage build

    系列链接 Docker系列之一:Docker介绍及在Ubuntu上安装 Docker系列之二:Docker 入门 Docker系列之三:使用Docker镜像和仓库 Docker系列之四:Dockerf ...

  4. Docker系列之三:使用Docker镜像和仓库

    系列链接 Docker系列之一:Docker介绍及在Ubuntu上安装 Docker系列之二:Docker 入门 Docker系列之三:使用Docker镜像和仓库 Docker系列之四:Dockerf ...

  5. Docker系列之五:Volume 卷的使用——以Redis为例

    系列链接 Docker系列之一:Docker介绍及在Ubuntu上安装 Docker系列之二:Docker 入门 Docker系列之三:使用Docker镜像和仓库 Docker系列之四:Dockerf ...

  6. docker 获取宿主机ip_Docker基础修炼6——网络初探及单机容器间通信

    如果觉得文章有帮助,欢迎点击头像关注我获取更多原创文章,同时也欢迎转发. 同时也可以在我的历史文章中找到Linux操作系统相关的服务器运维管理入门系列文章,欢迎交流. 前文演示docker容器内部数据 ...

  7. Docker系列文-----Docker的网络类型(4)

    Docker系列文-----Docker的网络类型(4) Docker里的常见文件及作用 Docker 内部的网络类型 1.桥接模式(默认): 2.host模式: 3.container模式 4.no ...

  8. Docker系列教程15-Docker容器网络

    原文:http://www.itmuch.com/docker/15-docker-network/ 本文是篇翻译.原文:https://docs.docker.com/engine/userguid ...

  9. 【Docker系列】Docker的网络

    问题 容器为什么能获取到IP地址? 为什么宿主机可有ping通容器的IP? 为什么容器之间的IP是互通的? 为什么容器能ping通外网? 容器的端口转发是怎么回事? Docker Bridge 网络 ...

  10. 小白都能懂的 玩转docker系列之 Docker网络详解(超详细)

    首先移掉之前所有的容器: [root@xiaoxiao tomcat]# docker rm $(docker ps -aq) fcfddcab1789 [root@xiaoxiao tomcat]# ...

最新文章

  1. java redis缓存理解_Java项目中使用Redis缓存案例
  2. GPS-nmealib学习
  3. tableau地图城市数据_优阅达“优分享” | Tableau 2020.4 “地图标记层” 的多种妙用...
  4. boost::mpl模块实现deque相关的测试程序
  5. webservice gsoap 小记
  6. ijcai statistics
  7. 过年了,是不是应该写点代码祝福别人
  8. 公众号开发 单独 给某个用户 推送消息_韩国5G用户6月底已达134万 较5月底增加近70%...
  9. java基础知识系列---垃圾收集
  10. gettid()和pthread_self()的区别
  11. 国产GPGPU如何赶超国外?这3条路最有希望
  12. 书生中学计算机应用自费,浙江省台州市书生中学2016-2017学年高二上学期期中考试信息试题 Word版含答案.doc...
  13. 详解LCD12864显示屏的使用(并行控制)
  14. 网易游戏(雷火)一、二、三交叉面
  15. parse_url() vul
  16. 基于MATLAB GUI的指纹识别系统
  17. vue组件通信1:父传子(props)
  18. 给公司取名的一些原则
  19. 61二次型—— 化二次型为标准形、矩阵的合同变换求二次型的标准形
  20. 微软 奥尔良 游戏服务器,去了新奥尔良,才知道是一个城市,别只知道奥尔良烤翅...

热门文章

  1. 阿里云商标注册价格和费用
  2. 公开说说别人看不到_空间设置了权限说说所有人可见
  3. Excel 如何让单元格内容不完全显示
  4. 量子机器学习HHL算法总结图文
  5. 每日工作记录——状态机的编码选择
  6. ios 销毁当前页面重新开启_iOS - 切换rootViewController时,销毁之前的控制器
  7. ESD笔记(二)_ESD测试
  8. html如何转换成中文,html页面中如何将编码转换成中文的示例代码
  9. 排列怎么用计算机计算公式,数学排列组合公式计算器
  10. 小白黑苹果安装N卡的方法和安装驱动后开机黑屏的解决方法