共计 5573 个字符,预计需要花费 14 分钟才能阅读完成。
一. 网络基础
Docker 使用到的与 Linux 网络有关的技术分别有:网络名称空间、Veth、Iptables、网桥、路由
1.什么是网络名称空间
- 为了支持网络协议栈的多个实例,Linux 在网络协议栈中引入了网络名称空间(Network Namespace)
- 这些独立的协议栈被隔离到不同的命名空间中
- 处于不同的命名空间的网络协议栈是完全隔离的,彼此之间无法进行网络通信,就好像两个“平行宇宙”
- 通过这种对网络资源的隔离,就能在一个宿主机上虚拟多个不同的网络环境
ps : 如果不同网络名称空间之间要进行通信该怎么办呢?
2.Veth 设备对
- 引入 Veth 设备对 就是为了在不同的网络名称空间之间进行通信
- 利用它可以直接将两个网络名称空间链接起来, Veth 设备是成对出现
- 像一对网卡, 我们将其中一端称为另一端的 peer
2.1. 底层原理实验示例
- 需求 : 建立两个名称空间, 并实现相互 ping 通
- 查看, 添加, 删除 namespace 命令
ip netns list # 查看
ip netns add [namespace] # 添加
ip netns delete [namespace] # 删除
- 建立两个名称空间
[root@shawn ~]#ip netns add test1
[root@shawn ~]#ip netns add test2
[root@shawn ~]#ip netns list
test2
test1
- 建立一对 veth
[root@shawn ~]#ip link add veth1 type veth peer name veth2
[root@shawn ~]#ip link
- 创建 veth 后, 我们将 veth 分别添加到名称空间 test1 及 test2 中
[root@shawn ~]#ip link set veth1 netns test1
[root@shawn ~]#ip link set veth2 netns test2
- 查看一下是否已经添加成功了
[root@shawn ~]#ip netns exec test1 ip link
[root@shawn ~]#ip netns exec test2 ip link
- 添加完成后我们就需要为其设置 IP 了, 并将其状态 up
[root@shawn ~]#ip netns exec test1 ip addr add 172.17.0.111/20 dev veth1
[root@shawn ~]#ip netns exec test2 ip addr add 172.17.0.112/20 dev veth2
[root@shawn ~]#ip netns exec test1 ip link set dev veth1 up
[root@shawn ~]#ip netns exec test2 ip link set dev veth2 up
- 查看 IP 是否设置成功
[root@shawn ~]#ip netns exec test1 ip a
[root@shawn ~]#ip netns exec test2 ip a
- 最后, 检测一下是否能相互 ping 通
[root@shawn ~]#ip netns exec test1 ping 172.17.0.112
[root@shawn ~]#ip netns exec test2 ping 172.17.0.111
- 成功✅
3. 网桥(Bridge)
- Linux 可以支持多个不同的网络,它们之间能够相互通信,就需要一个网桥, 网桥就是二层的虚拟网络设备
- 它是把若干个网络接口“连接”起来,从而报文能够互相转发
- 网桥命令格式 :
docker network [命令参数]
⚽查看当前系统有哪些网桥 "ls"
[root@shawn ~]#docker network ls
'''
NETWORK ID NAME DRIVER SCOPE
befd59194a71 bridge bridge local
94f8e35f3357 host host local
79fb28a9a12e none null local
'''
⚽创建网桥 "create"
[root@shawn ~]#docker network create shawn
ffac93578a0ce40395936d226bd097fd049ad077022419a9b6b074b6fe2f892b
[root@shawn ~]#docker network ls
'''
NETWORK ID NAME DRIVER SCOPE
befd59194a71 bridge bridge local
94f8e35f3357 host host local
79fb28a9a12e none null local
ffac93578a0c shawn bridge local #新建的网桥
'''
⚽查看网桥信息, 格式 : "docker network inspect [网桥的名称 | 网桥 ID]"
[root@shawn ~]#docker network inspect shawn
'''
[
{
"Name": "shawn",
"Id": "ffac93578a0ce40395936d226bd097fd049ad077022419a9b6b074b6fe2f892b",
"Created": "2020-12-03T11:56:35.554136022+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {"Network": ""},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}}
]
'''
⚽删除网桥 "rm"
[root@shawn ~]#docker network rm shawn
shawn
[root@shawn ~]#docker network ls
'''
NETWORK ID NAME DRIVER SCOPE
befd59194a71 bridge bridge local
94f8e35f3357 host host local
79fb28a9a12e none null local
''' # "Shawn" 被删除了
⚽清理网桥 "prune", 我们先创建多个网桥, 然后一次性清除
[root@shawn ~]#docker network create shawn1
f4d2f2b57b48cd35b3cc9eddad0377cae95d213032ed0d6a92e9de9571adeb4e #创建成功
[root@shawn ~]#docker network create shawn2
ea66ed0d06adbe7f5211f3ae38b6edeb47dffac0f53240e9204fd3dcaf4670d5 #创建成功
[root@shawn ~]#docker network create shawn3
222d6e298d6091cea0a6229e19c84825a41ea92b7c0b512db47c858dde7259f0 #创建成功
[root@shawn ~]#docker network prune
WARNING! This will remove all custom networks not used by at least one container.
Are you sure you want to continue? [y/N] y # 问你是否要这样做 "yes"
Deleted Networks: # 将要删除以下网桥
shawn1
shawn2
shawn3
[root@shawn ~]#docker network ls
'''
NETWORK ID NAME DRIVER SCOPE
befd59194a71 bridge bridge local
94f8e35f3357 host host local
79fb28a9a12e none null local
''' # 发现并没有 "shawn" 系列的网桥
4.Iptables
- iptables 是 linux 系统自带的优秀且完全免费的基于包过滤的防火墙工具、它的功能十分强大、使用非常灵活、可以对流入、流出及流经服务器的数据包进行精细的控制
5. 总结
network namespace | 主要提供了关于网络资源的隔离,包括网络设备、IPv4 和 IPv6 协议栈、IP 路由 表、防火墙、/proc/net 目录、/sys/class/net 目录、端口(socket)等 |
---|---|
linux Bridge | 功能相当于物理交换机,为连在其上的设备(容器)转发数据帧。如 docker0 网桥 |
iptables | 主要为容器提供 NAT 以及容器网络安全 |
veth pair | 两个虚拟网卡组成的数据通道。在 Docker 中,用于连接 Docker 容器和 Linux Bridge。一端在容器中作为 eth0 网卡,另一端在 Linux Bridge 中作为网桥的一 个端口 |
二.Docker 网络模式
安装 Docker 时,它会自动创建三个网络,bridge(创建容器默认连接到此网络)、none、host
docker network ls
: 查看当前系统有哪些网络(网桥)
[root@shawn ~]#docker network ls
NETWORK ID NAME DRIVER SCOPE
befd59194a71 bridge bridge local
94f8e35f3357 host host local
79fb28a9a12e none null local
1. 原理
- Docker 使用 Linux 桥接,在宿主机虚拟一个 Docker 容器网桥(docker0)
- Docker 启动一个容器时会根据 Docker 网桥的网段分配给容器一个 IP 地址,称为 Container-IP, 同时 Docker 网桥是每个容器的默认网关
- 因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的 Container-IP 直接通信
- Docker 网桥是宿主机 虚拟 出来的,并不是真实存在的网络设备,外部网络是 无法寻址 到的,这也意味着外部网络无法通过直接 Container-IP 访问到容器
- 如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射),即 docker run 创建容器时候通过 -p 或 -P 参数来启用,访问容器的时候就通过 [宿主机 IP]:[容器向外暴露的端口] 访问容器
2. 四类网络模式
网络模式 | 设置方法 | 简介 |
---|---|---|
Host | --network host | 容器将不会虚拟出自己的网卡,配置自己的 IP 等,而是使用宿主机的 IP 和端口 |
Bridge | --network bridge(默认此模式) | 此模式会为每一个容器分配、设置 IP 等,并将容器连接到一个 docker0 虚拟网桥,通过 docker0 网桥以及 Iptables nat 表配置与宿主机通信 |
None | -- network none | 该模式关闭了容器的网络功能(只提供回环) |
Container | --network "container:[共享容器名称]" | 创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围 |
2.1、Host 模式
- 相当于 Vmware 中的桥接模式,与宿主机在同一个网络中,但没有独立 IP 地址, 容易造成端口冲突
- 但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的
- 格式 :
docker run --network host [镜像名称或 ID]
[root@shawn ~]#docker run -d --network host nginx:latest
2.2、Container 模式
- 这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享
- 新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等
- 同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信
- 格式 :
docker run --network "containe:[共享容器名称]" [镜像名称或 ID]
- 实验:
⚽创建共享容器 "cont01"
[root@shawn ~]#docker run -dit --name cont01 busybox:latest sh
⚽创建链接容器 "cont02", 并指定网络模式 "container"
[root@shawn ~]#docker run -dit --name cont02 --network "container:cont01" busybox:latest sh
⚽查看两个容器的 "ip", 发现一样
[root@shawn ~]#docker exec cont01 ip a
[root@shawn ~]#docker exec cont02 ip a
2.3、None 模式
- 该模式将容器放置在它自己的网络栈中,但是并不进行任何配置, 只提供回环
- 该模式关闭了容器的网络功能 , 一般是因为容器并不需要网络(例如只需要写磁盘卷的批处理任务)
- 格式 :
docker run --network none [镜像名称或 ID]
[root@shawn ~]#docker run -dit --network none --name none_test busybox:latest sh
2.4、Bridge 网桥模式
- 相当于 Vmware 中的 Nat 模式,容器使用独立 network Namespace,并连接到 docker0 虚拟网卡(默认模式)
- 虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中
- bridge 模式是 docker 的 默认网络模式 ,不写 --network 参数,就是bridge 模式
- 使用 docker run -p 时,docker 实际是在 iptables 做了 DNAT 规则,实现 端口转发功能
- 相关操作
相关操作在文章第一段第三小章 ""网桥(Bridge)""
正文完