什么是网桥
理解什么是网桥、路由,如何应用,了解docker的网络模型
1.网桥的创建
# 安装 bridge-utils 包,它包含了配置网桥所需的工具
$ yum install bridge-utils
# 创建网桥
# sudo brctl addbr <bridge-name>
$ sudo brctl addbr my-net
# 将物理接口添加到网桥中
# sudo brctl addif <bridge-name> <physical-interface>
$ sudo brctl addif my-net lo
# 将名为 "my-net" 的网络接口(network interface)启用(up)
# sudo ip link set dev <bridge-name> up
$ ip link set dev my-net up
# ifconfig 可以查看到 my-net 网桥
# 查看网桥的状态以及连接到网桥上的接口
$ brctl show
2.删除网桥
# 查看网桥
$ brctl show
# 停止网桥
# ifconfig <bridge-name> down
$ ifconfig my-net down
# 删除网桥
# brctl delbr <bridge-name>
$ brctl delbr my-netm
3.典型的网桥应用
- bridge模式下的docker,会创建虚拟网桥docker0;
- 给每个容器分配私有IP;
- 私有IP地址(通常是172.17.x.x)映射到宿主机的公共IP地址 -- 实现容器与宿主机之间通信;
- 容器会连接到该虚拟网桥docker0 -- 实现容器之间的通信;
Docker会创建一对veth设备,其中一个连接到容器,另一个连接到Docker宿主机的Linux桥接设备中了;
验证docker在bridge模式下:
# 安装docker
$ yum install -y docker
$ docker version
# 18.09.0
# 运行nginx服务
$ docker run --name nginx-test -d nginx
# 网络接口
$ ifconfig
docker0 # 虚拟网桥
enp1s0 # 物理网卡
lo # 环回网卡
veth71942f7 # veth71942f7是docker创建的虚拟网卡设备,用于容器与宿主机之间的通信
virbr0 # virbr0是libvirt创建的虚拟网桥设备,用于在虚拟机之间提供网络通信
# 所谓路由就是指示了各个ip下的数据包的走向,具体走向到哪个网卡由路由决定
[root@i-7B581709 ~]# ip route
# 默认路由,即所有未知目的地的数据包将通过enp1s0网卡发送到网关10.16.207.254上
default via 10.16.207.254 dev enp1s0 proto dhcp metric 100
# 子网路由,指示10.16.200.0/21的数据包将被发送到enp1s0网卡,源IP地址为10.16.203.189
10.16.200.0/21 dev enp1s0 proto kernel scope link src 10.16.203.189 metric 100
# 链接范围的本地路由,指示数据包将在enp1s0网卡上本地处理
# 169.254.0.0/16是私有IP地址范围,通常为本地网络自动配置保留
169.254.0.0/16 dev enp1s0 scope link
# 容器网络路由
# 指示所有172.17.0.0/16的数据包将被发送到docker0虚拟桥接口,并使用源IP地址172.17.0.1
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
# virbr0虚拟网桥的路由,该路由无效,因为该接口已经下线(linkdown),所以无法路由任何数据包
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown
# 查看容器网络地址
$ docker inspect nginx-test
`
[
{
"NetworkSettings": {
"Bridge": "",
"Ports": {
"80/tcp": null
},
"Gateway": "172.17.0.1", # 容器网关
"IPAddress": "172.17.0.2", # 容器IP地址
"IPPrefixLen": 16,
"MacAddress": "02:42:ac:11:00:02",
"Networks": {
"bridge": {
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"MacAddress": "02:42:ac:11:00:02",
}
}
}
}
]
`
#
# arp 找 mac 地址,然后icmp
$ ping 172.17.0.2
# 查看和管理网络设备的邻居表的命令
# 显示和管理 IPv4 和 IPv6 地址之间的转换、ARP 地址解析协议、NDP 邻居发现协议等内容
# 显示当前主机的网络路由表和 ARP 缓存表,包括 IP 地址到 MAC 地址的映射关系
$ ip n
172.17.0.2 dev docker0 lladdr 02:42:ac:11:00:02 STALE
10.16.207.254 dev enp1s0 lladdr 6c:e5:f7:6b:79:61 DELAY
169.254.169.254 dev enp1s0 lladdr fe:ff:ff:ff:ff:ff REACHABLE
# docker内部网络列表
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
71e49c08add7 bridge bridge local
ec4c0f0642bd host host local
0750ef78e913 none null local
# 查看网桥
$ brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.024257229552 no veth71942f7 # 容器与宿主机之间的通信
virbr0 8000.5254003c195a yes virbr0-nic # 虚拟机之间提供网络通信
# bridge模式下
# docker daemon守护进程会创建一对对等虚拟设备接口 veth pair
# 将其中一个接口设置为容器的 eth0 接口(容器的网卡)
# 另一个接口放置在宿主机的命名空间中,以类似 vethxxx 这样的名字命名,从而将宿主机上的所有容器都连接到这个内部网络上
# 从网桥 docker0 的私有地址空间中分配一个 IP 地址和子网给该容器
# 并设置 docker0 的 IP 地址为容器的默认网关
# 查看bridge模式下的容器
$ docker network inspect bridge
`{
"Containers": {
"f554d6ebfc496a20ed6ac0644d2b4f49bab12536ac446a86485f43516c942e93": {
"Name": "nginx-test",
"EndpointID": "xxx",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
}
}`
docker 之中部署了一个nginx,那么访问该nginx服务,数据走向是怎么样的,经历了多少个网卡:
- 路由表来看,目标IP地址172.17.0.2属于172.17.0.0/16子网,数据包会被发送到docker0接口上;
- 数据包被Docker虚拟网络处理,最终被路由到与容器172.17.0.2对应的网络命名空间中,从而到达容器内部;
Q&A
1.将网络接口(网卡)添加到网桥之中会怎么样
- 将网卡加入网桥,该网卡可以接收和转发网桥中其他网络设备(包括其他网卡、虚拟机等)发送的数据包。
- 该网卡也可以向网桥中的其他设备发送数据包,从而实现网络通信。
- 通过使用网桥,可以在不同的网络设备之间进行透明的通信,就像它们直接相连一样.
同一个网桥的设备之间可以通信;
2.sudo brctl addif my-net eth0 这句话什么意思,lo的流量会怎么走
- 将 "eth0" 的物理网络接口(network interface)添加到名为 "my-net" 的 Linux 桥接器(bridge)上。
- "eth0" 的网络流量转发到该桥接器上,以便与其他连接到该桥接器的设备进行通信。
3.网络接口lo流量走向
- 系统上的本地回环接口(loopback interface);
- 同一系统内部发送和接收数据包;
- lo的流量不会通过该桥接器或任何其他物理网络接口,直接在内核中传递,计算机内部进行循环传输;
4.docker容器是net=none的,可以直接访问容器内部吗
如果将容器的网络类型设置为net=none,那么容器将完全没有网络访问权限,无论是从容器内部访问外部网络,还是从外部网络访问容器内部的服务都不可能实现。
5.docker的网络类型有哪些
bridge或者host模式,默认使用的是bridge网络模,在bridge网络模式下,容器的IP地址是通过NAT(Network Address Translation,网络地址转换)进行转换的,所以从容器外部无法直接访问容器内部的IP地址。 Docker daemon创建的docker0虚拟网桥,会为每个容器分配一个私有的IP地址。 当容器需要与外部网络通信时,容器的私有IP地址会被NAT为宿主机的IP地址,并通过宿主机上的网络接口与外部网络通信。 这样可以让多个容器共享一个宿主机的公网IP地址,从而节省公网IP地址的使用。
6.Docker的NAT是什么
- NAT(Network Address Translation)NAT功能通过Linux内核的iptables实现;
- 将Docker容器中的私有IP地址(通常是172.17.x.x)映射到宿主机的公共IP地址上,实现容器和宿主机之间的通信;
- 当容器访问外部网络时,Docker将数据包NAT处理,私有IP地址替换为宿主机的公共IP地址,以实现容器和外部网络之间的通信;
$ iptables -t nat -L -n
# 下面是docker NAT 输出规则
# 目的是实现docker容器访问外部网络
# 将来自172.17.0.0/16网段的所有数据包的源地址改为主机的IP地址
# 并将它们发送到目的地0.0.0.0/0
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 172.17.0.0/16 0.0.0.0/0
‘
# 至于访问外部网络可以直接走路由规则将所有172.17.0.0/16网段数据包发172.17.0.1
# 也就是docker0网桥
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
# docker网桥
docker0: inet 172.17.0.1/16 scope global docker0
# docker0网桥上插着每个容器网络命名空间的网卡的pair对端网卡
$ brctl show
bridge name bridge id STP enabled interfaces
br1 8000.62429a077f4c no veth1
br2 8000.aa0bfb51ea56 no veth3
docker0 8000.024236ffee25 no veth0c7094b(nginx1)
veth40a4dc5(nginx2)
vethdbe644d(nginx3)
7.docker的网络类型bridge和host有什么区别
- Bridge网络类型是Docker默认的网络类型,而Host网络类型是指容器直接使用宿主机的网络,不会进行网络隔离。
- Bridge网络类型在容器和宿主机之间建立虚拟网络,容器之间可以通过容器名或者IP地址相互通信,但是容器和宿主机之间需要映射端口才能通信。
- Host网络类型直接使用宿主机的网络,容器可以直接访问宿主机的所有端口和网络设备,但是容器之间的网络隔离失效。
- Bridge网络类型可以使用Docker内置的DNS服务来访问其他容器的服务,而Host网络类型需要使用宿主机的DNS服务来访问其他服务。
- Bridge网络类型可以使用Docker内置的端口映射来将容器内部的端口映射到宿主机的端口,从而实现容器与外部的通信。而Host网络类型不需要进行端口映射,直接使用宿主机的端口即可。
8.ip a
和ifconfig
有什么区别
都是用来显示系统网络配置信息的命令:
- ip a是较新的命令,能够显示更丰富的网络信息,包括IPv4和IPv6地址、MAC地址等,而ifconfig只能显示IPv4地址和MAC地址。
- ip a命令在处理网络配置时更加灵活,支持更多的网络参数设置,而ifconfig则不支持。
- ip a命令输出的信息更易于理解和解析,而ifconfig输出的信息比较混乱,需要进行额外的处理才可读。
9.veth pair技术
- veth pair 技术是一种网络虚拟化技术,它能够创建一对虚拟的网络设备(veth pair),这对设备之间通过一个虚拟的网络连接在一起。
- 每个 veth pair 都包含两个端点,一个端点被称为veth0,另一个端点被称为veth1,它们可以被分别连接到不同的网络命名空间中。
- veth pair 技术通常被用于实现容器网络,因为它可以使容器中的应用程序共享主机系统的网络设备,而不必在容器中运行一个独立的网络堆栈。
10.NAT功能通过Linux内核的iptables实现
- Network Address Translation (NAT) 功能可以通过 Linux 内核的 iptables 工具来实现。
- 但不是NAT都是需要用iptables实现,除了iptables,iproute2工具集中的ip命令可以用于配置和管理网络地址转换。
- 如netfilter和conntrack等,也可以在Linux系统上实现高级的NAT功能。
11.网桥相关概念
- 网桥(Bridge)可用于连接两个或多个网络段,使其成为一个逻辑局域网(LAN)。
- OSI模型的第二层,即数据链路层(MAC地址)。它通过学习和转发数据包的MAC地址来实现网络段之间的通信。
- 基本原理:当数据包到达网桥的一个接口,网桥会依据数据包的目的MAC地址,并将其发送到与该目的地址相应的接口上。
- 根据MAC地址进行转发,而不是根据IP地址,网桥可以在一个局域网中连接不同的IP子网。
12.邻居表
- 用途
查看本地节点直接相连的邻居节点的信息
- linux上如何查看邻居表
arp -a
(10.244.0.13) at c6:e5:e0:ff:70:e1 [ether] on cni0
(10.244.0.20) at <incomplete> on cni0
(10.244.0.7) at c2:9f:76:a6:1f:6b [ether] on cni0
(10.244.0.14) at 52:8e:1f:86:41:c4 [ether] on cni0
(10.202.41.113) at d0:0d:58:94:26:ab [ether] on ens3
- 如何维护
分动态邻居表、静态邻居表(需要管理员手动进行)
13.DHCP
DHCP(Dynamic Host Configuration Protocol)是一种网络协议,用于自动分配IP地址和其他网络配置参数给计算机设备。静态IP地址是由管理员手动分配给设备的固定IP地址,不通过DHCP协议进行动态分配。
- 配置静态IP
# 1.更新网卡配置文件
# 系统信息
$ hostnamectl
Virtualization: kvm
Operating System: openEuler 22.03 (LTS-SP1)
Kernel: Linux 5.10.0-136.12.0.86.oe2203sp1.x86_64
Architecture: x86-64
# 网卡配置
vi /etc/sysconfig/network-scripts/ifcfg-ens8
# 网卡配置内容
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static
DEFROUTE=no
IPV4_FAILURE_FATAL=no
NAME=enp8s0
DEVICE=enp8s0
ONBOOT=yes
IPADDR=192.168.1.7
NETMASK=255.255.255.0
GATEWAY=192.168.1.1
- 重启网络服务
systemctl restart network
相关资料
linux veth pair详解6 张图详解 Docker 容器网络配置Linux下IPV6添加、修改、删除邻居表及修改邻居表释放时间指令