命名空间是Linux内核针对容器虚拟化而引入的特性。每个容器拥有自己单独的命名空间,命名空间保证容器之间互不影响。
进程命名空间
进程命名空间是父子关系结构,子空间中的进程对于父空间是可见的。
新fork出的进程在父命名空间和子命名空间都有一个进程号对应。
例如,查看Docker主进程的pid进程号
ps -ef | grep docker
root 831 1 1 09:14 ? 00:05:54 /usr/bin/dockerd
新建的Ubuntu容器
docker run -d ubuntu /bin/sh -c "while true;do echo hello world;sleep 1;done"
则新创建的容器的父进程就是Docker进程。
网络命名空间
网络命名空间为进程提供了完全独立的网络协议栈视图,包括网络设备接口、IPv4和IPv6协议栈、IP路由表、防火墙规则、sockets等。Docker采用虚拟网络设备将不同命名空间的网络设备连接在一起。
默认,容器中的虚拟网卡将与本地的docker0网桥连接在一起。
通过brctl工具,可以查看桥接到宿主机docker0网桥的虚拟网口
brctl show
IPC命名空间
容器中进程交互采用IPC方法,包括信号量、消息队列、共享内存等。
PID命名空间和IPC命名空间可以组合使用,同一个IPC命名空间内的进程可以彼此可见,允许进行交互;而不同空间的进程则无法交互。
挂载命名空间
类似chroot,将一个进程放到特定的目录执行,挂载命名空间允许不同命名空间的进程看到的文件结构不同。
UTS命名空间
UTS(UNIX Time-sharing System)命名空间允许每个容器拥有独立的主机名和域名,从而可以虚拟出有独立主机名和网络空间的环境,就像网络上的独立主机一样。
默认,Docker容器的主机名就是返回的容器ID。
用户命名空间
每个容器可以有不同的用户和组id,这样,在容器内可以使用特定的内部用户执行程序,而非本地系统存在的用户。
每个容器都可以有root账号,跟宿主机不在一个命名空间。