专栏首页和baron一起学习TKE[docker](一)docker-namespaces资源隔离和cgroups资源限制
原创

[docker](一)docker-namespaces资源隔离和cgroups资源限制

Docker内核知识

Docker容器本质上是宿主机上的进程。Docker通过namespaces实现了资源隔离,通过cgroups实现了资源限制,通过写时复制机制(copy-on-write)实现了高效的文件操作。

namespaces资源隔离

想要实现一个资源隔离的容器,首先,根目录/的挂载点需要切换,即文件系统需要隔离;接着,为了在分布式的环境下进行通信和定位,容器必然要有独立的IP、端口、路由等,即网络需要隔离;同时,容器还需要一个独立的主机名以便在网络中标识自己;有了网络,自然离不开通信,即进程间通信需要隔离;不同用户和用户组之间需要用户权限的隔离;最后,运行在容器中的应用需要有进程号(PID),自然需要与宿主机中的PID进行隔离。

由此,基本上完成了一个容器所需要做的6项隔离,Linux内核中提供了这6种namespaces隔离的系统调用,如图所示:

namespaces的6项隔离.png

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

本文讨论的namespace实现针对的均是Linux内核3.8及以后的版本。接下来首先介绍使用namespace的API,然后对6种namespace进行逐一讲解。

1、进行namespaces API 操作的4种方式

namespaces的API包括clone()、setns()以及unshare(),还有/proc下的部分文件。

  • 通过clone()在创建新进程的同时创建namespaces

使用clone()来创建一个独立的namespaces的进程,是最常见的做法,也是Docker使用namespace最基本的方法,它的调用方式如下:

 	int clone(int (*child_func)(void *), void *child_stack, int flags, void *arg);
  • 查看/proc/pid/ns文件

如果两个进程指向的namespace编号相同,就说明它们在同一个namespace下。

  • 通过setns()加入一个已经存在的namespace

通过setns()系统调用,进程从原先的namespace加入某个已经存在的namespace。

  • 通过unshare()在原先进程上进行namespace隔离

调用unshare(),不启动新进程就可以起到隔离的效果,相当于跳出原先的namespace进行操作。

2、UTS namespace

UTS(UNIX Time-sharing System) namespace提供主机名和域名的隔离,这样每个docker容器就可以拥有独立的主机名和域名,在网络上可以被视作一个独立的节点,而非宿主机上的进程了。

3、IPC namespace

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

4、PID namespace

Linux内核为所有的PID namespace维护了一个树状结构,最顶层的是系统初始时创建的,被称为root namespace。它创建的新的PID namespace称为child namespace(树的子节点),而原先的PID namespace就是新创建的PID namespace的parent namespace(树的父节点)。通过这种方式,不同的PID namespace会形成一个层级体系。所属的父节点可以看到子节点中的进程,并可以通过信号等方式对子节点中的进程产生影响,反过来,子节点却不能看到父节点PID namespace中的任何内容。

5、mount namespace

mount namespace通过隔离文件系统挂载点对隔离文件系统提供支持,隔离后,不同mount namespace中的文件结构发生变化也互不影响。

6、network namespace

network namespace主要提供了关于网络资源的隔离,包括网络设备、IPv4、IPv6协议栈、IP路由表、防火墙、/proc/net目录、/sys/class/net目录、套接字(socket)等。一个物理的网络设备最多存在于一个network namespace中,可以通过创建veth pair在不同的network namespace间创建通道,以达到通信目的。

7、user namespace

user namespace主要隔离了安全相关的标识符(identifier)和属性(attribute),包括用户ID、用户组ID、root目录、key(密钥)以及特殊权限。

cgroups资源限制

1、什么是cgroups?

cgroups是Linux内核提供的一种机制,这种机制可以根据需求把一系列系统任务及其子任务整合(或分隔)到按资源划分等级的不同组内,从而为系统资源管理提供一个统一的框架。

本质上来说,cgroups是内核附加在程序上的一系列钩子(hook),通过程序运行时对资源的调度触发相应的钩子以达到资源追踪和限制的目的。

2、cgroups的作用

  • 资源限制:cgroups可以对任务使用的资源总额进行限制,如任务使用资源超出配额就会发出OOM(out of memory)的提示。
  • 优先级分配:通过分配的CPU时间片数量及磁盘IO带宽大小控制任务运行的优先级。
  • 资源统计:cgroups可以统计系统的资源使用量,如CPU使用时长、内存用量等。
  • 任务控制:cgroups可以对任务执行挂起、恢复等操作。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • [Kubernetes](五)Kubernetes多租户管理与资源控制

    namespace是Kubernetes进行多租户资源隔离的主要手段,那么它在系统中的表现形式是什么样的?实现原理和使用方法又是怎样的呢?

    baron
  • 《TKE学习》TKE服务中的HELM应用 (八)

    在Kubernetes中部署容器云应用(容器或微服务编排)是一项有挑战性的工作,Helm就是为了简化在Kubernetes中安装部署容器云应用的一个客户端工具...

    baron
  • [docker](四)docker -- libcontainer

    execdriver如何调用libcontainer加载容器配置container,继而创建真正的Docker容器?

    baron
  • Docker Notes-namespace

    摘要: Docker Notes系列为学习Docker笔记,本文是学习namespace 资源隔离的笔记

    itliusir
  • Docker 技术鼻祖 Linux Namespace 入门系列:Namespace API

    Linux Namespace 是 Linux 提供的一种内核级别环境隔离的方法。用官方的话来说,Linux Namespace 将全局系统资源封装在一个抽象中...

    米开朗基杨
  • k8s基础-命名空间

    k8s命名空间为对象名称提供了一个作用域,我们可以把资源放到不同的命名空间中,这样我们可以使用同名的资源名称,只要保证同一命名空间中的资源名称唯一即可

    dogfei
  • 科研Latex正确姿势

    1.markdown+latex2.office+latex2.1Aurora安装2.2开始使用

    公众号guangcity
  • java架构之路-(微服务专题)nacos集群精讲实战

      上次博客,我们主要说了微服务的发展历程和nacos集群单机的搭建,单机需要-m standalone启动,集群建议使用nginx做一下反向代理,自行保证my...

    小菜的不能再菜
  • 通过Oracle来辅助MySQL数据问题的恢复(r5笔记第31天)

    今天琢磨一个问题,在平时的工作中如果碰到一些不规范的操作,drop,truncate,delete,恢复起来还是很困难的,drop操作在oracle中如果开启了...

    jeanron100
  • MariaDB修改编码格式 转

    2、登录MySQL,使用 show variables like ‘character%’;

    双面人

扫码关注云+社区

领取腾讯云代金券