docker容器的网络

166 阅读3分钟

docker容器和宿主机、容器与容器之间网络是互通的, 下面我们通过以下的例子来验证.

创建两个容器, 分别是box1和box2

# 拉取busybox镜像
docker image pull busybox

# 根据busybox镜像创建box1容器和box2容器
docker container run -d --rm --name box1 busybox /bin/sh -c "while true; do sleep 3600; done"

docker container run -d --rm --name box2 busybox /bin/sh -c "while true; do sleep 3600; done"

进入其中一个容器box1

docker container exec -it box1 sh

# 使用 ip addr查看容器的ip地址
ip addr

18: eth0@if19: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

可以看出box1 容器的ip 地址是 172.17.0.3

我们可以尝试ping 一下宿主机的ip

ping 172.19.10.234

PING 172.19.10.234 (172.19.10.234): 56 data bytes
64 bytes from 172.19.10.234: seq=0 ttl=64 time=0.115 ms
64 bytes from 172.19.10.234: seq=1 ttl=64 time=0.103 ms
64 bytes from 172.19.10.234: seq=2 ttl=64 time=0.097 ms
64 bytes from 172.19.10.234: seq=3 ttl=64 time=0.092 m

我们发现box1 是可以ping 通宿主机的.

我们退出到宿主机, 尝试ping 一下 box1.

ping 172.17.0.3

PING 172.17.0.3 (172.17.0.3) 56(84) bytes of data.
64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.064 ms
64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.067 ms
64 bytes from 172.17.0.3: icmp_seq=3 ttl=64 time=0.059 ms

发现也是可以 ping 通的, 这说明宿主机和容器之间的网络是互通的.

我们尝试 ping 一下容器与容器的网络

进入box2 容器, 在box2 容器里ping 一下box1 的ip

docker container exec -it box2 sh

ping 172.17.0.3

PING 172.17.0.3 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.130 ms
64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.104 ms
64 bytes from 172.17.0.3: seq=2 ttl=64 time=0.101 ms

可以看出box2 是可以ping 通 box1 的

通过上面的例子可以看出, 宿主机容器之间网络是可以互通的.

创建和使用自定义bridge

在Docker中,"bridge"是一种网络模式,用于在Docker容器和主机之间创建一个虚拟网络桥接

    1. 创建自定义的bridge
docker network create -d mybridge

docker network ls

NETWORK ID     NAME       DRIVER    SCOPE
b3fd39a8bbdb   bridge     bridge    local
818738fdaee6   host       host      local
29adfe15e23f   mybridge   bridge    local
e377484c3bd1   none       null      local

创建后使用 network ls 可以到我们新增的mybridge 已经在列表里.

使用 inspect 查看 mybridge

docker network inspect mybridge

"IPAM": {
    "Driver": "default",
    "Options": {},
    "Config": [
        {
            "Subnet": "172.18.0.0/16",
            "Gateway": "172.18.0.1"
        }
    ]
}

可以看出mydridge 的子网是 172.18.0.0/16 , 也就是一个容器说连接到 mybridg, 会给这个容器分配一个 172.18 网段的 ip 地址.

    1. 使用自定义的bridge

默认情况下, 容器会链接docker0. 可以使用 container inspect查看

docker container inspect box2

可以在创建容器的时候指定要连接到的bridge

docker container run -d --rm --name box3 --network mybridge busybox /bin/sh -c "while true; do sleep 3600; done"

也可以使用 network connect 命令来连接

docker network connect mybridge box3

一个容器如何同时连两个网络

使用命令 container inspect box1, 我们可以看出box1 容器连了两个网络

docker container inspect box1

"Networks": {
    "bridge": {
        "Gateway": "172.17.0.1",
        "IPAddress": "172.17.0.3"
    },
    "mybridge": {
        "Gateway": "172.18.0.1",
        "IPAddress": "172.18.0.2"
    }
}

进入box1 容器也可以看出, box1使用了两个网络

docker container exec -it box1 sh
ip a

89: eth0@if90: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
93: eth1@if94: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
    link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.2/16 brd 172.18.255.255 scope global eth1
       valid_lft forever preferred_lft forever

连接到自定义的bridge, 可以使用容器名 ping 通, 但是连接到bridge, 不能使用容器名 ping 通

现在box1 和 box3 已经连接到了mybridge, 我们可以尝试ping 一下

docker container exec -it box1 ping box3

PING box3 (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.174 ms
64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.076 ms
64 bytes from 172.18.0.3: seq=2 ttl=64 time=0.063 ms
64 bytes from 172.18.0.3: seq=3 ttl=64 time=0.073 ms

可以看出, 直接使用容器名是可以 ping 通的. 但是如果 ping 连接到默认bridge的容器名, 是ping 不通的.

docker container exec -it box1 ping box2

ping: bad address 'box2'