一文秒会Docker网络(bridge,host,none)

时间:2024-11-09 21:16:26

 

目录

网络

​编辑

网络

网络

网络

5.自定义网络

network create

network inspect

network connect

6.真实环境实操


网络

当项目大规模使用 Docker 时,容器通信的问题也就产生了。要解决容器通信问题,必须先了解很多关于网络的知识。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker 同样有着很多不完善的地方,网络方面就是 Docker 比较薄弱的部分。因此,我们有必要深入了解 Docker 的网络知识,以满足更高的网络需求。

默认网络

安装 Docker 以后,会默认创建三种网络,可以通过 docker network ls 查看。

[root@localhost ~]# docker network ls
cNETWORK ID     NAME      DRIVER    SCOPE
b2d0689a7644   bridge    bridge    local
c598e7da9321   host      host      local
36391f761fe6   none      null      local
网络模式 简介
none 容器有独立的network namespace,但并没有对其进行任何网络设置,
host 容器将不会虚拟出自己的网卡,配置自动的IP等,而是使用宿主机的IP和端口
bridge 为每一个容器分配,设置IP等,并将容器连接一个docker0虚拟网桥,默认为该模式
自定义网络 根据个人需要进行创建网络

 

网络

none 网络模式是指禁用网络功能,只有 lo 接口 local 的简写,代表 127.0.0.1,即 localhost 本地环回接口。在创建容器时通过参数 --net none 或者 --network none 指定;

none网络就是什么都没有的网络,挂在这个网络下的容器除了lo,没有其他任何网卡了,是一个封闭的空间。

[root@localhost ~]# docker run -it --network=none busybox
/ # ls
bin   dev   etc   home  proc  root  sys   tmp   usr   var
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
    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

使用场景,一些对安全性要求高并且不需要联网的应用情况下可以使用none网络。比如某个容器的唯一用途是生成随机密码,就可以存放到none网络中,避免密码被窃取等。

网络

采用 host 网络模式的 Docker Container,可以直接使用宿主机的 IP 地址与外界进行通信,若宿主机的 eth0 是一个公有 IP,那么容器也拥有这个公有 IP。同时容器内服务的端口也可以使用宿主机的端口,无需额外进行 NAT 转换;

[root@localhost ~]# docker run -it --network host busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
    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
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 00:0c:29:10:b7:cb brd ff:ff:ff:ff:ff:ff
    inet 192.168.2.5/24 brd 192.168.2.255 scope global ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe10:b7cb/64 scope link
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue
    link/ether 02:42:48:47:28:8a brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:48ff:fe47:288a/64 scope link
       valid_lft forever preferred_lft forever

在容器中可以看到host的所有网卡,并且连hostname也是host的。host网络的使用场景又是什么呢? 直接使用docker host的网络最大的好处就是性能,如果容器对网络传输效率有较高要求,则可以选择host网络。当然不便之处就是牺牲一些灵活性,比如要考虑端口冲突问题,docker host 上已经使用的端口就不能再用了。

docker host的另一个用途是让容器可以直接配置host网络,比如某些跨host的网络解决方案,其本身也是以容器方式运行的,这些方案需要对网络进行配置,比如管理iptables。

下面我以nginx为例,来查看一些host网络的特性

[root@localhost ~]# docker run -it --network=host nginx

无需映射端口,就可以正常访问。

当然要关闭防火墙,或者开发80端口。

网络

在该模式中,Docker 守护进程创建了一个虚拟以太网桥 docker0,新建的容器会自动桥接到这个接口,附加在其上的任何网卡之间都能自动转发数据包。

docker安装时会创建一个命名为docker0的Linux bridge。如果不指定--network,创建的容器默认都会挂到docker0上。

[root@localhost ~]# brctl show
bridge name     bridge id               STP enabled     interfaces
docker0         8000.02424847288a       no

当前docker0上没有任何其他网络设备,我们创建一个容器看看变化

[root@localhost ~]# docker run -itd busybox
0fee2a50ff1136c302604c13b5b51a2b72d904268ff8d69df07a8d01a1c2c6a9
[root@localhost ~]# brctl show
bridge name     bridge id               STP enabled     interfaces
docker0         8000.02424847288a       no              vethe833331

一个新的网络接口vethe833331被挂载到了docker0上,vethe331aee3就是新创建容器的虚拟网卡

查看刚刚创建容器的网卡配置

[root@localhost ~]# docker exec -it 0fee2a50ff11 /bin/sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
    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
6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
/ # route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.17.0.1      0.0.0.0         UG    0      0        0 eth0
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 eth0

原来briage网络配置的subnet就是172.17.0.0/16,并且网关是172.17.0.1。这个网关就是docker0.

[root@localhost ~]# ifconfig docker0
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:48ff:fe47:288a  prefixlen 64  scopeid 0x20<link>
        ether 02:42:48:47:28:8a  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 5  bytes 438 (438.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

5.自定义网络

除了none,host,bridge这三个自动创建的网络,用户也可以根据业务需要创建user-defined网络。

network create

格式:

docker network create [OPTIONS] NETWORK

选项:

--driver,-d:驱动程序管理网络,选项网络类型
--gateway:主子网的IPv4或IPv6网关
--subnet:CIDR格式的子网,表示一个网段

创建一个192.168.8.0网段的网卡,网关为192.168.8.254

[root@localhost ~]# docker network create --driver bridge --gateway 192.168.8.254 --subnet 192.168.8.0/24 mynet1
37c8fcb1b7c93184f4efadac4cb849651b60738d1c3d667c3352a6e367a0a633
[root@localhost ~]# brctl show
bridge name     bridge id               STP enabled     interfaces
br-37c8fcb1b7c9         8000.024213041d24       no
docker0         8000.02424847288a       no              vethe833331
[root@localhost ~]# docker run -it --network mynet1 busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
    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
15: eth0@if16: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
    link/ether 02:42:c0:a8:08:01 brd ff:ff:ff:ff:ff:ff
    inet 192.168.8.1/24 brd 192.168.8.255 scope global eth0
       valid_lft forever preferred_lft forever
/ # route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.8.254   0.0.0.0         UG    0      0        0 eth0
192.168.8.0     0.0.0.0         255.255.255.0   U     0      0        0 eth0
network inspect

显示一个或多个网络的详细信息

格式:

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

选项:

--format,-f:自定义格式输出

查看刚刚创建网卡详细信息

[root@localhost ~]# docker network inspect mynet1
[
    {
        "Name": "mynet1",
        "Id": "37c8fcb1b7c93184f4efadac4cb849651b60738d1c3d667c3352a6e367a0a633",
        "Created": "2023-07-11T22:04:40.965301103+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.8.0/24",
                    "Gateway": "192.168.8.254"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]
network connect

将容器连接到网络

格式:

docker network connect [OPTIONS] NETWORK CONTAINER

创建一个网络,进行添加到容器中

[root@localhost ~]# docker network connect mynet02 041b95cd171e
[root@localhost ~]# docker exec -it 041b95cd171e /bin/sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
    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
20: eth0@if21: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
    link/ether 02:42:c0:a8:08:01 brd ff:ff:ff:ff:ff:ff
    inet 192.168.8.1/24 brd 192.168.8.255 scope global eth0
       valid_lft forever preferred_lft forever
22: eth1@if23: <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

network rm

移除一个或多个网络

格式:

docker network rm NETWORK [NETWORK...]

选项:

--force,-f:强制删除网络

删除刚刚创建的网络

[root@localhost ~]# docker network rm -f mynet1
mynet1
[root@localhost ~]# docker network rm -f mynet02
mynet02
[root@localhost ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
b2d0689a7644   bridge    bridge    local
c598e7da9321   host      host      local
36391f761fe6   none      null      local

6.真实环境实操

1.外部访问容器

网卡改为host模式

2.不同网段容器之间如何访问

为容器添加双网卡