Networking Basics
单主机 Bridge Driver 网桥驱动
当创建一个
bridge
的网络驱动时这个模型是默认的,这个驱动创建了一个私有的网络环境,并在主机提供了一个外部端口以供外部使用。
#创建一个我们的应用用户定义的网桥网络
$ docker network create -d bridge catnet
#使用自定义的网络创建一个redis容器
$ docker run -d --net catnet --name cat-db redis
#Instantiate the web frontend on the catnet network and configure it to connect to a container named `cat-db`
# 实例这个web容器,使用catnet这个网络并且配置它连接到cat-db的容器实例。
$ docker run -d --net catnet -p 8000:5000 -e 'DB=cat-db' -e 'ROLE=cat' chrch/web
当一个IP地址不指定时,端口会被映射到所有网卡上,0.0.0.0:8000,可以通过指定一个IP来只开放一个端口,
-p 127.0.0.1:8000:5000
,更多内容查看 Docker doc.
两个容器通过同一个网桥进行网络通信,上面的web
这个容器访问redis
时通过cat-db
这个域名进行访问,Docker
引擎内部有DNS
能将容器域名解析为可以访问的容器IP
,因此,在Bridge
模式下,多个容器都是可以通过容器名称进行访问。
可以通过docker network inspect catnet
查看这个网络下所以容器。
# 如下可以看出有两个容器是使用了这同一个网络。
$ docker network inspect catnet
[
{
"Name": "catnet",
"Id": "81e45d3e3bf4f989abe87c42c8db63273f9bf30c1f5a593bae4667d5f0e33145",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.19.0.0/16",
"Gateway": "172.19.0.1/16"
}
]
},
"Internal": false,
"Attachable": false,
"Containers": {
"2a23faa18fb33b5d07eb4e0affb5da36449a78eeb196c944a5af3aaffe1ada37": {
"Name": "backstabbing_pike",
"EndpointID": "9039dae3218c47739ae327a30c9d9b219159deb1c0a6274c6d994d37baf2f7e3",
"MacAddress": "02:42:ac:13:00:03",
"IPv4Address": "172.19.0.3/16",
"IPv6Address": ""
},
"dbf7f59187801e1bcd2b0a7d4731ca5f0a95236dbc4b4157af01697f295d4528": {
"Name": "cat-db",
"EndpointID": "7f7c51a0468acd849fd575adeadbcb5310c5987195555620d60ee3ffad37c680",
"MacAddress": "02:42:ac:13:00:02",
"IPv4Address": "172.19.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
多主机 Bridge Driver 网桥模式
在多台宿主机中使用Bridge
网络模式,redis
部署在host-A
中,并且需要映射一个外部IP,供web
去调用,web
部署在host-B
中,要调用db
时,要通过DB=host-A:6379
指定主机A的host
和redis
暴露的端口进行连接。
# 每个docker中都有一个默认的Bridge网络模式
host-A $ docker run -d -p 6379:6379 redis
host-B $ docker run -d -p 8000:5000 -e 'DB=host-A:6379' -e 'ROLE=cat' --name web chrch/web
主机B通过本机Host
来解析主机A的IP地址已进行访问。通常不建议这样硬编码的使用服务地址。
Overlay Driver
overlay
网络模式提供了服务发现和自动负载均衡的功能,但是前提是要把多主机部署为swarm
集群模式。
在lead
上面查看swarm
的节点数量。
$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
a8dwuh6gy5898z3yeuvxaetjo host-B Ready Active
elgt0bfuikjrntv3c33hr0752 * host-A Ready Active Leader
创建一个自定义的overlay
网络。在一个overlay
网络中开放的TCP
和UDP
端口都是开放。
$ docker network create -d overlay --subnet 192.0.0.0/24 --gateway 192.0.0.1 dognet
$ docker service create --network dognet --name dog-db redis
$ docker service create --network dognet -p 8000:5000 -e 'DB=dog-db' -e 'ROLE=dog' --name dog-web chrch/web
上图讲解了上面的命令中的部署图,首先创建了一个叫dognet
的overlay
网络,然后创建一个service
,使用dognet
这个创建好的网络,并且不开放任何可访问端口,命令为dog-db
;然后创建另一个服务,也是使用同一个网络,并且直接指定redis
的name即可.
同时访问两个overlay
的网络模式,比如有一个admin
需要同时访问dog-web
和cat-web
两个服务。我们可以如下操作,先启动一个catnet
的overlay
网络。
$ docker network create -d overlay --subnet 172.0.0.0/24 --gateway 172.0.0.1 catnet
$ docker service create --network catnet --name cat-db redis
$ docker service create --network catnet -p 8000:5000 -e 'DB=cat-db' -e 'ROLE=cat' --name cat-web chrch/web
# 同时使用两个overlay的网络环境
$ docker service create --network catnet --network dognet -p 7000:5000 -e 'DB1=dog-db' -e 'DB2=cat-db' --name admin chrch/admin
dog-web
和dog-db
之间网络可以互通,当时不可以访问catnet
上的服务,cat-web
和cat-db
之间也是可以互相访问的,但是不可以访问dognet
网络上的服务。