目录
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 专栏中讲解~