05 Docker网络

308次阅读
没有评论

共计 5573 个字符,预计需要花费 14 分钟才能阅读完成。

一. 网络基础

Docker 使用到的与 Linux 网络有关的技术分别有:网络名称空间、Veth、Iptables、网桥、路由

1.05 Docker 网络什么是网络名称空间

  • 为了支持网络协议栈的多个实例,Linux 在网络协议栈中引入了网络名称空间(Network Namespace)
  • 这些独立的协议栈被隔离到不同的命名空间中
  • 处于不同的命名空间的网络协议栈是完全隔离的,彼此之间无法进行网络通信,就好像两个“平行宇宙”
  • 通过这种对网络资源的隔离,就能在一个宿主机上虚拟多个不同的网络环境

05 Docker 网络

ps : 如果不同网络名称空间之间要进行通信该怎么办呢?

2.Veth 设备对

  • 引入 Veth 设备对 就是为了在不同的网络名称空间之间进行通信
  • 利用它可以直接将两个网络名称空间链接起来, Veth 设备是成对出现
  • 像一对网卡, 我们将其中一端称为另一端的 peer

05 Docker 网络

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

05 Docker 网络

  • 创建 veth 后, 我们将 veth 分别添加到名称空间 test1test2
[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

05 Docker 网络

05 Docker 网络

  • 添加完成后我们就需要为其设置 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

05 Docker 网络

05 Docker 网络

  • 最后, 检测一下是否能相互 ping
[root@shawn ~]#ip netns exec test1 ping 172.17.0.112
[root@shawn ~]#ip netns exec test2 ping 172.17.0.111

05 Docker 网络

05 Docker 网络

  • 成功

3. 网桥(Bridge)

  • Linux 可以支持多个不同的网络,它们之间能够相互通信,就需要一个网桥, 网桥就是二层的虚拟网络设备
  • 它是把若干个网络接口“连接”起来,从而报文能够互相转发

05 Docker 网络

  • 网桥命令格式 : 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

05 Docker 网络

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

05 Docker 网络

05 Docker 网络

05 Docker 网络

2.3、None 模式

  • 该模式将容器放置在它自己的网络栈中,但是并不进行任何配置, 只提供回环
  • 该模式关闭了容器的网络功能 , 一般是因为容器并不需要网络(例如只需要写磁盘卷的批处理任务)
  • 格式 : docker run --network none [镜像名称或 ID]
[root@shawn ~]#docker run -dit --network none --name none_test busybox:latest sh

05 Docker 网络

2.4、Bridge 网桥模式

  • 相当于 Vmware 中的 Nat 模式,容器使用独立 network Namespace,并连接到 docker0 虚拟网卡(默认模式)
  • 虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中
  • bridge 模式是 docker 的 默认网络模式 ,不写 --network 参数,就是bridge 模式
  • 使用 docker run -p 时,docker 实际是在 iptables 做了 DNAT 规则,实现 端口转发功能

05 Docker 网络

  • 相关操作

相关操作在文章第一段第三小章 ""网桥(Bridge)""

正文完
 
shawn
版权声明:本站原创文章,由 shawn 2023-06-16发表,共计5573字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)