当前位置: 首页 > news >正文

Docker原理详细剖析-Namespace

一、简介

    docker容器技术从2013年开始火了以后,2014年左右当时有幸在学校能和学院教授一起做些项目以及学习。其中docker技术在当时来说还算是比较新的技术,国内关于这块的资料以及使用也才刚刚开始,讨论docker技术,算是相对时髦的话题。 现在回头望去,已经10年有余,很佩服当时带领我们学习新技术的教授导师,看到这个技术的前景,所以接触的相对早,对后面我的工作起到了相当大的帮助。当时我还写了一篇关于如何通俗理解docker的博客文章,也得到了大多数朋友的支持和点赞~。 附上原文地址,入门的同学可以看下。

    原文链接: docker通俗理解

    Docker并没有创造了什么新的技术,所有用到的技术都是已经存在的, docker将这些技术进行了很好地组合与融汇, 降低了开发者使用容器技术的门槛。 核心来讲, Docker使用了:

        1、Linux 提供的namespace隔离技术(解决了进程"视野隔离"问题, 进程之间互不影响,达到隔离的目的)

        2、Linux提供的cgroups资源限制技术(可以针对进程进行资源限制)

    还未入门和使用过Docker的同学建议熟练使用docker后再回头看这篇文章,要不然效果适得其反~

    本章针对namespace做个剖析, 看下背后实现的基本原理。

二、Namespace隔离技术

1、为什么需要Namespace隔离技术?

    Docker本质上是一种虚拟化技术,属于进程级别的虚拟化。 既然是进程级别的虚拟化,那就是运行在不同容器的进程,彼此之间资源以及"视野"(进程所处上下文环境)是不同的。 例如我在A容器运行一个p1进程, 同时在B容器运行一个p2进程, 此时分别在A和B容器运行 ps aux, 看到的内容是不一样的。

    如果没有namespace技术做隔离,那么我们运行的这些进程彼此之间可以感知,看到的"视野"也是一样的,那就无法做到隔离的效果。

2、Namespace隔离进程的本质

    运行容器以后, 需要运行一个”主进程”, 这个进程本质上和宿主机的其他进程没太多差别, 只是这个进程看到的“视野”被namespace框住了,只看到自己namespace里面的东西,看不到宿主机上的东西(因为例如在容器和宿主机执行 lsifconfig命令,两者命令所处的mount namespacenet namespace不同,所以看到的内容自然不同)。

    简单理解, Linux的某种namespace,例如在【视觉】上, 类似给某个人带了"VR眼镜", "VR眼镜"可以将人的视野框起来,现实中你是在床上睡觉(房间就是宿主机), 但是你为了玩游戏感觉更加逼真, 带上"VR眼镜"眼镜的视野就可以身临其境。 但是只有【视觉】身临其境好像还差点意思,此时再给你的【触觉】带上MR混合虚拟设备,这时候就有了模拟触觉体验会更棒,这又是附加了另外一种namespace隔离。
     

3、Linux提供了哪些类型的Namespace

   为了让被虚拟的进程更加"身临其境", Linux内核提供了6种namespace隔离类型与系统调用:

    例如主机和域名隔离、信号量隔离、进程PID隔离、网络隔离、挂载隔离、用户信息隔离等。给你的进程套上"虚拟设备", 这样你的进程看到的"视野"和其他进程的"视野"就不一样。

     我们运行了一个简单的docker容器,我们可以查看到, 这个命令虽然在Docker容器内运行, 但是宿主机对应路径/proc/$pid/ns中就被分配了各种namespace:

      

    两个进程所处的nemspace不同也就意味着,这两个进程看到的“视野”不同,这个概念很重要.

    那反过来讲,如果我们要2个进程可以看到相同“视野”,那么有没有某种机制,让一个进程共享或者切换自己的namespace到目标进程的namespace呢? 这样原进程就可以看到和目标进程一样的“视野”了.

    答案是存在的, Linux中存在一个系统调用函数 setns   可以通过系统调用,让某个原进程的namespace切换为目标进程的namespace .

   其实docker exec -it /bin/sh 进入一个容器,本质上就是docker cli运行命令, 内部调用setns系统调用(system call), 指定 目标进程id namespace路径: /proc/$pid/ns/ 下的namepscae和要执行的命令/bin/sh传递进去. 这样这个docker cli就能和目标容器看到的“视野”是一样的.

4、验证docker exec /bin/sh,/bin/sh的namespace和容器进程tail 的 namespace是否一致

1、运行一个busybox的容器, 主进程是 tail -f /dev/null

2、宿主机ps aux | grep ‘tail’ 看下这个容器启动进程,在宿主机的实际pid是多少?

拿到实际进程PID:  29493

3.此时我们进入/proc/29493/ns/, 查看下namespace的信息,先做下记录,后续用到.

4.docker-compose exec bb /bin/sh运行进入容器,此时查看宿主机真实进程pid信息:

10325是docker-compose, 子进程是docker cli(10333),  最后, /bin/sh进程pid应该是10372.

5. 查看下/proc/10372/ns的namespace内容, 经过和步骤3的图(容器tail真实进程pid下的ns目录内容)对比,完全一致. 此时通过docker-compose exec bb /bin/sh进入容器后,例如执行ps aux,那么看到的“视野”和容器内部进程的“视野”是一样的,就达到了进入容器查看的目的.

容器内执行ps axu

http://www.lryc.cn/news/158222.html

相关文章:

  • sql:SQL优化知识点记录(九)
  • 【PowerQuery】PowerQuery导入JSON数据
  • bootstrap 主题
  • FPGA 学习笔记:Vivado 工程管理技巧
  • Java低代码开发:jvs-list(列表引擎)功能(二)字段及样式配置
  • 【Java】线程都有哪几种状态
  • 为什么服务端会有那么多的 TimeWait ?
  • 任意文件读取及漏洞复现
  • 目前的一些关于机器学习的感悟
  • salesforce从sandbox部署到生产环境的自定义字段权限没有成功上载
  • 字节跳动推出AI对话工具“豆包”:免费用
  • 时序预测 | MATLAB实现TCN-LSTM时间卷积长短期记忆神经网络时间序列预测
  • 代码随想录训练营二刷第十五天 | 层序遍历10道 226.翻转二叉树 101.对称二叉树 2
  • nowcoder NC10 大数乘法
  • 非科班菜鸡算法学习记录 | 代码随想录算法训练营第58天|| 单调栈! 739. 每日温度 496.下一个更大元素 I
  • 【Luogu】 P5445 [APIO2019] 路灯
  • Kafka3.0.0版本——消费者(独立消费者消费某一个主题中某个分区数据案例__订阅分区)
  • 基于Simulink的用于电力系统动态分析
  • 日200亿次调用,喜马拉雅网关的架构设计
  • 构造函数和析构函数(个人学习笔记黑马学习)
  • GPT引领前沿与应用突破之GPT4科研实践技术与AI绘图教程
  • Git上传新项目
  • C语言文件操作总结
  • 原生js之dom如何进行事件监听(事件捕获/冒泡)
  • 使用SimPowerSystems并网光伏阵列研究(Simulink实现)
  • BUUCTF-WEB-[ACTF2020 新生赛]Includel
  • 算法通关村十四关:白银挑战-堆能高效解决的经典问题
  • 跨站请求伪造(CSRF)攻击与防御原理
  • 从0到1实现播放控制器
  • 【Vue-Element-Admin】导出el-table全部数据