容器网络模型
libnetwork 中网络模型(Container Networking Model,CNM)十分简洁和抽象,可以让其上层使用网络功能的容器最大程度地忽略底层具体实现。
容器网络模型包括三种基本元素:
- 沙盒(Sandbox):代表一个容器(准确的说,是其网络命名空间)。
- 接入点(Endpoint):代表网络上可以挂载容器的接口,会分配 IP 地址。
- 网络(Network):可以连通多个接入点的一个子网。
CNM 概念模型:
CNM 的生命周期:
-
首先,驱动注册自己到网络控制器,网络控制器使用驱动类型,来创建网络。
-
然后,在创建的网络上创建接口。
-
最后,把容器连接到接口上。
-
销毁过程与创建正好相反,先把容器从接口上卸载,然后删除接入口和网络即可。
目前 CNM 支持的驱动类型有四种: -
Null:不提供网络服务,容器启动后无网络连接。
-
Bridge:Docker 传统上默认用 Linux 网桥和 Iptables 实现的单机网络。
-
Host:容器与主机共享同一 Network Namespace,共享同一套网络协议栈、路由表及 iptables 规则等。容器与主机看到的是相同的网络视图。
-
Overlay:用 vxlan 隧道实现的跨主机容器网络。
-
Remote:扩展类型,预留给其他外部实现的方案,比如有一套第三方的 SDN 方案(如 OpenStack Neutron)就可以接进来。
Docker 网络命令
$ docker network --help
Usage: docker network COMMAND
Manage networks
Commands:
connect Connect a container to a network
create Create a network
disconnect Disconnect a container from a network
inspect Display detailed information on one or more networks
ls List networks
prune Remove all unused networks
rm Remove one or more networks
创建网络
docker network create --help
Usage: docker network create [OPTIONS] NETWORK
Create a network
Options:
--attachable Enable manual container attachment
支持手动容器设置,默认为 false
--aux-address map Auxiliary IPv4 or IPv6 addresses used by Network driver (default map[])
辅助的 IP 地址,默认为 map[]
--config-from string The network from which copying the configuration
从某个网络复制配置数据
--config-only Create a configuration only network
启用仅可配置模式,默认为 false
-d, --driver string Driver to manage the Network (default "bridge")
网络驱动类型,bridge 或 overlay,默认为 bridge
--gateway strings IPv4 or IPv6 Gateway for the master subnet
网关地址
--ingress Create swarm routing-mesh network
创建一个 Swarm 可路由的网状网络用于负载均衡,可将对某个服务的请求,自动转发给一个合适的副本,默认为 false
--internal Restrict external access to the network
内部模式,禁止外部对所建网络的访问,默认为 false
--ip-range strings Allocate container ip from a sub-range
指定分配 IP 地址范围
--ipam-driver string IP Address Management Driver (default "default")
IP 地址管理插件类型,默认为 default
--ipam-opt map Set IPAM driver specific options (default map[])
IP 地址管理插件选项,默认为 map[]
--ipv6 Enable IPv6 networking
支持 IPv6 地址
--label list Set metadata on a network
为网络添加元标签信息
-o, --opt map Set driver specific options (default map[])
网络驱动所支持的选项,默认为 map[]
--scope string Control the network's scope
指定网络范围
--subnet strings Subnet in CIDR format that represents a network segment
网络地址段,CIDR 格式,如 192.168.0.0/16
接入网络
$ docker network connect --help
Usage: docker network connect [OPTIONS] NETWORK CONTAINER
Connect a container to a network
Options:
--alias strings Add network-scoped alias for the container
为容器添加一个别名,此别名仅在所添加的网络上可见
--driver-opt strings driver options for the network
指定网络驱动程序
--ip string IPv4 address (e.g., 172.30.100.104)
指定 IP 地址,注意不能与已经接口容器地址冲突
--ip6 string IPv6 address (e.g., 2001:db8::33)
指定 IPv6 地址
--link list Add link to another container
添加链接到另外一个容器
--link-local-ip strings Add a link-local address for the container
为容器添加一个链接地址
断开网络
$ docker network disconnect --help
Usage: docker network disconnect [OPTIONS] NETWORK CONTAINER
Disconnect a container from a network
Options:
-f, --force Force the container to disconnect from a network
强制把容器从网络中移除
查看网络信息
$ docker network inspect --help
Usage: docker network inspect [OPTIONS] NETWORK [NETWORK...]
Display detailed information on one or more networks
查看网络信息,包括接入的容器,网络配置信息等,展示为 JSON 格式
Options:
-f, --format string Format the output using the given Go template
给定一个 golong 模板字符串,对输出结果进行格式化,如 -f {{.IPAM.Config}},指定查看地址配置
-v, --verbose Verbose output for diagnostics
列出网络
$ docker network ls --help
Usage: docker network ls [OPTIONS]
List networks
用户列出网络,在不执行额外网络命令的情况下,一般会展示三个网络,分别对应 null、host 和 bridge
Aliases:
ls, list
Options:
-f, --filter filter Provide filter values (e.g. 'driver=bridge')
指定输出过滤器,如 driver=bridge
--format string Pretty-print networks using a Go template
给定一个 golong 模板字符串,对输出结果进行格式化
--no-trunc Do not truncate the output
不截断的输出内容,默认为 false
-q, --quiet Only display network IDs
安静模式,只打印网络 ID,默认为 false
清理无用网络
$ docker network prune --help
Usage: docker network prune [OPTIONS]
Remove all unused networks
清理所有已经没有容器使用的网络
Options:
--filter filter Provide filter values (e.g. 'until=<timestamp>')
指定选择过滤器
-f, --force Do not prompt for confirmation
强制清理
删除网络
$ docker network rm --help
Usage: docker network rm NETWORK [NETWORK...]
Remove one or more networks
删除指定网络。网络上没有容器连接时,才可以删除成功
Aliases:
rm, remove
构建跨主机容器网络
使用 libnetwork 自带的 Overlay 类型驱动实现跨主机网络通信。Overlay 驱动默认采用 VXLAN 协议,在 IP地址可以互相访问的多个主机之间搭建隧道,让容器可以互相访问。
Step1:配置网络信息管理数据库
要连通不同的实体主机,需要交换机,如果要跨子网连接,还需要路由器。交换机和路由器在物理上起到连接作用,也起到网络管理功能。同理,libnetwork 网络方案中,要实现跨主机的容器网络,也需要类似的网络信息管理机制,这种机制就是键值数据库,如 Consul、Etcd、Zookeeper 等工具。
# 启动一个 progrium/consul 容器,并映射到本地 8500 端口,该宿主机将作为数据库节点
$ docker run -d -p "8500:8500" -h "consul" progrium/consul -server -bootstrap
# -p 指定映射端口
# -h 指定容器 hostname
# -server
# -bootstrap
Step2:配置 Docker 主机
# 启动两台或多台 Docker 主机 s1、s2 ...
# 保证主机之间可以互相访问
# 保证主机都能访问到数据库节点的 8500 端口
# 配置主机的 Docker 服务启动项,/etc/default/docker 文件中添加如下配置
DOCKER_OPTS="$DOCKER_OPTS --cluster-store=consul://<CONSUL_NODE>:8500" --cluster-advertise=eth0:2376"
# 重启 Docker 服务
$ sudo service docker restart
Step3:创建网络
# 在任意节点上创建网络 multi,例如在 s1 上建立跨主机网络
s1:$ docker network create -d overlay multi
# 创建成功后,可以同时在 s1 和 s2 上新的网络 multi 的信息
s1:$ docker network ls
...
s2:$ docker network ls
...
# 查看网络信息
s1:$ docker network inspect multi
...
s2:$ docker network inspect multi
...
Step4:测试网络
# 在 s1 上启动一个容器 test1,通过 --net 连接到 multi 网络上
s1:$ docker run -it --nam=test1 --net=multi busybox
/ # ping test2
# 在 s2 上启动一个容器 test2,通过 --net 连接到 multi 网络上
s2:$ docker run -it --nam=test2 --net=multi busybox
/ # ping test1