目录
1.docker 网络
编辑
2.none 网络
3.host 网络
4.bridge 网络
5.自定义网络
1.docker network create
2.docker network inspect
3.docker 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: 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: 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: 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: 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: 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: 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 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
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
除了none,host,bridge这三个自动创建的网络,用户也可以根据业务需要创建user-defined网络。
格式:
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: 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: 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
显示一个或多个网络的详细信息
格式:
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": {}
}
]
将容器连接到网络
格式:
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: 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: 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: 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
1.外部访问容器
网卡改为host模式
2.不同网段容器之间如何访问
为容器添加双网卡