Docker 将网络视为第一级别的实体。网络实体具有自己的生命周期,不受其他对象约束。
连接到 Docker 网络的容器将获得唯一的 IP 地址,连接到同一 Docker 网络的容器可以根据 IP 找到目标容器并发送消息。
网络的范围有三种类型:
- 本地(local)- 网络被限制在所在的计算机上;
- 全局(global)- 在集群的每个节点上创建网络,但是不在节点间转发消息;
- 集群(swarm)- 网络无缝地跨接集群中的所有助局。
当前 Docker 网络不再提供容器之间的访问控制或防火墙设置,即同一容器网络上的容器具有相互无限制的网络访问权限。
默认网络
可用 docker network ls
打印所有网络。每个 Docker 默认会自带三个 本地 网络:
bridge
- Docker 的默认桥接网络;host
- 主机网络;none
- 无网络,连接到none
网络的容器没有出自身外的网络连接。
默认的 bridge
网络为了兼容旧版 Docker ,无法使用新版 Docker 的功能特性,比如服务发现和负载均衡等机制,因此不建议使用。通常应当建立自己的桥接网络来使用。
桥接网络
桥接网络是本地的,主要功能是在主机上的容器和主机网络之间建立路由。
Docker 使用 bridge 网络驱动程序创建桥接网络,它利用了 Linux 命名空间、虚拟以太网设备、Linux 防火墙三项技术来构建可定制化的虚拟网络拓扑结构。
每个容器身上都有私有接口和环回接口(localhost),同时还有一个虚拟接口,用来在连接私有接口和 Docker 桥接虚拟接口。处在同一桥接网络的容器会通过 Docker 桥接虚拟接口进行通信。
可用 docker network create
来创建本地桥接网络:
docker network create \
--driver bridge \
--attachable \
--scope local \
--subnet 10.0.42.0/24 \
--ip-range 10.0.42.128/25 \
user-network
--driver
:指定网络驱动程序,默认值即为bridge
;--attachable
:将网络标记为可连接的,即可随时对容器与容器连接或分离;--scope local
:将网络范围设为本地;--subset
:子网掩码;--ip-range
:可分配的 IP 地址范围。
创建容器时可以通过 --network
来连接网络:
docker run -it \
--network user-network \
--name network-explorer \
apline:3.8 sh
也可以用 docker network connect
将一个容器与一个桥接网络连接:
# 创建另一个桥接网络 `user-network2`
docker network create ... user-network2
# 将容器 `network-explorer` 与网络 `user-network2` 连接
docker network connect user-network2 network-explorer
可以安装
nmap
工具来检测当前主机/容器中的网络。
容器的主机名默认与容器名称一致,也可以在创建容器是通过 --hostname
指定主机名。
主机网络 & none
网络
对于一些系统服务或者基础架构,通常有必要再主机网络上运行。可以用 --network host
来使用主机网络:
# 列出主机网络上容器内部所有可用网络
docker run --rm --network host \
apline:3.8 ip -o addr
若容器使用的 none
网络,则容器自身只能与环回接口(localhost)连接,无法访问容器外网络。容器外部的组件也不能与该容器连接。
若容器的网络隔离需求很高,则应当使用 none
网络。本着最小权限原则,一般的容器若不需要网络则尽可能使用 none
网络。
节点端口发布
节点端口发布(NodePort Publishing)是用来匹配 Docker 和其它容器生态系统项目的专用术语。其中 Node 通常是指较大机器集群中的节点。
默认情况下,桥接网络中的容器是无法被主机外部路由到的,只能让容器之间相互通信。如果要与主机外部网络连接,需要我们在创建容器时指定 端口发布配置 。
端口发布配置在容器创建后 无法再次修改 ,它通过 --publish
或 -p
指定,而参数需要指定 主机接口、要转发的主机端口、容器目标端口、端口协议 。参数的格式比较灵活,比如以下参数均代表将主机的 TCP 端口 8080 的流量转发到容器的 TCP 端口 8080 上:
0.0.0.0:8080:8080/tcp
(完整形式)8080:8080/tcp
8080:8080
也可以不指定主机相关接口信息,比如对于 -p 8080
,Docker 会在主机上随机选择一个端口来映射到容器的 8080 端口。
可以通过 docker port
来查找给定容器的端口列表:
docker run -d -p 8080 --name listener ...
docker port listener
如果容器用了较多的端口,也可以在 docker port
中指定要查找的端口:
docker run -d -p 8080 -p 3000 -p 7500 --name multi-listener ...
docker port multi-listener 3000
Docker 通过 网络地址转换(NAT) 来将主机流量路由到容器端口。
DNS 配置
Docker 提供了一些 DNS 相关的命令选项:
--hostname <主机名>
:用于设置容器的主机名;--dns <DNS服务IP>
:用于设置容器所使用的 DNS 服务;--dns-search <域名>
:根据给定的(顶级)域名来让 DNS 进行短域名查找;--add-host <主机名:IP地址>
:在容器中添加主机记录;
其中,--dns
--dns-search
--add-host
均可以多次指定。--dns
--dns-search
也可以在 Docker 引擎启动时指定,来作为启动容器 DNS 默认配置,但当 Docker 引擎重新启动时,旧容器会保持原来的 DNS 配置。
这段内容仅作概要,书中有进一步的解释和例子,可见书中 P99 。