# 容器网络概述

## 单机网络

容器的创建使用到了两个 Linux 内核的特性 namespace 和 cgroup。

* Docker 创建容器四种网络模式
  1. `--net=host`
  2. `--net=container:NAME_or_ID`
  3. `--net=none`
  4. `--net=bridge` （默认）

### bridge

bridge 模式下，Docker Daemon 首次启动时会创建一个虚拟网桥，默认名称为 docker0，然后在私有网络空间给这个网桥分配一个子网。每创建一个容器都会创建一个 Veth 设备对，一端关联到网桥，另一端通过网络命名空间映射到容器内的 eth0 设备，然后在网桥的地址段内给 eth0 接口分配一个 IP 地址。

网桥的IP地址，Docker Daemon 会在几个备选地址段里给它选一个地址，通常是以 172 开头的一个地址， 这个地址和主机的 IP 地址是不重叠的。容器 IP 地址是 Docker 启动容器时在这个地址段选择的一个没有使用的 IP 地址，相应的 MAC 地址也根据这个 IP 地址，在 02:42:ac:11:00:00 和 02:42:ac:11:ff:ff 的范围内生成（02:42 为前缀，ac 为 172），这样做可以确保不会有 ARP 冲突。

启动后，Docker 还将 Veth 设备对的名称映射到 eth0 网络接口。一般情况下，网桥、容器所在子网和主机是不同的 IP 段，所以在默认不做任何特殊配置的情况下，在外部是看不到容器网络的。

容器访问外部网络通过 NAT 的方式。

### host

使用 host 模式将和宿主机共用一个 Network Namespace

容器不会虚拟出自己的网卡，配置自己的 IP 等，而是使用与主机相同的网络协议栈，容器可以直接使用主机的所有网络接口。

容器中的进程不用任何 NAT 转换，就像直接跑在宿主机中一样。但是，容器的其他方面，如文件系统、进程列表等还是和宿主机隔离的。

### MacVlan

MacVlan 是工作在二层的虚拟网络接口，这个接口连接着物理接口。

每个 MacVlan 都会被分配一个唯一的 MAC 地址，对应的容器收发数据包都会使用这个 MAC 地址。

## 多机网络

### Overlay

Overlay 网络通常使用 VxLAN \[^1] 实现，是一个跨越三层的二层方案。每个 VTEP \[^2] 连接到物理机器，在不同机器的网桥之间建立起隧道。

由编排工具协调 IP 地址和隧道。

### Direct Routing

Direct Routing 是一个三层方案。每台机器分配一个互相不冲突的子网，通过添加路由规则实现不同主机的容器通信，将每台物理机器作为机器上容器子网的网关。

通常每台机器上运行一个路由守护进程，将子网的路由信息通过 BGP 发送出去。

\[^1]: Virtual Extensible LAN \[^2]: Virtual Tunnel Endpoint
