概念
- 通过将某个特定的全局系统资源通过抽象方法使得namespace中的进程看起来拥有它们自己的隔离的全局系统资源实例、
- 当Docker创建一个容器时,它会创建6种namespce的实例,然后把容器中的所有进程放到这些namespace中,使得Docker中的进程只能看到隔离的系统资源
- 如下是Linux内核中的6种namespace
namespace | 被隔离的全局系统资源 | 在容器语境下的隔离效果 |
---|---|---|
mount namespace | 文件系统挂载点 | 每个容器能看到不同的文件系统层次结构 |
UTS namespace | nodename and domainname | 每个容器都可以有自己的hostname和domainname |
IPC namespace | 特定进程间通信资源,包括System V IPC 和 POSIX message queues | 每个容器有自己的System V IPC 和 POSIX 消息队列文件系统,因此,只有在同一个IPC namespace的进程间才能互相通信 |
PID namespace | 进程ID数字空间process ID numberspace | 每个PID namespace 中的进程可以有其独立的PID;每个容器可以有其PID为1的root进程;也可以使得容器可以在不同的host之间迁移,因为namespace的进程ID和host无关了。这也使得容器中的每个进程有两个PID:容器的PID和host上的PID |
Network namespace | 网络相关的系统资源 | 每个容器用有其独立的网络设备,IP 地址,IP 路由表,/proc/net 目录,端口号等等。这也使得一个 host 上多个容器内的同一个应用都绑定到各自容器的 80 端口上 |
User namespace | 用户和组 ID 空间 | 在 user namespace 中的进程的用户和组 ID 可以和在 host 上不同; 每个 container 可以有不同的 user 和 group id;一个 host 上的非特权用户可以成为 user namespace 中的特权用户 |
PID namespace
我们能够看到,在容器内外的PID时不同的:
- 在容器内PID=1,PPID=0
- 在容器外PID=xxx,PPID=xxxx,即docker-containerd-shim进程
- 关于containerd, containerd-shim & container的关系,如下图
- Docker 引擎管理着镜像,然后一脚给containerd运行,containerd再使用runC运行容器
- Containerd是一个简单的守护进程,它可以使用runC管理容器,使用gRPC暴露容器的其他功能。它管理容器的开始,停止,暂停和销毁。
- 由于容器运行时是孤立的引擎,引擎最终能够启动和升级而无需重新启动容器
- runC是要给轻量级的工具,它就是用来运行容器的,是一个小命令行工具,可以不用通过Docker引擎,直接操作容器
user namespace
- Linux通过clone()系统调用中使用的CLONE_NUWUSER标志,一个单独的user namespace就会被创建出来
- 新的user namespace中,有一个虚拟机用户和用户组的集合。这些用户/用户组可以映射到namespace之外的非root用户
在容器内部启动sleep进程
在主机上查看该进程
可见容器内外都是root用户,且容器外的进程用户权限是受限的。但很明显,不能信任,其中可能存在漏洞。面对同样的进程,在容器内享有root权限,映射到主机上应该对应一个普通用户。
一般情况下,docker会帮我们创建好dockermap用户,没有的话就自己创建一个
重启docker后,再容器内创建sleep进程可见:
检查Linux是否开启namespace
// 查看namespace关键字
CONFIG_UTS_NS=y
CONFIG_IPC_NS=y
CONFIG_USER_NS=y
CONFIG_PID_NS=y
CONFIG_NET_NS=y
network namespace
默认情况下,当docker实例被创建出来后,使用ip netns命令无法看到network namespace,因为ip netns命令是从/var/run/netns文件夹中读取内容的
- 找到容器的主进程ID
ps -ef |grep [containerID]
- 创建/var/run/netns目录以及符号链接
ln -s /proc/[container PID]/ns/net /var/run/netns/[containerID]
- 此时可以使用ip netns
ip netns
ip netns exec [containerID] ip addr
本文参考自 https://www.cnblogs.com/sammyliu/p/5878973.html