1. UTS namespace

UTS(UNIX Time-sharing System)namespace提供了主机名和域名的隔离,这样每个Docker容器就可以拥有独立的主机名和域名了,在网络上可以被视为一个独立的节点,而非宿主机上的一个进程。Docker中,每个镜像基本都以只身所提供的服务名称来命名镜像的hostname,且不会对宿主机产生任何影响,其原理就是利用了UTS namespace。

2. IPC namespace

进程间通信(Inter-Process Communication,IPC)涉及的IPC资源包括常见的信号量、消息队列和共享内存。申请IPC资源就申请了一个全局唯一的32位ID,所以IPC namespace中实际上包含了系统IPC标识符以及实现POSIX消息队列的文件系统。在同一个IPC namespace下的进程彼此可见,不同IPC namespace下的进程则互相不可见。

3. PID namespace

PID namespace隔离非常实用,对进程PID重新标号,即两个不同 namespace的进程可以有相同的PID。每个 PID namespace都有自己的计数程序。内核为所有的 PID namespace维护了一个树状结构,最顶层的是系统初始时创建的,被称为 root namespace它创建的新 PID namespace被称为 child namespace(树的子节点),而原先的 PID namespace就是新创建的 namespace的parent namespace(树的父节点)通过这种方式,不同的 PID namespaces会成一个层级体系。所属的父节点可以看到子节点中的进程,并可以通过信号等方式对子节点中的进程产生影响。反过来,子节点却不能看到父节点 PID namespace中的任何内容,由此产生如下结论

  1. 每个 PID namespace中的第一个进程“PID1”,都会像传统 Linux中的init进程一样拥有特权,起特殊作用。
  2. 一个 namespace中的进程,不可能通过kill或 ptrace影响父节点或者兄弟节点中的进程,因为其他节点的PID在这 namespace个中没有任何意义。
  3. 如果你在新的 PID namespace中重新挂载/proc文件系统,会发现其下只显示同属一个pid namespace中的其他进程。
  4. 在 root namespace中可以看到所有的进程,并且递归包含所有子节点中的进程。

到这里,读者可能已经联想到一种在外部监控Docker中运行程序的方法了,就是监控Docker daemon所在的PID namespace下的所有进程及其子进程,再进行筛选即可。

4. mount namespace

mount namespace通过隔离文件系统挂载点对隔离文件系统提供支持,它是历史上第一个 Linux namespace,所以标识位比较特殊,就是 CLONENEWNS。隔离后,不同 mount namespace中的文件结构发生变化也互不影响。可以通过/proc/[pid]/mounts看到所有挂载在当前中的文件系统,还可以通过proc/[pid]/mountstats到 mount namespace中文件设备的统计信息,包括挂载文件的名字、文件系统类型、挂载位置等。

进程在创建 mount namespace时,会把当前的文件结构复制给新的 namespace。新 namespace中的所有 mount操作都只影响自身的文件系统,对外界不会产生任何影响。这种做法非常严格地实现了隔离,但对某些情况可能并不适用,比如父节点 namespace 中的进程挂载了一张CD-ROM, 这时子节点 namespace复制的目录结构是无法动挂载上这张CD-ROM的,因为这种操作会影响到父节点的文件系统

2006年引入的挂载传播( mount propagation)解决了这个问题,挂载传播定义了挂载对象( mount object)之间的关系,这样的关系包括共享关系和从属关系,系统用这些关系决定任何挂 载对象中的挂载事件如何传播到其他挂载对象。

  • 共享关系( share relationship)。如果两个载对象具有共享关系,那么一个挂载对象中 的挂载事件会传播到另一个挂载对象,反之亦然。
  • 从属关系( slave relationship)。如果两个挂载对象形成从属关系,那么一个挂载对象中的接收者。 的挂载事件会传播到另一个挂载对象,但是反之不行;在这种关系中,从属对象是事件的接收者。

一个挂载状态可能为以下一种:

  • 共享挂载(share)
  • 从属挂载(slave)
  • 共享从属挂载(shared and slave)
  • 私有挂载(private)
  • 不可绑定挂载(unbendable)

传播事件的挂载对象称为共享挂载;接收传播事件的挂载对象称为从属挂载;同时兼有前述两者特征的挂载对象称为共享从属挂載;既不传播也不接收传播事件的挂载对象称为私有挂载;另一种特殊的挂载对象称为不可绑定的挂载,它们与私有挂载相似,但是不允许执行绑定挂载,即创建 mount namespace时这块文件对象不可被复制。通过下图可以更好地了解它们的状态变化。

mount各类挂载状态示意图:

5. network namespace

当我们了解完各类 namespace,兴致勃勃地构建出一个容器,并在容器中启动一个 Apache进程时,却出现了“80端口已被占用”的错误,原来主机上已经运行了一个 Apache进程,这时就要借助 Network namespace技术进行网络隔离。

network namespace主要提供了关于网络资源的隔离,包括网络设备、IPv4和IPv6协议栈、IP路由表、防火墙、/proc/net目录、/sys/ Class/net目录、套接字( socket)等。一个物理的网络设备最多存在于一个 network namespace中,可以通过创建 veth pair(虚拟网络设备对:有两端类似管道,如果数据从一端传入另一端也能接收到,反之亦然)在不同的 network namespace间创建通道,以达到通信目的。

一般情况下,物理网络设备都分配在最初的 root namespace(表示系统默认的 namespace)中。但是如果有多块物理网卡,也可以把其中一块或多块分配给新创建的 network namespace。需要注意的是,当新创建的 network namespace被释放时(所有内部的进程都终止并且 namespace文件没 有被挂载或打开),在这个 namespace中的物理网卡会返回到 root namespace,而非创建该进程的父 进程所在的 network namespace 。

当说到 network namespace时,指的未必是真正的网络隔离,而是把网络独立出来,给外部用户一种透明的感觉,仿佛在与一个独立网络实体进行通信。为了达到该目的,容器的经典做法就是创建一个 veth pair,一端放置在新的 namespace中,通常命名为eth0,一端放在原先的 namespace 中连接物理网络设备,再通过把多个设备接入网桥或者进行路由转发,来实现通信的目的。

也许读者会好奇,在建立起 veth pair之前,新旧 namespace该如何通信呢?答案是pipe(管道)。以 Docker daemon,启动容器的过程为例,假设容器内初始化的进程称为 init docker daemon在宿主机上负责创建这个 veth pair,把一端绑定到 docker网桥上,另一端接入新建的 network namespace进程中。这个过程执行期间,Docker daemon和init就通过pipe进行通信。具体来说,就是在 Docker daemon完成 veth pair的创建之前,init在管道的另一端循环等待,直到管道另一端传来 Dockerdaemon关于veth设备的信息,并关闭管道。init才结束等待的过程,并把它的“eth0”启动起来。

6. user namespaces

user namespace主要隔离了安全相关的标识符( identifier)和属性( attribute),包括用户ID用户组D、root目录、key(指密钥)以及特殊权限。通俗地讲,一个普通用户的进程通过 clone()创建的新进程在新 user namespace中可以拥有不同的用户和用户组。这意味着一个进程在容器外属于一个没有特权的普通用户,但是它创建的容器进程却属于拥有所有权限的超级用户,这个技术为容器提供了极大的自由。

Docker namespace技术(九)相关推荐

  1. Docker基础技术:Linux Namespace【上】

    点点收获: //之前发现Coolshell上好久不更新了, 博主果然去搞大业去了,只恨这几篇文章看到太晚了啊~太厉害了. 1.  clone(), unshare(), setns()初识; 主要是š ...

  2. Docker 基础技术之 Linux namespace 详解

    本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. Docker ...

  3. Docker 基础技术之 Linux namespace 源码分析

    上篇我们从进程 clone 的角度,结合代码简单分析了 Linux 提供的 6 种 namespace,本篇从源码上进一步分析 Linux namespace,让你对 Docker namespace ...

  4. 一文看懂docker容器技术架构及其中的各个模块

    概述 今天主要简单介绍下docker的技术架构及其中组成的各个模块. 技术架构 distribution 负责与docker registry交互,上传洗澡镜像以及v2 registry 有关的源数据 ...

  5. k8s 重要概念 - 每天5分钟玩转 Docker 容器技术(117)

    在实践之前,必须先学习 Kubernetes 的几个重要概念,它们是组成 Kubernetes 集群的基石. Cluster  Cluster 是计算.存储和网络资源的集合,Kubernetes 利用 ...

  6. DaemonSet 典型应用场景 - 每天5分钟玩转 Docker 容器技术(129)

    Deployment 部署的副本 Pod 会分布在各个 Node 上,每个 Node 都可能运行好几个副本.DaemonSet 的不同之处在于:每个 Node 上最多只能运行一个副本. DaemonS ...

  7. Kubernetes Dashboard - 每天5分钟玩转 Docker 容器技术(173)

    前面章节 Kubernetes 所有的操作我们都是通过命令行工具 kubectl 完成的.为了提供更丰富的用户体验,Kubernetes 还开发了一个基于 Web 的 Dashboard,用户可以用 ...

  8. Docker底层技术

    架构师之巅 1 容器 & Docker & 虚拟机 Container(容器)是一种轻量级的虚拟化技术,它不需要模拟硬件创建虚拟机.在Linux系统里面,使用到Linux kernel ...

  9. 部署 k8s Cluster(下)- 每天5分钟玩转 Docker 容器技术(119)

    上节我们通过 kubeadm 在 k8s-master 上部署了 Kubernetes,本节安装 Pod 网络并添加 k8s-node1 和 k8s-node2,完成集群部署. 安装 Pod 网络 要 ...

最新文章

  1. Oracle创建用户并给用户授权查询指定表或视图的权限
  2. 十、散列表(Hash Table)
  3. jmc线程转储_使线程转储智能化
  4. 和css3实例教程_最好CSS和CSS3教程
  5. Cocos2d手机游戏引擎介绍
  6. Kali Linux Web 渗透测试秘籍 第四章 漏洞发现
  7. rpm安装mysql
  8. 如何使用Hue上创建一个完整Oozie工作流
  9. 一个react项目案例01 组件部分
  10. React 入门第一天(小案例和注意细节)
  11. Atitit 信息系统安全法 目录 1. 常见的安全保护目标 1 2. WEB安全风险行为 2 2.1. Injection 2 2.2. Broker Authentication损坏的身份验证
  12. EI收录的中国(中文)期刊(2021版)
  13. spyder python下载_Spyder Python软件-Spyder Python下载-最火软件站
  14. opencv怎么安装?opencv下载安装教程
  15. 测试人员日常基本工作流程
  16. 如何下载中文和英文的全文专利
  17. liunx篇---测试过程中什么时候会用到liunx。常用的命令有哪些?
  18. 异常记录---Error creating bean with name 'sqlSessionFactory'
  19. 由移动价值链到知识价值链─裕隆日产汽车案例
  20. windows update服务不能正常开启

热门文章

  1. zerodivisionerror什么意思python-python代码里出现是啥意思
  2. python基础第三章选择结构答案-python3 学习笔记(二)选择结构、循环结构
  3. python免费入门手册-python基础入门手册。。。。。。
  4. python写程序求1-3+5-7+...-99+101的值-python基本练习
  5. git clone 出现错误 Could not resolve host: github.com
  6. LeetCode 316 Remove Duplicate Letters(删除重复字符)
  7. hdu1443 Joseph(约瑟夫环)
  8. mysql的学习总结
  9. Activity的使用(七):activity的返回值
  10. concurrenthashmap在1.8和1.7里面有什么区别