1. 什么是网络命名空间?
在Linux系统中,网络命名空间(Network Namespace)是一种内核特性,允许我们有多个独立的网络实例存在于同一个物理系统上。这相当于在单一操作系统中复制了多个网络栈,实现了网络隔离。每个网络命名空间都拥有自己的网络资源,例如IP地址、路由规则和端口号集合。应用程序可以被绑定到特定的网络命名空间中运行,从而被限制仅在该空间内的网络环境中通信。
2. Docker容器与网络命名空间
Docker通过容器化技术,让应用能够在隔离的环境中运行。
每个 Docker 容器都会自动创建一组命名空间,包括主机名命名空间(UTS)、用户命名空间(USER)、挂载命名空间(MNT)、网络命名空间(NET)、进程命名空间(PID)、进程间通信命名空间(IPC)。
其中的网络命名空间允许每个容器拥有独立的网络栈,从而实现网络的隔离和管理。这为容器之间的通信、容器与宿主机之间的通信,以及容器访问外部网络带来了极大的灵活性和控制。
3. Docker的网络模式
Docker支持几种网络模式,用于定义容器应该如何与网络交互:
- bridge:这是默认的网络模式。在这种模式下,Docker会为所有需要网络通信的容器创建一个虚拟桥接器。容器将通过这个桥接器与宿主机以及其他容器交互。
- none:在这个模式下,容器拥有自己的网络命名空间,但不会配置任何网络接口,这意味着容器与外界隔离。
- host:容器将不会获得自己的网络命名空间,而是直接使用宿主机的网络栈。
- overlay:适用于跨多个宿主机的容器集群,它们通过使用overlay网络互连,而不是依赖于每个宿主机的物理网络。
4. 手动管理网络命名空间
4.1. 查看指定容器的网络命令空间
通过容器详情查看网络信息
1 | docker inspect xxx |
查看 NetworkSettings
和 Networks
部分,包括其IP地址、网关和DNS设置等,但是不包含网络命名空间。
通过容器的进程查看网络命令空间
1 | ls -l /proc/$(docker inspect --format '{{.State.Pid}}' xxx)/ns/net |
4.2. 查看所有容器的网络命名空间
我们可以通过查看 /var/run/docker/netns/
目录来了解 Docker 创建了哪些网络命名空间:
1 | ls -l /var/run/docker/netns/ |
注意,不是所有的 Docker 安装都会将这些文件放在这个目录下。有时,为了安全考虑,这个目录可能并不容易直接访问。
4.3. 进入容器的网络命名空间
1、获取容器的PID
1 | pid=$(docker inspect --format '{{.State.Pid}}' xxx) |
2、进入指定容器的网络命名空间
1 | nsenter --target $pid --net |
3、执行网络相关命令
1 | ip addr |
4、退出容器的网络命名空间
1 | exit |