最后更新于
最后更新于
Sandbox: 协议栈,可包含多个 Endpoint,可通过 Namespace、Jail 等实现
Endpoint: 将 Sandbox 与 Network 连接
Network: 可直接通信的 Endpoint 的集合,可使用 Bridge、VLAN 等实现
Docker Daemon 管理可用的 NetworkController。在启动 Daemon 时,会创建当前操作系统下全部可用的 NetworkController,以 daemon_unix.go 为例,创建了 none、host、bridge 三种模式的网络控制器。
controller 是 libnetwork 中对 NetworkController 的实现。可以看到,controller 通过驱动表来区分不同类型的网络,使用驱动创建 Network 及 Endpoint,并将 Endpoint 加入 Sandbox 或移除出 Sandbox。 Container 通过 SandboxID 以及 SandboxKey 来找到对应的 Sandbox。Sandbox 可以使用 containerID 来确定是否归属于某个 Container。
Sandbox 接口没有列举出全部功能,只是能看出其能力边界的部分功能。后续以 Namespace 方式实现的 Sandbox 为例。 通过上图,并不难看出,路由、接口等功能应该是由 netlink 提供的,Namespace 获取 netlink 方式如下,需要注意,Namespace 内 netlink 配置,仅在 Namespace 内有效。根据 Namespace 获取 netlink 的关键方法如下
使用返回的 NsHandle 就可以创建具体的 SocketHandle 了,方法如下
根据配置文件中 BridgeName 查找系统中已存在的 Link 实例,如果 BridgeName 为空,使用默认网桥 docker0。
创建 bridgeNetwork 实例,并存入 networks
如果获取的 bridgeInterface 中不存在有效网桥设备,则将创建设备、sysctl 方法加入设置队列;如果使用 docker0,仅将 sysctl 方法加入设置队列
根据配置文件参数,将对应的设置方法加入设置队列
将设备启动设置方法加入设置队列,并返回执行结果
创建 netlink.Bridge 结构体,LinkAttrs 中使用配置中的 BridgeName,然后,使用 netlink 方法创建网桥设备,如果需要设置 MAC 则随机生成 MAC 地址。
Bridge 设备创建、配置等,最终均通过 netlink 接口完成。
System Control
/proc/sys/net/ipv6/conf/BridgeName/accept_ra -> 0:不接受路由建议
/proc/sys/net/ipv4/conf/BridgeName/route_localnet -> 1:将外部流量重定向至 loopback,需要配合 iptables 使用
INTERNAL
filter
DOCKER-ISOLATION-STAGE-1 -i BridgeInterface ! -d Network -j DROP
DOCKER-ISOLATION-STAGE-1 -o BridgeInterface ! -s Network -j DROP
NON INTERNAL
nat
DOCKER -t nat -i BridgeInterface -j RETURN
filter
FORWARD -i BridgeInterface ! -o BridgeInterface -j ACCEPT
HOST IP != nil
nat
POSTROUTING -t nat -s BridgeSubnet ! -o BridgeInterface -j SNAT --to-source HOSTIP
POSTROUTING -t nat -m addrtype --src-type LOCAL -o BridgeInterface -j SNAT --to-source HOSTIP
HOST IP == nil
nat
POSTROUTING -t nat -s BridgeSubnet ! -o BridgeInterface -j MASQUERADE
POSTROUTING -t nat -m addrtype --src-type LOCAL -o BridgeInterface -j MASQUERADE
Inter Container Communication Enabled
filter
FORWARD -i BridgeInterface -o __BridgeInterface -j ACCEPT
Inter Container Communication Disabled
filter
FORWARD -i BridgeInterface -o __BridgeInterface -j DROP
nat
PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
OUTPUT -m addrtype --dst-type LOCAL -j DOCKER
filter
FORWARD -o BridgeInterface -j DOCKER
FORWARD -o BridgeInterface -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
filter
-I FORWARD -j DOCKER-ISOLATION-STAGE-1
全局有一个默认 Bridge 设备 docker0,每个 Container 有自己独立的网络协议栈,容器网络和通过 veth 对与 Bridge 设备互通。 同一节点上不同 Container 间,通过 ARP 协议,即可进行 3 层通信;Container 出 Node 网络可以通过默认网关设备 docker0,再经过 IPTABLES 重定向至 eth0。