### 一、网络概述

Docker 的网络底层原理利用 Linux 操作系统提供的网络命名空间、虚拟网络设备、iptables 规则等特性，通过 Bridge 桥接网络或 Overlay 网络模式实现容器之间的通信。这种网络隔离和虚拟化的设计使得容器可以更灵活地运行在不同的网络环境中

### 二、Docker 网络模式

- Bridge 桥接模式（默认模式）
- Host 主机模式
- None 无网络模式
- Overlay 覆盖模式
- Macvlan MACVLAN 模式
- Custom 自定义网络模式

### 三、具体网络模式详解

#### 1. Bridge模式

Docker 默认的网络模式，容器连接到一个本地的 Docker 桥接网络，由宿主机上的 docker0 虚拟网桥负责管理。在这个模式下，容器可以相互通信，也可以通过宿主机与外部网络通信。这种模式提供了网络隔离，但容器之间可以通过容器名称进行访问

```bash
docker run --network=bridge my_container
```



#### 2. Host模式

容器与宿主机共享网络栈，即容器使用宿主机的网络命名空间和网络设备。这样可以提高容器的网络性能，但会导致容器失去网络隔离，与宿主机共享相同的网络地址和端口空间

```bash
docker run --network=host my_container
```



#### 3. None 无网络模式

容器没有自己的网络命名空间，也不连接到任何网络。这意味着容器无法进行网络通信，适用于一些特殊的场景，例如只需要本地访问的容器

```bash
docker run --network=none my_container
```



#### 4. Overlay 覆盖模式

Overlay 模式用于实现多个 Docker 守护进程之间的容器通信，特别适用于跨主机的容器编排工具（如 Docker Swarm）。Overlay 网络通过在容器之间创建逻辑网络层，使得它们可以在不同主机上进行通信

```bash
# 在 Docker Swarm 中使用 overlay 网络
docker network create --driver overlay myoverlaynetwork
```



#### 5. Macvlan macvlan模式

Macvlan 模式允许容器拥有自己的 MAC 地址，从而使其在网络中表现得像一个物理设备一样。这种模式通常用于需要容器与物理网络设备直接通信的场景

```bash
docker network create -d macvlan \
  --subnet=192.168.1.0/24 \
  --gateway=192.168.1.1 \
  -o parent=eth0 \
  mymacvlan
docker run --network=mymacvlan my_container
```



#### 6. Custom 自定义网络模式

用户可以创建自定义的 Docker 网络，灵活配置网络属性，以满足特定应用的需求。自定义网络模式提供了更高级的网络配置选项，用户可以定义子网、网关等参数

```bash
docker network create mynetwork
docker run --network=mynetwork my_container
```

### 四、同一个网络间容器通信原理

1. **共享网络命名空间：** 同一网络中的容器共享相同的网络命名空间。网络命名空间是 Linux 内核提供的一种隔离机制，它使得容器能够在网络层面互相感知和通信。容器内的网络配置、接口和路由表等信息都是在这个共享的网络命名空间中
2. **Docker Bridge：** 在默认的 Bridge 模式下，Docker 创建一个本地的桥接网络，通常称为 `docker0` 网桥。这个桥接网络作为同一网络中所有容器的连接点，使得它们可以相互通信。每个容器会被分配一个独立的 IP 地址，这样它们可以通过这个 IP 地址进行通信
3. **DNS 解析：** Docker 提供了容器间的 DNS 解析服务。通过容器的名称，可以在同一网络中的容器之间进行域名解析。这意味着你可以使用容器的名称而不是 IP 地址来访问其他容器
4. **iptables 规则：** Docker 利用 iptables 来实现网络地址转换（NAT）和端口映射等功能。这些规则允许容器之间的通信，以及容器与宿主机之间的通信。Docker 通过这些规则确保网络包从一个容器正确地流向另一个容器或宿主机
5. **虚拟网卡：**使用docker network创建自定义网络会在主机上创建一个虚拟网卡，容器需要与主机通信时需要通过该虚拟网卡

<img src="https://blog-heysq-1255479807.cos.ap-beijing.myqcloud.com/halo2/202401091733370.png" alt="image-20240109173303317" style="zoom:50%;" />



### 五、network 常用命令

#### 1. 列出所有网络

```bash
bash: docker network ls
NETWORK ID     NAME             DRIVER    SCOPE
d343c2f00fd6   1panel-network   bridge    local
6e0b3a12badf   bridge           bridge    local
7f5baf2ce0a8   host             host      local
c612b4fb2640   internal         bridge    local
52194e1004e7   none             null      local
```

#### 2. 创建网络

- 命令行参数

```bash
Usage:  docker network create [OPTIONS] NETWORK

Create a network

Options:
      --attachable           Enable manual container attachment
      --aux-address map      Auxiliary IPv4 or IPv6 addresses used by Network driver (default map[])
      --config-from string   The network from which to copy the configuration
      --config-only          Create a configuration only network
  -d, --driver string        Driver to manage the Network (default "bridge")
      --gateway strings      IPv4 or IPv6 Gateway for the master subnet
      --ingress              Create swarm routing-mesh network
      --internal             Restrict external access to the network
      --ip-range strings     Allocate container ip from a sub-range
      --ipam-driver string   IP Address Management Driver (default "default")
      --ipam-opt map         Set IPAM driver specific options (default map[])
      --ipv6                 Enable IPv6 networking
      --label list           Set metadata on a network
  -o, --opt map              Set driver specific options (default map[])
      --scope string         Control the network's scope
      --subnet strings       Subnet in CIDR format that represents a network segment
```

- 创建自定义网络
  - driver_name：bridge，macvlan，host，overlay， none

```bash
docker network create --subnet=<subnet> --gateway=<gateway> -d drive_name <network_name>

```



#### 3. 使用某个网络

- 创建容器时设置网络

```bash
docker run -itd --name nginx-test --network=mynetwork nginx:1.18
```

- 运行中的容器连接到网络，此时容器中会多一个网卡

```bash
docker network connect mynetwork1 nginx-test
```

<img src="https://blog-heysq-1255479807.cos.ap-beijing.myqcloud.com/halo2/202401091719391.png" alt="image-20240109171909268" style="zoom:50%;" />

- 将某个网络与容器断开连接

```bash
docker network disconnect mynetwork1 nginx-test
```



#### 4. 查看网络信息

```bash
docker network inspect mynetwork
[
    {
        "Name": "mynetwork",
        "Id": "bf66c98d13a8159c5539e873a0236974f501ac33c0b0622e66389fb7195d784b",
        "Created": "2024-01-09T04:25:50.892326739-05:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.21.0.0/16",
                    "Gateway": "172.21.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "ef4755825054960b2042f217e10666926a1f4226d56ac1a179c9dce2cc825b53": {
                "Name": "nginx-test",
                "EndpointID": "3b234715756c75194ce7947930f733424acef4f6855a53882d6986bc50ab2cfb",
                "MacAddress": "02:42:ac:15:00:02",
                "IPv4Address": "172.21.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]
```

