linux namespace的概述

Linux Namespace提供了一种资源隔离机制,让多个进程看到不同的全局资源视图,如文件系统、网络、进程ID等。通过mount、ipc、network等namespace实现容器的隔离。clone、unshare和setns系统调用用于创建、分离和切换namespace。当最后一个进程退出,正常情况下namespace会随之一同销毁,但若资源被占用或有子namespace存在,namespace将持续存在。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.Linux Namespace

    namespace是Linux系统的底层概念,在内核层实现,即有一些不同类型的命名空间被部署在核内,各个docker容器运行在同一个docker主进程并且共 用同一个宿主机系统内核,各docker容器运行在宿主机的用户空间,每个容器都要有类似于虚拟机一样的相互隔离的运行空间,但是容器技术是在一个 进程内实现运行指定服务的运行环境,并且还可以保护宿主机内核不受其他进程的干扰和影响,如文件系统空间、网络空间、进程空间等,目前主要通过 以下8种技术实现容器运行空间的相互隔离.

目前,Linux已经支持8种全局资源的虚拟化(每种资源都是随着Linux内核版本的迭代而逐渐加入的,因此有些内核版本可能不具备某种namespace):

  • cgroup namespace:该namespace可单独管理自己的cgroup

  • ipc namespace:该namespace有自己的IPC,比如共享内存、信号量等

  • network namespace:该namespace有自己的网络资源,包括网络协议栈、网络设备、路由表、防火墙、端口等

  • mount namespace:该namespace有自己的挂载信息,即拥有独立的目录层次

  • pid namespace:该namespace有自己的进程号,使得namespace中的进程PID单独编号,比如可以PID=1

  • time namespace:该namespace有自己的启动时间点信息和单调时间,比如可设置某个namespace的开机时间点为1年前启动,再比如不同的namespace创建后可能流逝的时间不一样

  • user namespace:该namespace有自己的用户权限管理机制(比如独立的UID/GID),使得namespace更安全

  • uts namespace:该namepsace有自己的主机信息,包括主机名(hostname)、NIS domain name

  •  

     

2.1mount namespace

提供磁盘挂载点和文件系统的隔 离: a.每个容器都要有独立的根文件 系统有独立的用户空间,以实 现在容器里面启动服务并且使 用容器的运行环境,即一个宿 主机是ubuntu的服务器,可以 在里面启动一个centos运行环 境的容器并且在容器里面启动 一个Nginx服务,此Nginx运行 时使用的运行环境就是centos 系统目录的运行环境,即在容 器里面是不能直接访问宿主机 的文件系统。 b. 宿主机是使用了chroot技术把 容器锁定到一个指定的运行目录里面并作为容器的根运行环境。

2.2ipc namespace

提供进程间通信的隔离,IPC namespce隔离进程间通信资源(同一个IPC namespace的进程可实现内 存等资源共享,但是不同的 IPC namespace则严格隔离).
2.3uts namespace
    主机名隔离,UTS namespace(UNIX Timesharing System包含了运行 内核的名称、版本、底层体系结
构类型等信息)用于系统标识, 其中包含了hostname 和域名 domainname ,它使得一个容
器拥有属于自己hostname标 识,这个主机名标识独立于宿主 机系统和其上的其他容器。
2.4pid namespace
    进程隔离,Linux系统中,有一个PID为1的进程(init/systemd)是其他所有进程的父进程,那么在每个容器内也要有一个父进程来管理其下属的子进程,那么多个容器的进程通PID namespace进程隔离(比如PID编号重复、器内的主进程生成与回收子进程等)。
2.5network namespace
  网络隔离,每一个容器都类似于虚拟机一样有自己的网卡、监听端口、TCP/IP协议栈等,docker使用network namespace启动一个vethX接口,这样你的容器将拥有它自己的桥接ip地址,通常是docker0,而docker0 实质就是Linux的虚拟网桥,网 桥是在OSI七层模型的数据链 路层的网络设备,通过mac地址对网络进行划分,并且在不同网络直接传递数据。
2.6 user namesapce
    用户隔离,各个容器内可能会出现重名的用户和用户组名称,或重复的用户UID或者GID,那么怎么隔离各个容器内的用户空间呢?
     User Namespace允许在各个宿 主机的各个容器空间内创建相同的 用户名以及相同的用户UID和
GID,只是会把用户的作用范围限 制在每个容器内,即A容器和B容 器可以有相同的用户名称和ID的账 户,但是此用户的有效范围仅是当 前容器内,不能访问另外一个容器 内的文件系统,即相互隔离、互不 影响。
3.namespace 主要api
    

clone()

系统调用 clone() 创建一个新的进程,它会根据参数中的 CLONE_NEW* 设置,逐个实现对应的配置功能。当然这个系统调用也实现了一些与 namespace 无关的功能。对低于 Linux 3.8 版本内核的系统而言,大多数情况下, 需要具备 CAP_SYS_ADMIN 的 capability。

unshare()

系统调用 unshare()  将进程分配至新的 namespace ,同样,它也会根据参数中的 CLONE_NEW* 设置来调整实现对应的配置功能。对低于 Linux 3.8 的系统而言,大多数情况,需要具备 CAP_SYS_ADMIN 的 capability。

setns()

系统调用 setns() 将进程移动到某一已存在的 namespace,这会导致 /proc/[pid]/ns 对应的目录中内容的变更。进程创建的子进程可以通过调用 unshare() 和 setns() 来调整所属的 namespace。这通常是需要具备 CAP_SYS_ADMIN 的 capability 的。

4.部分重点目录

4.1./proc/[pid]/ns/ 目录

每个进程都有一个 /proc/[pid]/ns/ 子目录,目录中的内容会受到 setns() 系统调用的影响。只要目录中的文件被打开,对应的 namespace 就不能被销毁。系统可以通过调用 setns() 来变更这些文件内容。

  • Linux 3.7 及更早期的版本 - 文件是以硬链接方式存在的;

  • Linux 3.8 开始 - 文件以软连接的方式存在;

 

如果两个进程的 namespace 相同,那么它们这个目录内的内容应该是一样的。

以下是该目录下文件的详细说明:

文件名称起始版本描述
/proc/[pid]/ns/cgroupLinux 4.6进程的 cgroup namespace
/proc/[pid]/ns/ipcLinux 3.0进程的 IPC namespace
/proc/[pid]/ns/mntLinux 3.8进程的 mount namespace
/proc/[pid]/ns/netLinux 3.0进程的 network namespace
/proc/[pid]/ns/pidLinux 3.8进程的 PID namespace在进程的整个生命周期里是不变的
/proc/[pid]/ns/pid_for_childrenLinux 4.12进程创建子进程的 PID namespace这个文件与 /proc/[pid]/ns/pid 不一定一致。
/proc/[pid]/ns/timeLinux 5.6进程的 time namespace
/proc/[pid]/ns/time_for_childrenLinux 5.6进程创建子进程的 time namespace
/proc/[pid]/ns/userLinux 3.8进程的 user namespace
/proc/[pid]/ns/utsLinux 3.0进程的 UTS namespace

4.2./pro/sys/user 目录

/proc/sys/user 目录下的文件记录了各 namespace 的相关限制。当达到限制,相关调用会报错 error ENOSPC 。

文件名称限制内容说明
max_cgroup_namespaces在 user namespace 中的每个用户可以创建的最大 cgroup namespaces 数
max_ipc_namespaces在 user namespace 中的每个用户可以创建的最大 ipc namespaces 数
max_mnt_namespaces在 user namespace 中的每个用户可以创建的最大 mount namespaces 数
max_net_namespaces在 user namespace 中的每个用户可以创建的最大 network namespaces 数
max_pid_namespaces在 user namespace 中的每个用户可以创建的最大 PID namespaces 数
max_time_namespacesLinux 5.7在 user namespace 中的每个用户可以创建的最大 time namespaces 数
max_user_namespaces在 user namespace 中的每个用户可以创建的最大 user namespaces 数
max_uts_namespaces在 user namespace 中的每个用户可以创建的最大 uts namespaces 数

5.namespace 的生命周期

正常的 namespace 的生命周期与最后一个进程的终止和离开相关。

但有一些情况,即使最后一个进程已经退出了,namespace 仍不能被销毁。这里来稍微聊下这些特殊的情况:

  • /proc/[pid]/ns/* 中的文件被打开或者 mount ,即使最后一个进程退出,也不能被销毁;

  • namespace 存在分层,子 namespace 仍存在 ,即使最后一个进程退出,也不能被销毁;

  • 一个 user namespace 拥有一些非 user namespace (比如拥有 PID namespace 等其他的 namespace 存在),即使最后一个进程退出,也不能被销毁;

  • 对于 PID namespace 而言,如果与 /proc/[pid]/ns/pid_for_children  存在关联关系时,即使最后一个进程退出,也不能被销毁;

当然除此之外还有一些其他的情况,基本都是存在被占用或未被释放。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值