• Post author:
  • Post category:docker
Like
Like Love Haha Wow Sad Angry

一、概念

  我们知道 docker 容器是独立互不影响的,那么其网络也是,其底层主要就是依赖 Linux 的网络命名空间来实现网络的隔离。每个容器都有着独属自己的网络命名空间,每个网络命名空间都提供了一个完全独立的网络协议栈,包括网络设备接口、IPV4 和 IPV6 协议栈、IP路由表、防火墙规则、端口、sockets 等,这样便使得每个容器的网络是相互隔离互不影响的。而网络命名空间的通信也就是容器间的通信主要是借助虚拟网络设备(特别是veth)实现的。
  当然关于网络命名空间,我们这里不深究(可以阅读我的另一篇文章:ip netns,来了解网络命名空间的一些基本操作)。docker 为我们提供了网络相关的命令来管理容器网络,让我们使用时最大程度上忽略了其底层的具体实现。下面我们将会学习到 docker 网络相关的命令。

  当我们安装启动 docker 之后,docker 会在宿主机上自动创建一个名为 docker0 的虚拟网桥,其网段一般为172.17.0.0/16,地址为172.17.0.1。我们后续创建的容器如果不特别指定网络,默认会分配一个该网段的地址给容器。容器和容器间通信都会通过这个网桥来进行通信,类似于交换机。
  当创建一个容器时,如果不特别指定的话它的网络默认为 bridge(即网桥docker0)。同时还会创建一对 veth pair 虚拟接口,一端在容器内(网络命名空间内),名称为eth0;一端在本地宿主机,会连接到 docker0 或者指定网桥上,作为其的从属网卡,且名称一般为 veth 开头。然后会从网桥可用地址段中获取一个空闲的地址分配给容器的 eth0,并配置默认网关为网桥的的 IP 地址。通过这种方式就实现了容器和宿主机间的通信、容器和容器间的通信。

二、四种网络模式

docker 容器有四种网络模式,如下:

 • bridge:网桥,如上,为默认网络。
 • host:容器和宿主机共享网络,即不给容器分配独立的网络命名空间,和宿主机处于同一个网络栈里,使用的也是宿主机的网络。
 • none:给容器分配独立的网络命名空间,但是不进行网络配置,需要自行手动配置(如何配置:可阅读 ip netns )
 • container:和另一个容器一起共享它的网络命名空间。

设置方法:

root@cp:~# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
559b98272716   bridge    bridge    local
43ba4a7c0f8f   host      host      local
bd89dc2f3ffa   none      null      local

在使用 docker run 命令时指定 --network 选项:
root@cp:~# docker run -it --network 
bridge   container:   host   none    

--network=bridge
--network=host
--network=none
--network=container:容器名称或者ID

就不用示例演示了,大家自行尝试

三、基本命令

docker 网络相关操作都是作为 network 的子命令出现,如下:

Usage:  docker network COMMAND

Manage networks

Commands:
  create      创建一个网络
  connect     将容器连接到网络
  disconnect  断开容器与网络的连接
  inspect     查看网络的详细信息
  ls          列出所有网络
  prune       清理无用的网络
  rm          删除一个网络

1、创建网络

docker network create [OPTIONS] NETWORK

该命令用于创建一个新的网络,默认是 bridge 类型。

选项 含义
–subnet strings 网络地址段。CIDR格式,如:192.168.1.0/24
–gateway strings 网关地址
–ip-range strings 指定分配的ip地址范围
–internal 禁止外部访问创建的网络
–scope string 指定网络范围
-d, –driver string 网络驱动类型,有bridge、ipvlan、macvlan、overlay
–config-from string 从某个网络复制配置数据
–config-only 创建仅可配置网络
–attachable 支持手动容器挂载
–ipv6 支持ipv6地址

例:
创建名为 test 的网络,网络网段为192.168.1.0/24,网关为 192.168.1.1(不指定也可以默认为该网段的第一个ip)。

root@cp:~# docker network create --subnet 192.168.1.0/24 --gateway 192.168.1.1 test
ca4631b94e5aacff7b2f5e9666e40aa1f5da8eae6a248df228916c39a5b63d75
root@cp:~# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
559b98272716   bridge    bridge    local
43ba4a7c0f8f   host      host      local
bd89dc2f3ffa   none      null      local
ca4631b94e5a   test      bridge    local

此时就可以看到会多出一个虚拟网桥出来。

root@cp:~# ip a
......
5: br-ca4631b94e5a: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:1c:04:76:f1 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.1/24 brd 192.168.1.255 scope global br-ca4631b94e5a
       valid_lft forever preferred_lft forever

创建一个容器,指定容器的网络为上面新创建的 test,再创建一个容器不指定网络,进行对比。

root@cp:~# docker run -it --network=test --ip=192.168.1.10 centos
[root@0e606105f24a /]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:c0:a8:01:0a brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.1.10/24 brd 192.168.1.255 scope global eth0
       valid_lft forever preferred_lft forever

root@cp:~# docker run -it  centos
[root@4b63d4284e45 /]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
12: eth0@if13: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

值得注意的是:默认网络并不支持指定容器的ip地址,仅用户自定义的网络可以指定。

2、连接容器到网络

docker network connect [OPTIONS] NETWORK CONTAINER

该命令用于将一个容器连接到一个网络,处于同一网络的容器是互通的,且一个容器可以同时连接到多个网络。

选项 含义
–ip string 指定ipv4地址(例如 172.30.100.104)
–ip6 string 指定ipv6地址(例如 2001:db8::33)
–alias strings 为容器添加一个别名,此别名只在所连接的网络上可见
–link list 添加链接到其它容器
–link-local-ip strings 为容器添加本地链接地址

例:

root@cp:~# docker run -itd --name test1 centos
06fd23c7122d7cb661d314356169095f561c9917e0546bd1e7a28e47c82b160a
root@cp:~# docker network connect test test1
root@cp:~# docker exec test1 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
29: eth0@if30: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
31: eth1@if32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:c0:a8:01:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.1.2/24 brd 192.168.1.255 scope global eth1
       valid_lft forever preferred_lft forever

同样我们可以在连接时,使用 –ip 选项指定 ip 地址。

root@cp:~# docker run -itd --name test2 centos
6ab05c10291dbe2a515793c2d802aa0a7f295321fd4cca9666dd4b08604bc060
root@cp:~# docker network connect --ip 192.168.1.5 test test2
root@cp:~# docker inspect -f {{.NetworkSettings.Networks.test.IPAddress}} test2
192.168.1.5

3、断开容器与网络的连接

docker network disconnect [OPTIONS] NETWORK CONTAINER

该命令用于将一个网络和连接的容器上断开连接。

选项 含义
-f, –force 强制断开

例:

root@cp:~# docker network disconnect test test1
root@cp:~# docker exec test1 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
29: eth0@if30: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

root@cp:~# docker inspect -f '{{.NetworkSettings.Networks.test}}' test1
<no value>

4、列出网络

docker network ls [OPTIONS]

该命令用于列出所有网络。

选项 含义
-f, –filter filter 过滤输出信息
–format string 使用Go模板打印出指定格式的输出信息
–no-trunc 不截断输出信息
–q, –quiet 仅输出id信息

例:
前面3个网络是 docker 默认创建的网络,创建一个容器时不指定网络,默认就是第一个网络 bridge。

root@cp:~# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
559b98272716   bridge    bridge    local
43ba4a7c0f8f   host      host      local
bd89dc2f3ffa   none      null      local
ca4631b94e5a   test      bridge    local

使用 -f 选项过滤输出信息,支持name、id、driver、scope等。

root@cp:~# docker network ls -f 
dangling=  driver=    id=        label=     name=      scope=     type=      
root@cp:~# docker network ls -f name=b
NETWORK ID     NAME      DRIVER    SCOPE
559b98272716   bridge    bridge    local
root@cp:~# docker network ls -f id=^4
NETWORK ID     NAME      DRIVER    SCOPE
43ba4a7c0f8f   host      host      local
root@cp:~# docker network ls -f driver=host
NETWORK ID     NAME      DRIVER    SCOPE
43ba4a7c0f8f   host      host      local

5、查看网络详细信息

docker network inspect [OPTIONS] NETWORK [NETWORK...]

该命令用于查看一个网络的详细信息

选项 含义
-f, –format string 使用Go模板打印出指定格式的输出信息
-v, –verbose 输出调试信息

例:

root@cp:~# docker network inspect test
[
    {
        "Name": "test",
        "Id": "ca4631b94e5aacff7b2f5e9666e40aa1f5da8eae6a248df228916c39a5b63d75",
        "Created": "2021-01-17T16:30:13.752450389+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.1.0/24",
                    "Gateway": "192.168.1.1"
                }
            ]
        },
......

使用 -f 查询 test 网络的指定信息。

root@cp:~# docker network inspect -f '{{.Name}}' test
test
root@cp:~# docker network inspect -f '{{.IPAM.Config}}' test
[{192.168.1.0/24  192.168.1.1 map[]}]
root@cp:~# docker network inspect -f '{{json .IPAM.Config}}' test | python -m json.tool
[
    {
        "Gateway": "192.168.1.1",
        "Subnet": "192.168.1.0/24"
    }
]

6、清理无用网络

docker network prune [OPTIONS]

该命令用于清除没有容器使用的网络。

选项 含义
–filter filter 根据过滤值清理无用网络
-f, –force 不要提示确认

7、删除网络

docker network rm NETWORK [NETWORK…]

该命令用于删除指定网络,当网络没有容器连接时,才能被成功删除,不然会报错。
例:

root@cp:~# docker network rm test
test
root@cp:~# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
559b98272716   bridge    bridge    local
43ba4a7c0f8f   host      host      local
bd89dc2f3ffa   none      null      local

参考书籍:《Docker技术入门与实战》 作者: 杨保华 / 戴王剑 / 曹亚仑

Like
Like Love Haha Wow Sad Angry