docker 网络
1.Docker网络类型
安装Docker时,它会自动创建三个网络,bridge(创建容器默认连接到此网络)、 none 、host。
使用命令查看当前Docker所有的网络模式。
[root@VM-4-13-centos ~]# docker network ls #查看docker网络列表 NETWORK ID NAME DRIVER SCOPE 3f4b3d7cf8c3 bridge bridge local cd78b77fae62 host host local e383fbb889d2 none null local
2.Docker网络实现原理
Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的 Container-IP 直接通信。
Docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法直接通过 Container-IP 访问到容器。如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射),即 docker run 创建容器时候通过 -p 或 -P 参数来启用,访问容器的时候就通过[宿主机IP]:[容器端口]访问容器
3.Docker 网络模式
Host:容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
Container:创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围。
None:该模式关闭了容器的网络功能。
Bridge:默认为该模式,此模式会为每一个容器分配、设置IP等,并将容器连接到一个docker0虚拟网桥,通过docker0网桥以及iptables nat 表配置与宿主机通信。
自定义网络
使用docker run创建Docker容器时,可以用 --net 或 --network 选项指定容器的网络模式
模式 | 说明 |
---|---|
host模式 | 使用 --net=host 指定。 |
none模式 | 使用 --net=none 指定。 |
container模式 | 使用 --net=container:NAME_or_ID 指定。 |
bridge模式 | 使用 --net=bridge 指定,默认设置,可省略。 |
4.网络模式的详解
4.1.1 使用host模式
如果启动容器时使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。
使用host模式的容器可以直接使用宿主机的IP地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,host最大的优势就是网络性能比较好,但是docker host上已经使用的端口就不能再用了,网络的隔离性不好。
注:
Namespace的简要说明:
Docker使用了Linux的Namespaces技术来进行资源隔离,如PID Namespace隔离进程,Mount Namespace隔离文件系统,Network Namespace隔离网络等。
一个Network Namespace提供了一份独立的网络环境,包括网卡、路由、Iptable规则等都与其他的NetworkNamespace隔离。一个Docker容器一般会分配一个独立的Network Namespace。
Remove network isolation between container and host
Only one container (or application on the host) can use a port at the same time
Useful for specific applications, such as management container that you want to run on every host
4.1.2 docker network inspect host
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
[root@VM-4-13-centos soft]# docker network inspect host [ { "Name": "host", "Id": "cd78b77fae62da84a3bd0fb76a742e407f1d8d5f77dbb400fa8981fe79dedff9", "Created": "2022-10-24T09:24:34.551747569+08:00", "Scope": "local", "Driver": "host", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "718d9625068ed9c7d7edc5e0aec2b85c41576cad020c017d3124570ab5e8aa8b": { "Name": "redis", "EndpointID": "83425bb2c17ae19d759dcf108b7c1e21b256424c2fb92354dcca057aeafab6e6", "MacAddress": "", "IPv4Address": "", "IPv6Address": "" }, "e646ce78f95d4a483553f7462a7c6fc3c913cfba6b23ce3911937be80dec8ac8": { "Name": "nginx", "EndpointID": "c0a8fa93d811356e5061df7bf2da2cd62170dd05a0f04ae7fcf9c8c60abf9cd1", "MacAddress": "", "IPv4Address": "", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ]
4.2 container模式
Docker中一种较为特别的网络模式,主要用于容器和容器直接频繁交流的情况。
特点:
- 该模式指定新建的容器和现有的一个容器共享网络名称空间。
- 新创建的容器和一个现有的指定容器共享IP地址、端口范围,不创建自己的网络接口、IP地址。
- 两个容器间网络不隔离,进程可通过回环网络进行通信。
- 这两个容器和主机和其他容器存在网络隔离。
4.2.1 创建
docker run -d --name tomcat02-mongo --net=container:共享的容器名或容器id \
mongo:latest
4.3 none模式
none模式将容器放置在它自己的网络栈中,但是并不进行任何配置,实际上关闭了容器的网络功能。 特性:none模式,容器有自己的网络名称空间,但未进行任何网络配置,未构建任何网络环境,容器内部只能使用回环网络接口(127.0.0.1)。 可用场景: 有些容器并不需要网络,例如只需要写入磁盘卷的批处理任务。 安全性要求高并且不需要联网的应用可以使用none模式。 要创建自定义网络。
4.3 使用bridge模式(创建容器默认连接到此网络)
4.3.1 守护进程 dockerd:
创建虚拟网桥 docker0,新建的容器会自动桥接到该接口下,附加在其上的任何网卡之间都能自动转发数据包。
创建一对虚拟设备接口 veth pair,将其中一个接口设置为容器的 eth0 接口(容器网卡),另一个接口放置在宿主机命名空间中,以 vethxxx 这样的名字命名,宿主机上的所有容器都连接到这个内部网络上
分配一个和网桥 docker0在同网段的IP地址给容器,并设置 docker0 的 IP 地址为容器的默认网关
使用 docker run -p 时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL 查看。
4.3.2 docker network inspect bridge
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
[root@VM-4-13-centos soft]# docker network inspect bridge [ { "Name": "bridge", "Id": "3f4b3d7cf8c3c2c5bde91f00c598fd6fd500c8027c86fe3d803c47ab0c4198e8", "Created": "2022-11-17T17:56:43.400271744+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [ { "Subnet": "172.17.0.0/16", "Gateway": "172.17.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "37d97db4d108b67c16749782be634621d628679f85001c39ce53130b9d8cc8c7": { "Name": "tomcat03", "EndpointID": "f5fa5eb681931d54095938c242fa84857cc9eb4815e338e92846374e3ac0747e", "MacAddress": "02:42:ac:11:00:03", "IPv4Address": "172.17.0.3/16", "IPv6Address": "" }, "503cca4393fae33d760d85b1b85b25156c23d415e6b89a0e7f0fd0aa210f3b37": { "Name": "tomcat02", "EndpointID": "92b1e3ea396d50b64b6eaef41f4a0990530114b2ce5f5d3fc8129fe65b6b885a", "MacAddress": "02:42:ac:11:00:04", "IPv4Address": "172.17.0.4/16", "IPv6Address": "" }, "c098ca1bb4210068bb685fa79ab055971dc89df3c326b5bde77a32074cef37f2": { "Name": "portainer", "EndpointID": "7cf1020684671f4a7e018c8a8a65a050371f48eec6b7a815cbcfa2948b68ca08", "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.2/16", "IPv6Address": "" } }, "Options": { "com.docker.network.bridge.default_bridge": "true", "com.docker.network.bridge.enable_icc": "true", "com.docker.network.bridge.enable_ip_masquerade": "true", "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0", "com.docker.network.bridge.name": "docker0", "com.docker.network.driver.mtu": "1500" }, "Labels": {} } ]