docker容器网络
docker的四种网络模式
基于docker run创建容器时,可以使用--net选项指定容器的网络模式:Docker默认有以下4种网络模式:
- bridge模式,使用--net=bridge指定,默认设置
- host模式,使用--net=host指定
- none模式,使用--net=none指定
- container模式,使用--net=container:NAME_or_ID指定
常用的是bridge模式和host模式
bridge模式网络拓扑图如下:
docker bridge网络模式会为每个容器分配地址,当docker启动时会自动创建一个docker0的网卡,它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和宿主机都放到同一个二层网络。
网桥工作在二层(OSI堆栈),是通用网络设备的一种,可以设置IP地址。有了IP地址,Linux便可通过路由表或IP表,在网络层定位网桥,这就相当于有了一个虚拟网卡,即docker0。
1 2 3 4 5 6 7 | [root@node1 ~] # ip a show docker0 3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link /ether 02:42:78:8c:4b:0c 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:78ff:fe8c:4b0c /64 scope link valid_lft forever preferred_lft forever |
当docker容器启动时会在宿主机上创建一对虚拟网卡veth pair设备。veth pair设备总是成对出现的,它们组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来。因此,veth pair设备会连接容器和docker0网桥。
在容器启动时,Docker引擎将veth pair设备的一端放在新创建的容器中,并命名为eth0。另一端放在宿主机中,以veth***这样类似的名字命名,并将这个网络设备加入到docker0网桥中,可以通过bridge link命令查看。
从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。
查看docker的网络模式
docker network ls
1 2 3 4 5 | [root@node1 ~] # docker network ls NETWORK ID NAME DRIVER SCOPE 27658af758a0 bridge bridge local 6fb339ac4884 host host local cabb999b64f2 none null local |
查看连接到bridge网桥的容器信息
docker network inspect bridge
[root@node1 ~]# docker network inspect bridge [ { "Name": "bridge", "Id": "27658af758a0f0636924199eb34cc9893833bb185ff48f654618c2c778906f61", "Created": "2021-10-20T21:28:08.694911039+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": { "b713aabd323d03a2d158dacdad210a13335e35c81f73fa63347d073b964dcc41": { "Name": "dazzling_raman", "EndpointID": "7bfb04c7f54eb298a7e8ee47a1c7f8f1adc2a63628d04b40dfba9e017c3134bd", "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": {} } ]
总结:docker的bridge网络模式采用的是linux bridge,veth pair ,iptables
docker的host网络模式
host模式网络拓扑如下:
docker的host网络模式其实就是容器和主机host共享一个网络,容器完全使用主机的网络,不对网络容器做任何隔离,优点是性能好,缺点是容器网络缺少隔离性,增加风险,由于容器和宿主机使用同一网络,当宿主机容器多时,网络资源会受到限制。
运行一个容器时使用--network host可以指定网络模式,默认是bridge模式。
1 2 | [root@node1 ~] # docker run -dt --name centos1 --network host centos 329d642084839644edee52d9cfcf9e0e3401d27715e03ab116ff6ff809c813d1 |
当我们进入容器后使用ip a 查看网卡信息的时候跟宿主机是一样的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | [root@node1 ~] # docker exec -it centos1 bash [root@node1 /] # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 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 state UP group default qlen 1000 link /ether 00:0c:29:ea:64:2c brd ff:ff:ff:ff:ff:ff inet 192.168.41.140 /24 brd 192.168.41.255 scope global dynamic noprefixroute ens33 valid_lft 1278sec preferred_lft 1278sec inet6 fe80::5451:a974:cdec:42fa /64 scope link noprefixroute valid_lft forever preferred_lft forever 3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link /ether 02:42:78:8c:4b:0c 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:78ff:fe8c:4b0c /64 scope link valid_lft forever preferred_lft forever 21: veth3a1fcf0@if20: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link /ether 02:b0:f3:7d:59:58 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet6 fe80::b0:f3ff:fe7d:5958 /64 scope link valid_lft forever preferred_lft forever |
docker的none网络模式
docker的none网络模式会使容器禁用网络功能,只保留一个回环网卡。none模式不参与网络配置,如果想针对none模式做网络配置,需要第三方的服务。none模式使容器不再局限于docker自带的网络模式。
创建一个容器指定网络模式是none
1 2 | [root@node1 ~] # docker run -dt --name centos2 --network none centos ec1ff13482af75689039dbc8d02678c4bf38c8dceb298f5f6f37e8932eda8650 |
进入容器查看网卡信息,只有一个lo网卡
1 2 3 4 5 6 7 | [root@node1 ~] # docker exec -it centos2 bash [root@ec1ff13482af /] # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 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 [root@ec1ff13482af /] # |
docker的container模式
container模式网络拓扑图如下:
docker的container模式就是在容器创建时指定另一个容器,与它共享一个网络
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | [root@node1 ~] # docker run -dt --name centos3 --network container:centos1 centos 4a32d8865bcb570dad5f448f536acb47103e288466d3b8d33fd317c128e42e0b [root@node1 ~] # docker exec -it centos3 ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 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 state UP group default qlen 1000 link /ether 00:0c:29:ea:64:2c brd ff:ff:ff:ff:ff:ff inet 192.168.41.140 /24 brd 192.168.41.255 scope global dynamic noprefixroute ens33 valid_lft 1538sec preferred_lft 1538sec inet6 fe80::5451:a974:cdec:42fa /64 scope link noprefixroute valid_lft forever preferred_lft forever 3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link /ether 02:42:78:8c:4b:0c 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:78ff:fe8c:4b0c /64 scope link valid_lft forever preferred_lft forever 21: veth3a1fcf0@if20: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link /ether 02:b0:f3:7d:59:58 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet6 fe80::b0:f3ff:fe7d:5958 /64 scope link valid_lft forever preferred_lft forever |
由于centos3与centos1共用一个网络,所以也是host模式
通过docker inspect centos1 | grep NetworkMode查看 centos1的网络模式是host,同样查看centos3的网络模式是container模式,但是指向的是centos1的容器ID,所以centos1与centos3共用一个网络。
docker的自定义网络和网络连接
docker network 命令用法
1 2 3 4 5 6 7 8 | Commands: connect Connect a container to a network #将容器连接到网络 create Create a network #创建一个网络 disconnect Disconnect a container from a network #断开容器与网络的连接 inspect Display detailed information on one or more networks #显示一个或多个网络的详细信息 ls List networks #列出网络 prune Remove all unused networks #删除所有未使用的网络 rm Remove one or more networks #删除一个或多个网络 |
创建一个网络
1 2 | [root@node1 ~] # docker network create -d bridge --subnet 192.168.0.1/16 --gateway 192.168.1.0 mybr 54d8d1e974d4a454a67026ead4a4e53f633b6c708df69f1a6cc859183fb0893e<br>解析:<br>-d;--driver bridge 表示使用桥接模式,默认是桥接模式,也可以设置其他模式<br>--subnet 192.168.1.0 /16 表示子网ip 可以分配 192.168.1.2 到 192.168.255.255 非必要指定,如不指定系统自动生成<br>--gateway 192.168.1.0 表示网关 非必要指定,同上<br>mybr 表示网络名 |
查看网络
1 2 3 4 5 6 | [root@node1 ~] # docker network ls NETWORK ID NAME DRIVER SCOPE 27658af758a0 bridge bridge local 6fb339ac4884 host host local 54d8d1e974d4 mybr bridge local cabb999b64f2 none null local |
查看自定义网络信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | [root@node1 ~] # docker network inspect mybr [ { "Name" : "mybr" , "Id" : "54d8d1e974d4a454a67026ead4a4e53f633b6c708df69f1a6cc859183fb0893e" , "Created" : "2021-10-21T23:16:48.884388011+08:00" , "Scope" : "local" , "Driver" : "bridge" , "EnableIPv6" : false , "IPAM" : { "Driver" : "default" , "Options" : {}, "Config" : [ { "Subnet" : "192.168.0.1/16" , #这个是我们自定义网络的IP "Gateway" : "192.168.1.0" } ] }, "Internal" : false , "Attachable" : false , "Ingress" : false , "ConfigFrom" : { "Network" : "" }, "ConfigOnly" : false , "Containers" : {}, "Options" : {}, "Labels" : {} } ] |
使用自定义网络中的网桥创建容器
1 2 | [root@node1 ~] # docker run -dt -P --name centos4 --net mybr centos 8c84d24b4a3493d8f6c68877a80e848ca57fc030637304fac4f05512aeae60da |
进入容器查看网卡信息
1 2 3 4 5 6 7 8 9 10 | [root@node1 ~] # docker exec -it centos4 bash [root@8c84d24b4a34 /] # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 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 27: eth0@if28: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link /ether 02:42:c0:a8:00:01 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 192.168.0.1 /16 brd 192.168.255.255 scope global eth0 valid_lft forever preferred_lft forever |
容器间网络连通
首先创建一个名为lizf的容器
1 2 | [root@node1 ~] # docker run -dt --name lizf centos bash f462aa750e0fa301afc711e19785ca700578fdf94966659d16580fe6976a9569 |
然后将lizf容器连接到mybr网桥上
1 | [root@node1 ~] # docker network connect mybr lizf |
然后查看mybr网桥的信息,发现lizf容器已经连接上了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | [root@node1 ~] # docker network inspect mybr [ { "Name" : "mybr" , "Id" : "54d8d1e974d4a454a67026ead4a4e53f633b6c708df69f1a6cc859183fb0893e" , "Created" : "2021-10-21T23:16:48.884388011+08:00" , "Scope" : "local" , "Driver" : "bridge" , "EnableIPv6" : false , "IPAM" : { "Driver" : "default" , "Options" : {}, "Config" : [ { "Subnet" : "192.168.0.1/16" , "Gateway" : "192.168.1.0" } ] }, "Internal" : false , "Attachable" : false , "Ingress" : false , "ConfigFrom" : { "Network" : "" }, "ConfigOnly" : false , "Containers" : { "8c84d24b4a3493d8f6c68877a80e848ca57fc030637304fac4f05512aeae60da" : { "Name" : "centos4" , "EndpointID" : "73dccbaf3dc6a9f24d8d7d930a26ebb3629184cd7bbbb5553f4331ac7759ec0d" , "MacAddress" : "02:42:c0:a8:00:01" , "IPv4Address" : "192.168.0.1/16" , "IPv6Address" : "" }, "f462aa750e0fa301afc711e19785ca700578fdf94966659d16580fe6976a9569" : { "Name" : "lizf" , "EndpointID" : "2462af6ff408950ec0dbeb2d902987a9b2bb8b6b660dcb74da1918adb075692c" , "MacAddress" : "02:42:c0:a8:00:02" , "IPv4Address" : "192.168.0.2/16" , "IPv6Address" : "" } }, "Options" : {}, "Labels" : {} } ] |
目前centos4和lizf这两个容器都连接到了mybr这个网桥上了,可以实现网络间的互通,登陆centos4容器ping一下lizf
1 2 3 4 5 6 7 8 | [root@node1 ~] # docker exec -it centos4 ping -c 2 lizf PING lizf (192.168.0.2) 56(84) bytes of data. 64 bytes from lizf.mybr (192.168.0.2): icmp_seq=1 ttl=64 time =0.277 ms 64 bytes from lizf.mybr (192.168.0.2): icmp_seq=2 ttl=64 time =0.097 ms --- lizf ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1001ms rtt min /avg/max/mdev = 0.097 /0 .187 /0 .277 /0 .090 ms |
将lizf这个容器从mybr网桥上断开
docker network disconnect mybr lizf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | [root@node1 ~] # docker network disconnect mybr lizf [root@node1 ~] # docker network inspect mybr [ { "Name" : "mybr" , "Id" : "54d8d1e974d4a454a67026ead4a4e53f633b6c708df69f1a6cc859183fb0893e" , "Created" : "2021-10-21T23:16:48.884388011+08:00" , "Scope" : "local" , "Driver" : "bridge" , "EnableIPv6" : false , "IPAM" : { "Driver" : "default" , "Options" : {}, "Config" : [ { "Subnet" : "192.168.0.1/16" , "Gateway" : "192.168.1.0" } ] }, "Internal" : false , "Attachable" : false , "Ingress" : false , "ConfigFrom" : { "Network" : "" }, "ConfigOnly" : false , "Containers" : { "8c84d24b4a3493d8f6c68877a80e848ca57fc030637304fac4f05512aeae60da" : { "Name" : "centos4" , "EndpointID" : "73dccbaf3dc6a9f24d8d7d930a26ebb3629184cd7bbbb5553f4331ac7759ec0d" , "MacAddress" : "02:42:c0:a8:00:01" , "IPv4Address" : "192.168.0.1/16" , "IPv6Address" : "" } }, "Options" : {}, "Labels" : {} } ] |
此时容器lizf已经从mybr网桥断开了
端口映射(容器可以被外部访问)
这里要注意的一点是,如果是nat网桥必须开启核心转发功能
[root@jiaqi211 ~]# cat /proc/sys/net/ipv4/ip_forward 1
第一种 随机映射
docker run -p PORT
示例,我们把容器的80端口随机映射到宿主机上,我们可以看到映射到的宿主机端口为32769
[root@jiaqi211 ~]# docker run --name mynginx -p 80 -itd --rm nginx 5bea3c77aaee1c4a3d7e7617838697a3745b9ae3e74e7088e30ad86fe7cdbecc
[root@jiaqi211 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5bea3c77aaee nginx "nginx -g 'daemon of…" 4 seconds ago Up 3 seconds 0.0.0.0:32769->80/tcp mynginx
我们来验证一下,打开浏览器HOST:PORT
第二种 指定映射
-p hostPort:containerPort -p ip:hostPort:containerPort -p ip::containerPort -p hostPort
我们也可以指定映射,比如,映射宿主机的80端口对应容器的80端口
[root@jiaqi211 ~]# docker run --name mynginx -p 80:80 -itd nginx 2326a68c58546ec19c4c5c971662f45d5166cb13bbc56f11d849f146fba6f473 [root@jiaqi211 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2326a68c5854 nginx "nginx -g 'daemon of…" About a minute ago Up About a minute 0.0.0.0:80->80/tcp mynginx
验证
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」