目录
1. Docker 为什么需要网络管理
2. Docker 网络架构简介
CNM(Container Network Model)
Libnetwork
驱动
3. ⭕常见网络类型(5 种)
4. Docker 网络管理命令
一. bridge 网络
1. 操作案例:容器间网络通信
实验步骤
示例命令
观察
2. 创建自定义 Bridge
示例命令
连接到自定义Bridge网络 2.0
3.DNS解析
一、Docker 自定义桥接网络支持 DNS 解析服务
二、准备实验环境
三、是否支持 DNS 解析服务
端口暴露和转发
1. 暴露方式
2. 端口转发
二. Docker host 网络模式
1. 网络介绍
2. 操作案例
三、Docker container 网络模式
1. 网络介绍
2. 实现逻辑
3. 操作案例
4. 使用场景
四、Docker none 网络模式
1. 网络介绍
2. 操作案例
3. 使用场景
1. Docker 为什么需要网络管理
容器的网络默认与宿主机及其他容器相互隔离,但实际应用中需要解决以下问题:
- 多个容器之间的通信
- 容器与宿主机的通信
- 容器与外界主机的通信
- 外部访问容器内的网络应用
- 容器网络不隔离的需求
- 容器无需网络的情况
- 定制化网络需求(如集群网络、局域网)
我们想尽量的通过命令,来实现上述功能
2. Docker 网络架构简介
Docker 容器网络是应用程序的虚拟环境的一部分,包括虚拟网络设备、IP 协议栈、端口套接字、IP 路由表、防火墙等。Docker 网络架构主要由三部分组成:CNM、Libnetwork 和驱动。
CNM(Container Network Model)
Docker 网络架构采用的设计规范是 CNM(Container Network Model)。CNM 中规定了 Docker 网络的基础组成要素:Sandbox、Endpoint、Network。
- Sandbox:提供容器的虚拟网络栈,隔离容器网络与宿主机网络。
- Network:Docker 内部的虚拟子网,使网络内的参与者能够通信。
- Endpoint:虚拟网络接口,负责创建连接。一个 Endpoint 只能接入一个网络,容器需要接入多个网络时需要多个 Endpoint。
如上图所示,容器 B 有两个 Endpoint 并且分别接入 Networkd A 和 Network B。
- 那么 容器 A 和容器 B 之间是可以实现通信的,因为都接入了 NetworkA。
- 但是容器 A 和容 器 C 不可以通过容器 B 的两个 Endpoint 通信。
可以理解 A B 为宿舍上网打游戏,联机成功了
Libnetwork
- 介绍:Libnetwork 是 CNM 的一个标准实现。Libnetwork 是开源库,采用 Go 语言编写(跨 平台的),也是 Docker 所使用的库,Docker 网络架构的核心代码都在这个库中。
- 功能:实现了 CNM 中定义的全部三个组件,此外它还实现了本地服务发现、基 于 Ingress 的容器负载均衡,以及网络控制层和管理层等功能。
驱动
- 功能:实现数据层内容,如网络的连通性和隔离性。
- 驱动通过实现特定网络类型的方式扩展了 Docker 网络栈,例如桥接网络和覆盖网络。Docker 内置了若干驱动,通常被称作原生驱动或者本地驱动。
- 类型:Bridge Driver、Host Driver、Overlay Driver、MacVLan Driver、IPVLan Driver、None Driver 等。
- 每个驱动负责创建其上所有网络资源的创建和管理。
3. ⭕常见网络类型(5 种)
bridge 网络
- 描述:默认网络驱动,创建 Linux 网桥,容器在同一主机上可以相互通信。
- 用途:多个容器在同一个 Docker 主机上通信。
host 网络
- 描述:移除容器与宿主机的网络隔离,直接使用主机的网络。
- 用途:网络堆栈不应与 Docker 主机隔离,但希望容器的其他资源被隔离。
container 网络
- 描述:新创建的容器与现有容器共享网络,不创建自己的网卡和 IP。
- 用途:容器间网络共享,但仍保持文件系统和进程列表隔离。
none 网络
- 描述:容器没有网络配置,完全网络隔离。
- 用途:容器完全不需要网络的情况。
overlay 网络
- 描述:跨 Docker Daemon 网络,连接多个 Docker 守护进程,使集群服务能够相互通信。
- 用途:运行在不同 Docker 主机上的容器通信,或多个应用程序使用集群服务协同工作。
- overlay 网络 可以使用 Kubernetes (k8s) 时,通过网络插件(如 Flannel、Calico)实现跨主机的容器网络通信,提供了一个简单的网络解决方案,使得不同节点上的 Pod 能够相互通信。
4. Docker 网络管理命令
docker network create:创建网络
docker network create [OPTIONS] NETWORK
关键参数:
-d, --driver
:网络驱动--gateway
:网关地址--subnet
:子网--ipv6
:启用 IPv6
样例:
docker network create --driver=bridge --subnet=192.168.0.0/16 br0
docker network inspect:查看网络详情
docker network inspect [OPTIONS] NETWORK [NETWORK...]
关键参数:
-f, --format
:指定格式
样例:
docker network inspect mynetwork
docker network connect:连接网络
docker network connect [OPTIONS] NETWORK CONTAINER
关键参数:
--ip
:指定 IP 地址--ip6
:指定 IPv6 地址
样例:
docker network connect multi-host-network my_container1
docker run -itd --network=multi-host-network busybox-container
docker network connect --ip 10.10.36.122 multi-host-network container2
测试:
发现
docker network disconnect:断开网络
docker network disconnect [OPTIONS] NETWORK CONTAINER
关键参数:
-f
:强制退出
样例:
docker network disconnect multi-host-network my_container1
docker network prune:删除不使用的网络
docker network prune [OPTIONS]
关键参数:
-f, --force
:不提示
样例:
docker network prune
docker network rm:删除网络
docker network rm NETWORK [NETWORK...]
关键参数:
-f
:强制退出
样例:
docker network rm br0
docker network ls:列出网络
docker network ls [OPTIONS]
别名:
docker network list
关键参数:
-f, --filter
:指定过滤条件--format
:指定格式--no-trunc
:不截断-q, --quiet
:仅仅显示 id
样例:
一. bridge 网络
Docker Bridge 网络使用内置的 bridge 驱动,基于 Linux 内核中的 Linux bridge 技术。作为链路层设备,bridge 网络在网段之间转发流量,可以是硬件或软件设备。Docker 使用软件网桥 docker0
,允许同一网桥网络中的容器通信,同时隔离未连接网桥网络的容器。
Docker Container 的 bridge 桥接模式可以参考下图
默认 Bridge 网络
- 创建容器时,若未指定
--network
参数,容器默认加入名为bridge
的网络。 bridge
网络映射到内核中的docker0
网桥。
生活案例
- Bridge 网络如同立交桥,连接不同方向的通道。
1. 操作案例:容器间网络通信
实验步骤
- 使用 busybox 镜像创建两个容器
c1
和c2
。 - 查看容器 IP 地址,确认容器间能通过 IP 地址通信。
示例命令
- 创建容器:
docker container run -itd --name c1 busybox
docker container run -itd --name c2 busybox
- 查看容器 IP:
docker container exec -it c1 ip a
docker container exec -it c2 ip a
- 容器间通信测试:
docker container exec -it c1 ping 172.17.0.4
观察
- 容器
c1
和c2
通过docker0
网桥通信。 - 停止容器后,容器与
docker0
网桥的连接断开。
2. 创建自定义 Bridge
- 使用
docker network create -d bridge new-bridge
创建新的 bridge 网络。 - 通过
--network
参数指定容器连接到自定义 bridge。
示例命令
- 创建自定义 bridge:
docker network create -d bridge new-bridge
- 创建容器并连接到自定义 bridge:
docker container run -itd --name c3 --network new-bridge busybox
- 查看自定义 bridge 网络信息:
docker network inspect new-bridge
使用命令 docker network inspect 查看 new-bridge 网络信息会发现这个网络的子 网 IP 是 172.18.0.0/16,它表示如果我们创建容器并连接到该网络上,就会给该容 器分配一个 172.18.xx.xx 这个网段的 IP 地址。
连接到自定义Bridge网络 2.0
- 使用
--network
选项:在运行容器时,通过--network
选项指定要连接的网络( 172.18.xx.xx )。如果不指定,容器将默认连接到名为bridge
(172.17.0.1/16)的网络。
# 创建名为c3的容器,并指定连接到new-bridge网络
docker container run -itd --name c3 --network new-bridge busybox
- 查看容器网络信息:使用
docker container inspect
命令查看容器的网络配置,确认容器已连接到指定的网络。
# 查看c3容器的网络相关信息
docker container inspect c3 | grep "Networks" -A 17
3.DNS解析
一、Docker 自定义桥接网络支持 DNS 解析服务
- Docker DNS服务:Docker自定义桥接网络支持通过Docker DNS服务进行域名解析。这意味着可以直接使用容器名进行通信,因为DNS服务可以解析容器名到IP地址的映射。而默认的bridge网络不支持DNS。
二、准备实验环境
- 创建容器并连接到不同的网络
# 创建 c4 容器,连接 new-bridge
docker container run -itd --name c4 --network new-bridge busybox# 查看当前容器列表
docker container ls# 查看 bridge 网络连接的容器
docker network inspect bridge | grep "Containers" -A 20# 查看 new-bridge 网络连接的容器
docker network inspect new-bridge | grep "Containers" -A 20
c3
和c4
容器连接到自定义的new-bridge
网络。
三、是否支持 DNS 解析服务
- 查看
c3
和c4
容器的 IP 地址
# 查看 c3 容器的 IP 地址
docker container exec -it c3 ip a# 查看 c4 容器的 IP 地址
docker container exec -it c4 ip a
- 测试
c3
容器与c4
容器的通信
# c3 容器 ping c4 容器的 IP 地址
docker container exec -it c3 ping 172.18.0.3# c3 容器 ping c4 容器名
docker container exec -it c3 ping c4
输出示例:
结论:自定义的 new-bridge
网络支持 DNS 解析服务。
端口暴露和转发
1. 暴露方式
-P
:将指定的容器端口映射至主机所有地址的一个动态端口。-p <hostPort>:<containerPort>
:将容器端口<containerPort>
映射至指定的主机端口<hostPort>
。
2. 端口转发
连接 bridge
网络的容器只能与连接在当前网络中的容器进行通信。如果一个容器想要对外提供一些网络服务,需要进行端口转发。
示例:启动一个 nginx
容器,并将容器的 80 端口映射到宿主机的 8088 端口。
docker container run --name test-nginx --rm -d -p 8088:80 nginx
--rm
:运行完自动删除该容器。--name
:指定容器名。
如下图所示,两个容器内部均开放 80 端口,它 们分别映射到宿主机的 8088 和 8089 端口
- 即表示任何发送到 8088 端口的流量都会转发到----> Container 1 容器的 80 端口
- 发送到 8089 端口的流程都会转发到----> Container 2 容器的 80 端口
二. Docker host
网络模式
1. 网络介绍
Docker 容器运行默认都会分配独立的 Network Namespace。但如果基于 host
网络模式,容器将不会获得一个独立的 Network Namespace,而是和宿主机共用同一个 Network Namespace。容器将不会虚拟出自己的网卡、IP 等,而是直接使用宿主机的 IP 和端口。
2. 操作案例
- 创建容器
c1
使用bridge
网络
# 创建容器 c1 使用 bridge 网络
docker container run --name c1 -itd busybox
- 创建容器
c2
使用host
网络
# 创建容器 c2 使用 host 网络
docker container run --name c2 -itd --network=host busybox
- 查看容器
c1
和c2
的网络信息
# 查看 c1 的网络信息
docker container exec c1 ip a# 查看 c2 的网络信息
docker container exec c2 ip a
输出示例:
c1
容器的网络信息:
c2
容器的网络信息:
三、Docker container
网络模式
1. 网络介绍
- 定义:
container
网络模式是一种特殊的网络模式,其中新创建的容器会共享另一个容器的网络命名空间。
特点:
- 容器之间的网络隔离性介于
bridge
模式和host
模式之间。 - 共享网络环境的容器之间没有网络隔离,但与宿主机和其他容器之间存在网络隔离。
- 传输效率较高,容器可以通过
localhost
访问共享网络命名空间的其他容器。
2. 实现逻辑
- 查找需要被共享网络环境的容器(
other container
)的网络命名空间。 - 将新创建的容器的网络命名空间设置为
other container
的网络命名空间。
3. 操作案例
创建第一个容器 netcontainer1
docker run -itd --name netcontainer1 busybox
使用 netcontainer1
的网络创建第二个容器 netcontainer2
docker run -itd --name netcontainer2 --network container:netcontainer1 busybox
进入两个容器,查看网络信息
- 结论:两个容器的 IP 和 MAC 地址完全相同。
停止容器 netcontainer1
,再次查看 netcontainer2
的网络信息
docker stop netcontainer1
docker exec -it netcontainer2 sh
- 结论:
netcontainer2
的eth0
网卡消失,只剩本地回环网络。
重启容器 netcontainer1
和 netcontainer2
,再次查看网络信息
docker restart netcontainer1
docker restart netcontainer2
docker exec -it netcontainer2 sh
- 结论:容器网络恢复。
4. 使用场景
- 高效率网络传输:容器可以通过
localhost
访问共享网络命名空间的其他容器,传输效率较高。 - 依赖关系:两个容器之间存在依赖,如果依赖容器重启,会导致另一个容器的网络不可用。
四、Docker none
网络模式
1. 网络介绍
- 定义:
none
网络模式下,容器没有任何网络接口,除了本地回环网络(lo
)。
特点:
- 适合对安全性要求较高的应用,避免网络通信带来的安全风险。
- 容器无法与其他网络进行通信。
2. 操作案例
创建容器 c3
使用 none
网络
docker container run -itd --name c3 --network none busybox
查看容器 c3
的网络信息
docker container exec -it c3 ip a
输出示例:
结论:c3
容器只有本地回环网络,没有其他网络接口。
3. 使用场景
- 高安全性需求:针对一些对安全性要求较高且不需要联网的应用,如生成随机密码,避免生成的密码被第三方获取。
- 第三方应用:一些第三方应用可能需要 Docker 创建一个没有网络的容器,网络配置由第三方自行管理。
对于第五种常见网络类型,将在之后的 k8s 专栏中讲解~