type
status
date
slug
summary
tags
category
icon
password
1、Docker的网络类型
Docker 有四种网络类型:
- None
- Host
- Bridge
- Container
安装 Docker 以后,会默认创建三种网络,可以通过
docker network ls
查看。1.1 none模式
none 网络模式即不为 Docker Container 创建任何的网络环境,容器内部就只能使用 loopback 网络设备,不会再有其他的网络资源。即只有 lo 接口 local 的简写,代表 127.0.0.1,即 localhost 本地环回接口。
在创建容器时通过参数
--net none
或者 --network none
指定使用 none 网络。我们不禁会问,这样一个封闭的网络有什么用呢?
其实还真有应用场景。封闭意味着隔离,一些对安全性要求高并且不需要联网的应用可以使用 none 网络。比如某个容器的唯一用途是生成随机密码,就可以放到 none 网络中避免密码被窃取。
1.2 host模式
连接到 host 网络的容器共享 Docker host 的网络栈,容器的网络配置与host完全一样。若宿主机的 eth0 是一个公有 IP,那么容器也拥有这个公有 IP。同时容器内服务的端口也可以使用宿主机的端口,无需额外进行 NAT 转换。
创建容器时通过参数
--net host
或者 --network host
指定使用 host 网络。在容器中可以看到 host 的所有网卡,并且连 hostname 也是 host 的。host 网络的使用场景又是什么呢?
直接使用 Docker host 的网络最大的好处就是性能,如果容器对网络传输效率有较高要求,则可以选择 host 网络。当然不便之处就是牺牲一些灵活性,比如要考虑端口冲突问题,Docker host上已经使用的端口就不能再用了。
Docker host 的另一个用途是让容器可以直接配置 host 网路,比如某些跨 host 的网络解决方案,其本身也是以容器方式运行的,这些方案需要对网络进行配置,比如管理 iptables,大家将会在后面进阶技术章节看到。
1.3 bridge模式
Docker 的默认网络模式。Docker 安装时会创建一个命名为 docker0 的 Linux bridge。如果不指定 --network,创建的容器默认都会挂到 docker0 上。
当前 docker0 上没有任何其他网络设备,我们创建一个容器看看有什么变化,如图所示。
一个新的网络接口 veth28c57df 被挂到了 docker0 上,veth28c57df 就是新创建容器的虚拟网卡。下面看一下容器的网络配置。
实际上 eth0@if34 和 veth28c57df 是一对 veth pair。veth pair 是守护进程会创建的一对对等的虚拟设备接口,可以把它们想象成由一根虚拟网线连接起来的一对网卡,网卡的一头(eth0@if34)在容器中,另一头(veth28c57df)挂在网桥 docker0 上,其效果就是将 eth0@if34 也挂在了 docker0 上。
我们还看到 eth0@if34 已经配置了IP 172.17.0.2。为什么是这个网段呢?让我们通过 docker network inspect bridge 看一下 bridge 网络的配置信息。
原来 bridge 网络配置的 subnet 就是172.17.0.0/16,并且网关是172.17.0.1。这说明,守护进程还会从网桥 docker0 的地址段中分配一个 IP 地址和子网给该容器,并设置 docker0 的 IP 地址为容器的默认网关。
总结一下,Bridge 桥接模式的实现步骤主要如下:
- Docker Daemon 利用 veth pair 技术,在宿主机上创建一对对等虚拟网络接口设备,假设为 veth0 和 veth1。veth pair 技术的特性可以保证无论哪一个 veth 接收到网络报文,都会将报文传输给另一方。
- Docker Daemon 将 veth0 附加到 Docker Daemon 创建的 docker0 网桥上。保证宿主机的网络报文可以发往 veth0;
- Docker Daemon 将 veth1 添加到 Docker Container 所属的 namespace 下,并被改名为 eth0。如此一来,宿主机的网络报文若发往 veth0,则立即会被 Container 的 eth0 接收,实现宿主机到 Docker Container 网络的联通性;同时,也保证 Docker Container 单独使用 eth0,实现容器网络环境的隔离性。
要想使用 bridge 模式,在创建容器时通过参数
--net bridge
或者 --network bridge
指定即可,当然这也是创建容器默认使用的网络模式,也就是说这个参数是可以省略的。1.4 container模式
处于 Container 网络模式下的 Docker 容器会共享一个网络栈,这样两个容器之间可以使用 localhost 高效快速通信。即新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样两个容器除了网络方面相同之外,其他的如文件系统、进程列表等还是隔离的。
要想使用 container 网络模式,在创建容器时通过参数
--net container:已运行的容器名称|ID
或者 --network container:已运行的容器名称|ID
指定。处于 Container 网络模式下的容器,如果所依赖的容器停止运行了,本容器就只剩下 lo 接口了。
2、容器间的通信
容器之间可通过IP、Docker DNS Server 或 joined 容器三种方式通信。
docker run --link
可以用来链接两个容器,使得源容器(被链接的容器)和接收容器(主动去链接的容器)之间可以互相通信,并且接收容器可以获取源容器的一些数据,如源容器的环境变量。这种方式官方已不推荐使用,并且在未来版本可能会被移除。
2.1 IP通信
处于同一网络下的两个容器可以直接通过 IP 地址进行通信。具体做法是在容器创建时通过 --network 指定相应的网络,或者通过 docker network connect 将现有容器加入到指定网络。
但是 IP 地址可能是不固定的,有被更改的情况发生,那容器内所有通信的 IP 地址也需要进行更改。
2.2 Docker DNS Server和自定义网络
从 Docker 1.10 版本开始,Docker daemon 实现了一个内嵌的 DNS server,使容器可以直接通过容器名称通信。方法很简单,只要在创建容器时使用 –name 为容器命名即可。
但是使用 Docker DNS 有个限制:只能在 user-defined 网络中使用。也就是说,默认的 bridge 网络是无法使用 DNS 的。
为了启用容器名称到 IP 地址的自动 DNS 解析,以及提高容器的安全性,我们就需要自定义网络。
2.2.1 创建网络
创建一个基于 bridge 网络模式的自定义网络模式 custom_network。
查看网络模式,确认生成 custom_network 模式。
2.2.2 使用自定义网络创建容器
这时候进入容器 custom_bbox01,直接执行
通过容器名字已经可以 ping 通。
2.2.3 加入自定义网络模式
已经存在的容器 custom_bbox03,可以加入自定义网络模式 custom_network
2.2.4 断开自定义网络模式
custom_bbox03也可以退出自定义网络模式
2.2.5 删除自定义网络模式
注意:如果通过某个自定义网络模式创建了容器,则该网络模式无法删除。
2.3 joined容器
joined 容器非常特别,它可以使两个或多个容器共享一个网络栈,共享网卡和配置信息,joined 容器之间可以通过 127.0.0.1 直接通信。
先创建一个httpd容器,名字为web1。
然后创建 busybox 容器并通过 --network=container:web1 指定 joined 容器为 web1。
这样 busybox 和 web1 的网卡 mac 地址与 IP 完全一样,它们共享了相同的网络栈。busybox 可以直接用 127.0.0.1 访问 web1 的 http 服务。
joined 容器非常适合以下场景:
- 不同容器中的程序希望通过 loopback 高效快速地通信,比如 Web Server 与 App Server。
- 希望监控其他容器的网络流量,比如运行在独立容器中的网络监控程序。
3、将容器与外部世界连接
前面我们已经解决了容器间通信的问题,接下来讨论容器如何与外部世界通信。这里涉及两个方向:
- 容器访问外部世界。
- 外部世界访问容器。
3.1 容器访问外部世界
容器默认就能访问外网。
3.2 外部世界访问容器
下面我们来讨论另一个方向:外网如何访问到容器?答案是:端口映射。
docker 可将容器对外提供服务的端口映射到 host 的某个端口,外网通过该端口访问容器。容器启动时通过 -p 参数映射端口。
容器启动后,可通过 docker ps 或者 docker port 查看到 host 映射的端口。在上面的例子中,httpd 容器的 80 端口被映射到 host 32773上,这样就可以通过 <host ip>:<32773> 访问容器的 Web 服务了。
每一个映射的端口,host 都会启动一个 docker-proxy 进程来处理访问容器的流量,如图所示。
- Author:mcbilla
- URL:http://mcbilla.com/article/24078f9f-894c-4920-a72c-5e9402d1508f
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!
Relate Posts