前言
在一个Python web项目中,比如django web服务,该服务肯定是需要和MySQL Redis等进行通信,使用docker进行部署的时候,容器之间是相互隔离的,那么它们之间是如何通信的呢?外部又是如何通过宿主机访问到宿主机上的容器中运行的服务的呢?本文介绍docker的网络通信机制,解释如何通过这种机制进行容器和容器之间的相互访问以及容器和宿主机之间的相互访问。
docker网络通信机制
docker提供的网络通信机制就是允许通过外部访问容器或者容器互联的方式提供网络服务。
当docker启动时会自动在宿主机上创建一个虚拟网桥(bridge),可以理解为一个软件交换机,它会挂载到它的网口进行转发。docker在启动时还会随机分配一个本地未占有的私有网段的一个地址给bridge接口,此后,以该网桥启动的容器的网口也会自动分配一个同一网段的地址。当创建一个docker容器的时候,同时会创建一对veth接口,这对接口一段在容器内即eth0
,另一段被挂载到bridge网桥名称以veth
开头,当数据包发送到一个接口时,另一个接口也可以收到相同的数据包,通过这种方式主机可以和容器通信,容器之间也可以相互通信,docker就创建了在主机和所有容器之间一个虚拟共享网络。
使用docker默认网桥好处和坏处体现在同一点,就是所有的容器之间都可以互相通信,产生的问题就是如果某两个某几个容器频繁的交换数据势必会对其他容器产生影响,因此可以通过构建自己的网桥进行使用,一个项目应该构建一个网桥。
docker网络使用
一般我们在部署项目的时候都会创建一个该项目的网桥,而不是使用默认的,如果每个应用都使用默认的网桥,就意味着每个容器之间都是可以进行通信的,而在实际项目中,我们只需要让这个项目中使用到的容器之间可以通信就可以了。
一般在使用docker网桥实现容器与容器通信时,都是站在一个应用角度进行容器通信。
docker network ls:查看docker网桥配置
docker create bridge(网桥名称):docker创建自定义网桥
docker run -d -p 8080:8080 --name xx --network xxx(网桥名称) 镜像名:tag:为容器指定网桥启动,使用docker run指定--network时网桥必须存在。一旦在启动容器时指定了网桥,日后可以在任何这个网桥关联的容器中使用容器名字进行与其他容器通信。容器名字就代表该容器的ip地址。即同一网桥上的服务可以互相访问,可以使用http://ip:port
的形式,也可以使用http://容器名:port
的形式,因为容器名是唯一的。
docker network rm 网桥名称:删除网桥
docker inspect 网桥名称:查看网桥的详细信息