1.docker 网络
当项目大规模使用 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虚拟网桥,默认为该模式 |
自定义网络 | 根据个人需要进行创建网络 |
2.none 网络
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网络中,避免密码被窃取等。
3.host 网络
采用 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端口。
4.bridge 网络
在该模式中,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网络。
1.docker network create
格式:
docker network create [OPTIONS] NETWORK
选项:
1. --driver,-d:驱动程序管理网络,选项网络类型 2. --gateway:主子网的IPv4或IPv6网关 3. --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
2.docker 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": {} } ]
3.docker 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
4.docker 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.不同网段容器之间如何访问
为容器添加双网卡