Linux - Namespace

news2025/1/20 18:27:18

一、namespace 是什么?

Linux namespaces 是对全局系统资源的一种封装隔离,使得处于不同 namespace 的进程拥有独立的全局系统资源改变一个 namespace 中的系统资源只会影响当前 namespace 里的进程,对其他 namespace 中的进程没有影响。

二、namespace 解决了什么问题?

Linux 内核出现 namespace 的一个主要目的就是实现轻量级虚拟化(容器)服务。在同一个 namespace 下的进程可以感知彼此的变化,而对外界的进程一无所知,从而达到隔离的目的。

其实换个说法,Linux 内核所提供的 namespace 技术为 docker 等容器技术的出现和发展提供了基础条件。没有 Linux 内核中的 namespace 的出现,可能 docker 容器化技术还不会那么快出现。

三、namespace 具体有哪些呢?

1. Mount Namespace 文件系统隔离。隔离了一组进程所看到的文件系统挂载点的集合,在不同的Mount Namespace 的进程所看到的文件是不同的。

2. UTS Namespace 隔离主机和域名信息。隔离了 uname() 系统调用返回的两个系统标识符 nodename 和 domainname. 在容器的上下文中,UTS namespace 允许每个容器拥有自己的hostname 和 UNIX domainname,这对于初始化和配置脚本是十分有用的,这些脚本根据这些名称来定制他们的操作。

3. IPC Namespace 隔离进程间通信。隔离了某些IPC资源(interprocess community,进程间通信)使划分到不同IPC Namespace 的进程组通信上隔离,无法通过消息队列、共享内存、信号量方式通信,这样,只有在同一个Namespace下的进程才能相互通信。如果你熟悉IPC的原理的话,你会知道,IPC需要有一个全局的ID,即然是全局的,那么就意味着我们的Namespace需要对这个ID隔离,不能让别的Namespace的进程看到。 要启动IPC隔离,我们只需要在调用clone时加上CLONE_NEWIPC参数就可以了。 int container_pid = clone(container_main, container_stack+STACK_SIZE, CLONE_NEWUTS | CLONE_NEWIPC | SIGCHLD, NULL);

4. PID Namespace 进程隔离。隔离了进程ID空间,不同的 PID Namespace 中的进程可以拥有相同的 PID。PID Namespace 的好处之一是,容器可以在主机之间迁移,同时容器内的进程保持相同的进程ID。PID Namespace 空间还允许每个容器拥有自己的 init (PID 1),它是“所有进程的祖先”,负责管理各种系统初始化任务,并在子进程终止时收割孤儿进程。

5. Network Namespace 网络资源隔离。每个 Network Namespace 都有自己的网络设备、IP地址、IP路由表、/proc/net目录、端口号等。

6. User Namespace 用户和用户组隔离。一个进程的用户和组ID在 User Namespace 空间外可以是不同的,一个进程可以在用户命名空间外拥有一个正常的无权限用户 ID,同时在命名空间内拥有一个(root 权限) 的用户ID。

上面说到了一句,要启动IPC隔离,我们只需要在调用clone时加上CLONE_NEWIPC参数就可以了

这主要是因为 Linux 的 namespace 主要是利用下面三个系统调用:

  • clone() – 实现线程的系统调用,用来创建一个新的进程,并可以通过设计上述参数达到隔离。
  • unshare() – 使某进程脱离某个namespace
  • setns() – 把某进程加入到某个namespace

深处我也不会~

四、通过实践来证明

理论结合实践才能更好的理解这些到底在说什么,我用一个简单的例子来简单阐述一下吧。

docker run -it busybox /bin/sh

 

1、我们以交互式的方式进入容器,执行 ls 命令,可以看到常规的 Linux 系统目录结构,但这并非是宿主机的文件系统。

有了文件系统隔离,我们在当前容器内对文件所做的操作并不会影响到外部宿主机的文件另外我们启动不同的容器,我们所看到的文件系统也是隔离的。

 

2、隔离主机和域名信息。这点其实很好验证,当执行 hostname 命令时,控制台会返回当前主机名称给我们。

前者是在容器内部执行,返回的是容器ID后者是在宿主机的控制台执行,输出的是ubuntu。

 

3、当我们执行 ifconfig 命令,我们会看到和我们宿主机不同的网卡和网关信息等

 

除了上面的方式,我们也可以通过 docker inspect <容器名|容器ID> 来看容器的相关信息,其中也包含了容器网络相关信息。

 

 

4、进程隔离也是同样如此,我们在宿主机和容器中分别执行 ps -ef | grep sh 命令,看看结果就知道啦 

 

在容器内明显看不到宿主机其他进程情况,并且容器内的 /bin/sh PID 为1,PID =1 的进程是系统启动时的第一个进程,也称 init 进程。其他的进程,都是由它管理产生的。而此时,PID=1 却是 /bin/sh 进程。而它在宿主机上所展示时,它的PID变成了 2456。

这一点也可以换成下面这条命令来准确定位:

docker inspect -f '{{.State.Pid}}' <容器名称或ID> # 查看容器的PID

这个结论就非常好说了,在容器中,它确确实实是完成了 PID 的隔离,明明宿主机上是 2456 的进程,变成了容器内的 1 号进程,同时在容器中还看不到宿主机其他进程。

 

五、Docker 中的 User Namespace 详解

Docker 中引入的 user namespace 可以让容器中有一个 “假”的 root 用户,它在容器内是 root,在容器外是一个非 root 用户。也就是 user namespace 实现了 host user 和 container user 之间的映射。

我们拿一个简单的例子来说明:

docker run -it -v /bin:/host/bin busybox /bin/sh

先来解释下这条命令,现在是 dj(uid=1000,gid=1000)的用户,将本机上的 /bin 目录,挂载到容器中 /host/bin 目录下啦,并以交互式的方式启动了容器 busybox ,进入到容器内部。

那么现在有个问题:我在容器中的 /host/bin 目录下可以修改文件或者增加文件吗? 见下图。

答案是可以的。为什么呢?我一个非root用户,为什么可以操作root权限的文件呢?

原因:Docker容器运行的时候,如果没有专门指定user, 默认以root用户运行它并不是说按照你现在的登录的用户去分配权限的,而是没有指定就默认使用root用户运行。

另外有没有觉得这是非常恐怖的一件事情,我明明没有 root 权限,却突然之间通过 docker 给容器挂载一个文件目录,虽然我一下没想起来可以做什么,但还是有点恐怖的哈。

因为在 Docker中默认并没有开启 user namespace这并不是说 Linux 机器没有支持 user namespace ,而是 docker 中没有开启。

在说如何让 Docker 启用 user namespace 之前,我们先用另一种方式来曲线救国一下。

我之前使用 id 命令, 看到了我当前用户 dj 的(uid=1001),我们在执行 docker run 记得指定一下即可。

上面的命令改为:

docker run -it  -u 1001:1001 -v /bin:/host/bin busybox /bin/sh

我们使用了 -u 1001:1001 来指定了容器内所使用的用户。我们再重复一下上面的操作。

  

六、如何让 Docker启用 User namespace 呢?

1、备份 docker 配置文件

 因为我之前没有配置文件,所以我直接新建了一个文件

 

2、修改 docker 配置文件

添加 User Namespace 配置: 在配置文件中添加以下内容以启用 User Namespace。这将告诉 Docker 守护进程使用 User Namespace 功能。

    {
      "userns-remap": "default"
    }

 

3、保存文件,重启启动 Docker 服务,以使配置文件生效

sudo systemctl restart docker

 

4、验证配置 

cat /etc/subuid
cat /etc/subgid

dockermap 是默认的映射名称。

补充/etc/subuid 是一个系统配置文件,用于管理用户命名空间中用户的子用户标识(sub-IDs)。不多占篇幅介绍了,/etc/subgid 相应就是用户组的标识。具体感兴趣可以去了解。

现在我们再执行上面之前测试的命令。

docker run -it -v /bin:/host/bin busybox /bin/sh

我们还是使用 dj 这个用户,但是它已经没有权限修改从宿主机 /bin 映射到容器的/host/bin的目录了。

并且使用 id 命令,可以看到容器内部是 root 用户,但实际上它在容器外并不是root 用户。

另外还可以查找容器的PID(进程号),通过容器的进程号,来查看它的命名空间。

docker inspect -f '{{.State.Pid}}' <容器名称或ID> # 查看容器的PID

查看进程命名空间: 

cat /proc/${容器PID}/uid_map

 

/proc/5517/uid_map 它表示了容器内外用户的映射关系即将host 上的 231072 用户映射为容器内的 0 即 root 用户。

这说明通过使用 user namespace 使得容器内的进程运行在非 root 用户上,我们成功地限制了容器内进程的权限

 

七、Docker 为什么不默认启用 User namespace呢?

编写这一小章节的时候,我原打算去找资料啦,因为我已经猜测到一些原因,但需要验证一下,但是看到还没关闭的 GPT窗口,就打算拿它试一下。答案如下:

 

结论也很容易得出,Docker 希望降低复杂性,获取更强的兼容性,降低故障排查难度,也希望降低普通开发人员的使用门槛,更好的推广。 

八、Namespace 存在的问题

我们都知道 Namespace 的隔离是轻量化的,比起虚拟化的隔离,它的缺陷也很明显,就是无法进行彻底的隔离

因为不管如何隔离,它都是依赖于同一个内核的,那么此时内核就成了所有容器的共享变量,改动了一次,就会影响到全部。

九、检查 linux 操作系统是否启用了 namespace

运行下面的命令即可检查是否启用了:

root@ubuntu:/home# uname -a
Linux ubuntu 5.15.0-78-generic #85~20.04.1-Ubuntu SMP Mon Jul 17 09:42:39 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

root@ubuntu:/home# cat /boot/config-5.15.0-7
config-5.15.0-76-generic  config-5.15.0-78-generic  
    
root@ubuntu:/home# cat /boot/config-5.15.0-78-generic | grep CONFIG_USER_NS
CONFIG_USER_NS=y
    
root@ubuntu:/home#

如果是 「y」,则启用了,否则未启用。同样地,可以查看其它 namespace:

CONFIG_UTS_NS=y
CONFIG_IPC_NS=y
CONFIG_USER_NS=y
CONFIG_PID_NS=y
CONFIG_NET_NS=y

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1215212.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

12-2- DCGAN -简单网络-卷积网络

功能 随机噪声→生成器→MINIST图像。 训练方法 1 判别器的训练,首先固定生成器参数不变,其次判别器应当将真实图像判别为1,生成图像判别为0 loss=loss(real_out, 1)+loss(fake_out, 0) 2 生成器的训练,首先固定判别器参数不变,其次判别器应当将生成图像判别为1 loss =…

如何避免在Flask中使用Response对象

在Flask框架中&#xff0c;Response对象的__bool__和__nonzero__方法被重载&#xff0c;以便返回一个表示HTTP响应状态是否为’OK’的布尔值。然而&#xff0c;这可能会导致一些预期之外的行为。 解决方案 对于上述问题&#xff0c;可以通过直接检查Response对象的ok属性来避…

在哪里可以制作一本精美的翻页产品册呢?

你是否曾经为了一张可滑动的画册而翻看了整个产品册&#xff1f;翻页产品册是一种数字化的画册形式&#xff0c;它可以在电脑、手机、平板等设备上进行浏览和阅读。相比传统的纸质画册&#xff0c;翻页产品册有着更多的优势和用途。那么&#xff0c;在哪里可以制作一本这种精美…

解决requests库中session.verify参数失效的问题

在使用requests库进行HTTP请求时&#xff0c;如果在环境变量中设置了’REQUESTS_CA_BUNDLE’&#xff0c;并且在session对象中设置了verify参数为False&#xff0c;那么API请求会使用环境变量中的值而不是session对象中的值。这是因为在requests库中&#xff0c;当session对象中…

(十一)Flask模板引擎jinja2

模板引擎Jinja2 一、简介及基本使用&#xff1a; Flask使用Jinja2作为默认的模板引擎。Jinja2是一个功能强大且易于使用的模板引擎&#xff0c;它允许我们在HTML中嵌入Python代码&#xff0c;并通过将模板和数据进行渲染来生成动态内容。 实战之在Flask中使用Jinja2模板引擎…

GDS 命令的使用 srvctl service TAF application continuity

文档中prim and stdy在同一台机器上&#xff0c;不同机器需要添加address list TAF ENABLED GLOBAL SERVICE in GDS ENVIRONMNET 12C. (Doc ID 2283193.1)​编辑To Bottom In this Document Goal Solution APPLIES TO: Oracle Database - Enterprise Edition - Version 12.1.…

操作系统(五)文件系统和I/O系统

文章目录 前言文件系统文件系统和文件文件描述符目录、文件别名和文件系统分层文件系统目录实现文件别名名字解析&#xff08;路径遍历&#xff09;文件系统挂载文件系统种类 虚拟文件系统文件缓存和打开文件打开文件 文件分配空闲空间管理和冗余磁盘阵列RAID空闲空间管理冗余磁…

小程序游戏、App游戏与H5游戏:三种不同的游戏开发与体验方式

在当今数字化的时代&#xff0c;游戏开发者面临着多种选择&#xff0c;以满足不同用户群体的需求。小程序游戏、App游戏和H5游戏是三种流行的游戏开发和发布方式&#xff0c;它们各自具有独特的特点和适用场景。 小程序游戏&#xff1a;轻巧便捷的社交体验 小程序游戏是近年来…

为什么都说学医的转行网络安全行业更容易些?

网络系统坏了&#xff0c;被入侵破坏了&#xff0c;找安全工程师防护修补。如果没有修好&#xff0c;我可以不给钱&#xff0c;再找一家能修好的。但是看病就不一样了&#xff0c;就算医生没有给我治好病&#xff0c;也照样要收医疗费。 这样的类比乍一听上去好像挺有道理&…

解析:什么是生成式AI?与其他类型的AI有何不同?

原创 | 文 BFT机器人 快速浏览一下头条新闻&#xff0c;你会发现生成式AI似乎无处不在。事实上&#xff0c;一些新闻标题甚至可能是通过生成式AI编写的&#xff0c;例如OpenAI旗下的ChatGPT&#xff0c;这个聊天机器人已经展现出了生成看起来像人类所写文本的惊人能力。 当人们…

蓝桥杯每日一题2023.11.16

蓝桥杯大赛历届真题 - C 语言 B 组 - 蓝桥云课 (lanqiao.cn) 题目描述 对于此代码&#xff0c; 注释解释如下&#xff1a;答案&#xff1a;f(a,k1,m-j,b)&#xff1b; 在这里插入代码片#include <stdio.h> #define N 6 #define M 5 #define BUF 1024 void f(int a[], in…

市场研究报告:量子计算将颠覆银行业!

&#xff08;图片来源&#xff1a;网络&#xff09; 量子银行将对金融体系产生重大影响&#xff0c;它在量子计算和区块链的基础上建立了一个更快的支付机制&#xff0c;并且通过消除传统点对点支付中常见的中间人&#xff0c;降低了运营成本。 量子计算及其运作机制 中东地区…

【人工智能实验】遗传算法求解旅行商问题 golang

人工智能经典问题旅行商求解 使用遗传算法求解&#xff0c;算法流程如下&#xff1a; 读取所有的城市坐标&#xff0c;记作集合initCitys生成popSize个种群&#xff0c;记为pops取出种群中适应度最高的&#xff0c;记作rank0使用轮盘算法&#xff0c;从rank0中选出eliteSize个…

Redis分布式锁(中)

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 我们在不久前介绍了Spr…

【场景】高并发解决方案

文章目录 1. 硬件2. 缓存2.1 HTTP缓存2.1.1 浏览器缓存2.1.2 Nginx缓存2.1.3 CDN缓存 2.2 应用缓存 3 集群4. 拆分4.1 应用拆分&#xff08;分布式、微服务&#xff09;4.2 数据库拆分 5. 静态化6. 动静分离7. 消息队列8. 池化8.1 对象池8.2 数据库连接池8.3 线程池 9. 数据库优…

酷开系统 酷开科技,将家庭娱乐推向新高潮

在当今数字化时代&#xff0c;家庭娱乐已经成为人们日常生活中不可或缺的一部分。如果你厌倦了传统的家庭娱乐方式&#xff0c;想要一种全新的、充满惊喜的娱乐体验&#xff0c;那么&#xff0c;不妨进入到酷开科技的世界&#xff0c;作为智能电视行业领军企业&#xff0c;酷开…

Git常用操作-MD

文章目录 1. 本地创建分支&#xff0c;编写代码&#xff0c;提交本地分支到远程仓库2. 提交本地代码到本地仓库3. 提交本地代码到本地dev分支4. 提交本地dev分支到远程仓库5. 本地dev分支拉取远程master分支&#xff0c;并将master分支内容合并到本地dev6. 同义命令7. 撤销上次…

Codeforces Round 908 (Div 2——AB)

A. Secret Sport 题目 AB二人玩游戏&#xff0c;每一局&#xff08;plays&#xff09;游戏会有一个获胜者&#xff0c;首先获胜X局&#xff08;play&#xff09;的玩家得一分&#xff08;赢得一轮sets&#xff09;。率先获得Y分的玩家获得最终胜利。 给你整场游戏的每局&…

Spring Boot使用EhCache完成一个缓存集群

在上一篇在SpringBoot中使用EhCache缓存&#xff0c;我们完成了在Spring Boot中完成了对EhCaChe的使用&#xff0c;这篇&#xff0c;我们将对EhCache的进一步了解&#xff0c;也就是搭建一个EhCache的缓存集群。 集群 在搭建一个EhCache的时候&#xff0c;我们需要先了解&…

areadetector ADURL模块应用在面探测控制的初步应用

本章中讨论了使用ADURL控制面探测器Lambda的过程&#xff1a; ADURL的使用请见&#xff1a; EPICS -- areaDetector URL驱动程序-CSDN博客 需要启动一个ADURL的IOC程序&#xff0c;并且设置相关的插件中参数的值&#xff1a; # st.cm < envPaths < st_base.cmddbpf 1…