Docker---网络模式详解与用户自定义网络使用

Docker---网络模式详解与用户自定义网络使用目录 一 docker 网络实现原理 二 docker 的四类网络模式 三 docker 用户自定义网络使用命令 一 docker 网络实现原理 虚拟机平台的网卡分析 我们使用 ifconfig 命令查看安装 docker ce 的虚拟机平台有 如下信息 root localhost ifconfig docker0

大家好,我是讯享网,很高兴认识大家。

目录

 

一.docker网络实现原理

二.docker的四类网络模式

三.docker用户自定义网络使用命令


一.docker网络实现原理

虚拟机平台的网卡分析

  • 我们使用ifconfig命令查看安装docker-ce的虚拟机平台有,如下信息
[root@localhost ~]# ifconfig docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 172.18.0.1 netmask 255.255.0.0 broadcast 172.18.255.255 ether 02:42:24:fe:93:22 txqueuelen 0 (Ethernet) RX packets 2652 bytes  (136.6 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 3407 bytes  (14.4 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.43.101 netmask 255.255.255.0 broadcast 192.168.43.255 inet6 fe80::ba30:ef5e:b59f:4f1c prefixlen 64 scopeid 0x20<link> ether 00:0c:29:ce:5f:24 txqueuelen 1000 (Ethernet) RX packets 45 bytes 5797 (5.6 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 92 bytes 12139 (11.8 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1 (Local Loopback) RX packets 68 bytes 5916 (5.7 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 68 bytes 5916 (5.7 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 virbr0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 192.168.122.1 netmask 255.255.255.0 broadcast 192.168.122.255 ether 52:54:00:7a:bf:df txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 [root@localhost ~]# 

讯享网
  • 其中eth0是真实存在的适配器,用来连接物理机网卡;
  • 而lo则是虚拟出来的回环网卡,用来检测tcp/ip协议是否生效;
  • 对于virbr0虚拟桥接网卡,linux自身集成了一个虚拟化功能,被镶嵌在内核当中

docker0网桥分析

  • docker使用linux桥接,在宿主机虚拟一个容器网——docker 0,Docker启动一个容器时会根据docker网桥的网段分配给容器一个IP地址,称为Container-IP。
  • 同时Docker网桥也是每个容器的默认网关。因为在同一个宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的container-IP直接通信。
  • Docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,意味着外部网络无法直接通过Container-IP访问到容器。如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射)。

虚拟机平台容器网络架构图


讯享网

  • 启动docker 0和ens33之间通过NAT地址转换技术,使得后面的容器IP映射到ens33的地址,再通过不同的端口映射区分不同的容器。

二.docker的四类网络模式

  • 安装docker时,docker会自动创建三个网络,bridge(bridge创建容器默认连接到此网络)、none、host
讯享网[root@cloud ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 9c7af129bb18 bridge bridge local 6679de44fc2e host host local b1e4b6deb58f none null local [root@cloud ~]# 

host模式

  • 如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network NameSpace,而是和宿主机共用一个Network NameSpace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,比如文件系统、进程列表等还是和宿主机隔离的。
  • 使用host模式的容器可以直接使用宿主机的IP地址与外界通信,容器内部的服务端口可以使用宿主机的端口,不需要要进行NAT,Host的最大的优势就是网络性能比较好,但是docker host上已经使用的端口,就不能再用了,网络的隔离性不好。

container模式

  • container模式指定新创建的容器和已经存在的容器共享一个Network NameSpace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP地址,而是和指定的一个容器共享IP地址、端口范围。同样,两个容器除了网络方面,其他如文件系统,进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。

none模式

  • 使用none模式,docker容器拥有自己的network namesapce,但是,并不为docker容器进行任何网络配置。也就是说,这个docker容器没有网卡、Ip、路由等信息。需要我们自己为docker容器添加网卡、配置IP地址等
  • 在none模式下容器只有lo回环网络,没有其他网卡。none模式可以在容器创建时通过 --network=none来指定。这种网络没有办法联网。封闭的网络能够很好的保证容器的安全性。

 

bridge模式

  • 当docker进程启动时,会在主机上创建一个名为docker 0的虚拟网桥,此主机上启动的docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就可以通过交换机连在一个二层网络中。
  • 从docker 0子网中分配一个给容器使用,并且设置docker 0的IP地址位容器的默认网关。在主机上创建一对虚拟网卡veth pair设备,docker将veth pair设备的一端放在新创建的容器中,并且命名为eth0(容器的网卡),另外一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker 0网桥中。可以通过brctl show命令查看。
  • bridge模式是docker的默认网络模式。不写--net参数,就是bridge模式。使用docker run -p时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL 查看。

 

当我们使用多个node时,我们可以使用k8s,进行多节点容器管理

上述四种网络模式的配置说明

docker网络模式 配置 说明
host模式 -net=host 容器和宿主机共享network namespace
container模式 -net=container:NAME_or_ID 容器和另外一个容器共享Network namespace。kubernetes中的pod就是多个容器共享一个network namespace
none模式 -net=none 容器有独立的network namespace,但是并没有对其进行任何网络设置,如分配veth pair和网桥连接,配置IP等
bridge模式 -net=bridge (默认为该模式)

三.docker用户自定义网络使用命令

自定义网络

  • 除了默认的名为docker 0的bridge网络,还可以创建自己的bridge网络或overlay网络。
  • bridge网络用于在本机内容器之间的互通
  • overlay网络用于不同主机内容的容器之间的互通
  • 本文主要对bridge网络说明,overlay网络在搭建k8s管理多节点时会详细说明

注:当我们使用如下命令,创建一个bridge网络下的指定IP地址的容器时,会发现使用bridge无法支持指定IP

docker run -itd --name test1 --network bridge --ip 172.17.0.10 centos:7 /bin/bash

  • 一个bridge类型的网络
[root@cloud ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 9c7af129bb18 bridge bridge local 6679de44fc2e host host local b1e4b6deb58f none null local [root@cloud ~]# docker network create -d bridge my-net ae3d32337feb2daea7c51ba43c946ef041af594d66265a8 [root@cloud ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 9c7af129bb18 bridge bridge local 6679de44fc2e host host local ae3d32337feb my-net bridge local b1e4b6deb58f none null local [root@cloud ~]# docker network ls列出docker的网络类型 docker network create -d指定要创建什么类型的网络 ,后面在加自定义的网络名称 假如不使用-d参数,会创建bridge网络 docker network create -d bridge my-net 等同于 docker network create my-net
  • 查看自定义网络的源数据
讯享网[root@cloud ~]# docker network inspect my-net 使用inspect查看详细信息 [ { "Name": "my-net", "Id": "ae3d32337feb2daea7c51ba43c946ef041af594d66265a8", "Created": "2020-04-16T09:42:28.+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.19.0.0/16", 此处docker为该网卡分配了一个子网 "Gateway": "172.19.0.1" 定义了网关 } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": {}, "Options": {}, "Labels": {} } ] [root@cloud ~]# 
  • 创建一个bridge网络并且指定子网
创建一个bridge类型的网络,定义子网段,定义网络名称 [root@cloud ~]# docker network create --subnet=172.20.0.0/16 my-net_172_20 cd3c2d0fcfde4abbffcfec9265abc5ed3894a033b20828addc6d7af [root@cloud ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 9c7af129bb18 bridge bridge local 6679de44fc2e host host local ae3d32337feb my-net bridge local cd3c2d0fcfde my-net_172_20 bridge local b1e4b6deb58f none null local 查看该网络的源信息 [root@cloud ~]# docker network inspect my-net_172_20 [ { "Name": "my-net_172_20", "Id": "cd3c2d0fcfde4abbffcfec9265abc5ed3894a033b20828addc6d7af", "Created": "2020-04-16T09:49:08.+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.20.0.0/16" 子网段成功设置 } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": {}, "Options": {}, "Labels": {} } ] [root@cloud ~]# 
  • 创建一个网络时,可以使用--label添加元数据
讯享网#在创建一个网络时使用--label,为此网络指定一些元数据信息 #如下 [root@cloud ~]# docker network create \ > --label network_name=my-net_label \ 指定网络名称元数据 > --label project=LB_nginx \ 指定项目名称元数据 > my-net_label 1db0bc5d23308fa582dea32c044ec910e23e5f6c7012dd9a51751dd1a0ef3e5d [root@cloud ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 9c7af129bb18 bridge bridge local 6679de44fc2e host host local ae3d32337feb my-net bridge local cd3c2d0fcfde my-net_172_20 bridge local 1db0bc5d2330 my-net_label bridge local b1e4b6deb58f none null local [root@cloud ~]# docker network inspect my-net_label [ { "Name": "my-net_label", "Id": "1db0bc5d23308fa582dea32c044ec910e23e5f6c7012dd9a51751dd1a0ef3e5d", "Created": "2020-04-16T09:57:10.+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.21.0.0/16", "Gateway": "172.21.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": {}, "Options": {}, "Labels": { 此处是我们指定label信息 "network_name": "my-net_label", "project": "LB_nginx" } } ] [root@cloud ~]# 
  • 删除自定网络
[root@cloud ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 9c7af129bb18 bridge bridge local 6679de44fc2e host host local ae3d32337feb my-net bridge local cd3c2d0fcfde my-net_172_20 bridge local 1db0bc5d2330 my-net_label bridge local b1e4b6deb58f none null local [root@cloud ~]# docker network rm my-net 使用docker network rm + 自定义网络名称删除 my-net [root@cloud ~]# docker network rm my-net_172_20 my-net_172_20 [root@cloud ~]# docker network rm my-net_label my-net_label [root@cloud ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 9c7af129bb18 bridge bridge local 6679de44fc2e host host local b1e4b6deb58f none null local [root@cloud ~]# 

定义容器网络并且通信

  • 我们可以将现有的容器连接到一个或者多个网络。容器可以连接到使用不同网络驱动程序的网络,比如连接到bridge网络或者overlay网络。连接后,容器可以使用其他容器的IP地址或名称进行通信。

上图中表明的意思是,在一台docker主机docker host上有三个容器,且三个容器分别连接到两个不同的网络中

容器container1连接到默认的桥接网络bridge

容器container2连接到默认的网络的bridge,同时它还连接到自定义的桥接网络my-net中

容器container3连接到自定义的桥接网络my-net中

  • 先创建并且运行两个容器container1和container2
讯享网[root@cloud ~]# docker run -itd --name=container1 centos:7 b14be84a6307e1e539d1c1f9d7c10c8cc7a01ebe3228d27388d4bd3732 [root@cloud ~]# docker run -itd --name=container2 centos:7 52c71b93d4cc6a2f5898ba5becf0bdd79e2198b563b52273ee44031c4 [root@cloud ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 52c71b93d4cc centos:7 "/bin/bash" 4 seconds ago Up 3 seconds container2 b14be8 centos:7 "/bin/bash" 12 seconds ago Up 11 seconds container1 [root@cloud ~]# 
  • 创建一个隔离的桥接网络my-net
[root@cloud ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 9c7af129bb18 bridge bridge local 6679de44fc2e host host local b1e4b6deb58f none null local //--subnet指定子网 [root@cloud ~]# docker network create -d bridge --subnet 172.20.0.0/16 my-net 7b4bef68576ca21991dfb132a96c8db458beaeb84a7fa084b5fe88055aa90644 [root@cloud ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 9c7af129bb18 bridge bridge local 6679de44fc2e host host local 7b4bef68576c my-net bridge local b1e4b6deb58f none null local [root@cloud ~]# 
  • 将容器container2假如my-net网络中
讯享网使用connect连接网络 [root@cloud ~]# docker network connect my-net container2 [root@cloud ~]# docker network inspect my-net [ { "Name": "my-net", "Id": "7b4bef68576ca21991dfb132a96c8db458beaeb84a7fa084b5fe88055aa90644", "Created": "2020-04-16T11:03:46.+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.20.0.0/16" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "52c71b93d4cc6a2f5898ba5becf0bdd79e2198b563b52273ee44031c4": { "Name": "container2", 此处信息显示添加成功 "EndpointID": "f3d6b544d66216f1e914cffae302f895b8b816bc348fefbfe88bb6549e20d4d4", "MacAddress": "02:42:ac:14:00:02", "IPv4Address": "172.20.0.2/16", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ] [root@cloud ~]# 
  • 创建并且运行container3容器并且指定网络
[root@cloud ~]# docker run -itd --name=container3 --network=my-net --ip=172.20.0.100 centos:7 77565a1449d2095d75b0cb4aaaeeb99db58758c9e12 --network指定网络类型 --ip指定固定的IP地址
  • 进入container2容器查看网卡信息
讯享网[root@cloud ~]# docker exec -it container2 /bin/bash [root@52c71b93d4cc /]# yum install net-tools -y 下载网络命令工具 [root@52c71b93d4cc /]# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.18.0.3 netmask 255.255.0.0 broadcast 172.18.255.255 ether 02:42:ac:12:00:03 txqueuelen 0 (Ethernet) RX packets 6214 bytes  (14.6 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 4405 bytes  (295.3 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.20.0.2 netmask 255.255.0.0 broadcast 172.20.255.255 ether 02:42:ac:14:00:02 txqueuelen 0 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 loop txqueuelen 1000 (Local Loopback) RX packets 61 bytes 5883 (5.7 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 61 bytes 5883 (5.7 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 [root@52c71b93d4cc /]# 

在container2中可以看到eth0和eth1两张虚拟网卡信息

这是因为,我们一开始运行这个容器的时候,被连接到默认的网络上,后来我们又执行了 docker network connect 命令,把它连接到了 my-net 网络上了,所以这使其有两个网络,并且有两个网卡。

  • 容器间的通信
[root@cloud ~]# docker exec -it container1 /bin/bash [root@b14be8 /]# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.18.0.2 netmask 255.255.0.0 broadcast 172.18.255.255 ether 02:42:ac:12:00:02 txqueuelen 0 (Ethernet) RX packets 6816 bytes  (14.6 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 4508 bytes  (295.2 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 loop txqueuelen 1000 (Local Loopback) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 [root@b14be8 /]# ping 172.18.0.3 PING 172.18.0.3 (172.18.0.3) 56(84) bytes of data. 64 bytes from 172.18.0.3: icmp_seq=1 ttl=64 time=0.073 ms ^C --- 172.18.0.3 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.073/0.073/0.073/0.000 ms [root@b14be8 /]# ping 172.20.0.100 PING 172.20.0.100 (172.20.0.100) 56(84) bytes of data. ^C --- 172.20.0.100 ping statistics --- 7 packets transmitted, 0 received, 100% packet loss, time 5999ms [root@b14be8 /]# 

上面我们进入container1容器,container1可以ping通container2,但是ping不同container3。

因为 container3 和 container1 并没有任何共同的网络,所以他们是无法通信的。

  • 从网络中断开一个容器的连接
讯享网docker network disconnect 网络名 容器名

 

小讯
上一篇 2025-04-07 16:54
下一篇 2025-04-10 11:01

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/129190.html