Docker学习总结(一)—— namespace,cgroup机制
1.namespace:
Linux Namespaces机制提供一种资源隔离方案。PID,IPC,Network等系统资源不再是全局性的,而是属于特定的Namespace。每个
Namespace里面的资源对其他Namespace都是不可见的,要创建新的Namespace,只需要在调用clone时指定相应的flag。Linux
Namespaces机制为实现基于容器的虚拟化技术提供了很好的基础,容器正是利用这一特性实现了资源的隔离。不同container内的
进程属于不同的Namespace,彼此透明,互不干扰。
Linux很早就实现了一个系统调用chroot,该系统调用能够为进程提供一个限制的文件系统。chroot提供了一种简单的隔离模式:chroot
内部的文件系统无法访问外部的内容。Linux Namespace在此基础上,提供了对UTS、IPC、mount、PID、network的隔离机制。
UTS: 包含了运行内核的名称,版本,底层体系结构的信息
IPC: 包含了所有与进程间通信有关的信息
PID: 就是进程ID
mount: 包含了文件系统的视图
NET: 网络访问
  1.1 task_struct中的结构:
struct task_struct { 
... 
struct nsproxy *nsproxy; 
... 
};
<——————将给定进程关联到所属的各个命名空间——————>
struct nsproxy { 
atomic_t count; 
struct uts_namespace *uts_ns; 
struct ipc_namespace *ipc_ns; 
struct mnt_namespace *mnt_ns; 
struct pid_namespace *pid_ns; 
struct net *net_ns; 
};
1.2 创建命名空间的方式
1.2.1. clone创建新进程时,可以设置选项,使新进程与父进程共享命名空间,还是新进程创建一个独立的命名空间.
1.2.2. unshare系统调用,可以将进程的某些部分从父进程分离,其中也包括命名空间。
1.3 PID
PID命名空间按层次组织,在创建一个新的pid namespace,该命名空间中所有的pid都对父命名空间可见,但是子命名空间
看不到父命名空间的pid,因此进程在不同的pid namespace中具有不同的pid,只要能看到该进程的namespace都有一个PID。
对于所有的进程来说,都有两种ID:一个是全局的ID(包含PID、TGID、PGRP、SID),保存在task_struct->pid中;
另一个是局部的ID,即属于某个特定的命名空间的ID,对应task_struct->pids数组,可以通过task_struct->pids[pid_type]->pid
来找到对应的pid结构。pid_type:PIDTYPE_PID,PIDTYPE_PGID,PIDTYPE_SID,PIDTYPE_MAX
struct pid 
{ 
atomic_t count; //计数
unsigned int level; //对应多少namespace
struct hlist_head tasks[PIDTYPE_MAX]; //指回task_struct
struct rcu_head rcu; //rcu是将所有struct pid组织起来的辅助结构
struct upid numbers[1]; //numbers成员中存储的是struct upid结构,该结构是pid与pid_namespace相关联的结构。
}
upid
struct upid { 
int nr; 
struct pid_namespace *ns; 
struct hlist_node pid_chain; 
};
所有的upid都保存在一个散列表中,通过upid->pid_chain组织。
static struct hlist_head *pidhash;
};
pid_namespace
struct pid_namespace { 
struct kref kref; 
struct pidmap pidmap[PIDMAP_ENTRIES]; //保存该namespace中pid的分配情况
int last_pid; //保存上一个分配的pid
struct task_struct *child_reaper; //每个namespace都有一个进程来扮演Linux中init进程的角色,child_reaper指向这个进程
struct kmem_cache *pid_cachep; 
unsigned int level; //表示该namespace在整个命名空间的层次
struct pid_namespace *parent; //父namespace
struct vfsmount *proc_mnt; 
struct bsd_acct_struct *bacct; 
};
2.cgroups:限制被namespaces隔离起来的资源,为资源设置权重,计算使用量,操控任务启停。
特点:cgroups通过伪文件系统方式实现
组织管理操作单元细粒度到线程级别,用户也可以创建销毁cgroup实现资源再分配
资源管理的功能都已子系统方式实现,接口统一
子任务创建之初与副任务同出一个cgroups
作用:资源限制:对任务使用的资源总额进行限制
优先级分配:通过分配CPU时间片,IO带宽等来控制任务优先级
资源统计:CPU使用时长,内存用量等
任务控制:任务挂起,恢复等
相互关系: cgroups具有层级结构,每个层级通过绑定对应的子系统进行资源控制,cgoups层级可以包含0或1个子节点。子节点继承
父节点挂载的子系统。
1.一个子系统能附加到多个层级,前提是目标层级只有唯一一个子系统
2.一个层级可以附加多个子系统
3.一个任务可以是多个cgroup的成员,但是这些cgroup必须在不同的层级。
4.系统中的进程(任务)创建子进程(任务)时,该子任务自动成为其父进程所在 cgroup 的成员。然后可根据需要将该子任务移动到不
同的 cgroup 中,但开始时它总是继承其父任务的cgroup。
Cgroups子系统:
blkio -- 这个子系统为块设备设定输入/输出限制,比如物理设备(磁盘,固态硬盘,USB 等等)。
cpu -- 这个子系统使用调度程序提供对 CPU 的 cgroup 任务访问。
cpuacct -- 这个子系统自动生成 cgroup 中任务所使用的 CPU 报告。
cpuset -- 这个子系统为 cgroup 中的任务分配独立 CPU(在多核系统)和内存节点。
devices -- 这个子系统可允许或者拒绝 cgroup 中的任务访问设备。
freezer -- 这个子系统挂起或者恢复 cgroup 中的任务。
memory -- 这个子系统设定 cgroup 中任务使用的内存限制,并自动生成由那些任务使用的内存资源报告。
net_cls -- 这个子系统使用等级识别符(classid)标记网络数据包,可允许 Linux 流量控制程序(tc)识别从具体 cgroup 中生成的数据包。
ns -- 名称空间子系统。
cgroups数据结构:
task_struct中与cgroups有关的:
struct css_set *cgroups;
struct list_head cg_list;
其中cgroups指针指向了一个css_set结构,而css_set存储了与进程相关的cgroups信息。cg_list是一个list_head结构,用于将连到同一个css_set的进程组织成一个链表。
struct css_set {
atomic_t refcount; //该css_set的引用数
struct hlist_node hlist; //用于把所有css_set组织成一个hash表,这样内核可以快速查找特定的css_set
struct list_head tasks; //指向所有连到此css_set的进程连成的链表
struct list_head cg_links; //指向一个由struct cg_cgroup_link连成的链表
struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT]; //subsys是一个数组,存储一组指向cgroup_subsys_state的指针。
};
一个cgroup_subsys_state就是进程与一个特定子系统相关的信息。通过这个指针数组,进程就可以获得相应的cgroups控制信息了
struct cgroup_subsys_state {
struct cgroup *cgroup;
atomic_t refcnt;
unsigned long flags;
struct css_id *id;
};
cgroup指针指向了一个cgroup结构,也就是进程属于的cgroup。进程受到子系统的控制,实际上是通过加入到特定的cgroup实现的,因为cgroup在特定的层级上,而子系统又是附加到层级上的。通过以上三个结构,进程就可以和cgroup连接起来了:task_struct->css_set->cgroup_subsys_state->cgroup。
cgroup和css_set是一个多对多的关系,一个进程对应一个css_set,一个css_set就存储了一组进程(有可能被几个进程共享)跟各个子系统相关的信息,而且一个进程可以同时属于几个cgroup,只要这些cgroup不在同一个层级。一个cgroup中可以有多个进程,而且这些进程的css_set不一定都相同,因为有些进程可能还加入了其他cgroup。
struct cg_cgroup_link {
struct list_head cgrp_link_list;
struct cgroup *cgrp;
struct list_head cg_link_list;
struct css_set *cg;
};
cg_cgroup_link作为一个中间结构将 cgroup和css_set联系起来,cgrp_link_list和cg_link_list分别指向cgroup和css_set所在的链表。每个进程都会指向一个css_set,与这个css_set关联的所有进程都会链入到css_set->tasks链表,cgroup通过中间结构cg_cgroup_link来寻找所有与之关联的所有css_set,从而可以得到与cgroup关联的所有进程。
mount -t cgroup 查看当前系统所有根层级,进入到跟层级目录下,mkdir [名称]就可以创建一个cgroup,新创建的cgroup下的tasks文件为空的,表示当前cgroup无进程,根层级目录下的tasks文件内包含当前系统所有进程。
Docker学习总结(一)—— namespace,cgroup机制的更多相关文章
- Docker实现原理之Namespace,CGroup
		找了几篇这方面的文章,写的还不错,跟大家共享:DOCKER基础技术:LINUX NAMESPACE(上)DOCKER基础技术:LINUX NAMESPACE(下)DOCKER基础技术:LINUX CG ... 
- 利用内核cgroup机制轻松实现类似docker的系统资源管控
		近几年,以docker为代表的容器技术异常火热,它的轻量.高效让人欣喜若狂,它被赋予了改变传统IT运维的使命.相信随着时间推移,以容器云为落地形式的产品将真正实现这一使命. 我们都知道docker能够 ... 
- docker 学习路线
		docker 学习路线 参考资料 知乎 docker 的学习路线 Docker - 从入门到实践 Docker 核心技术与实现原理 Docker 入门 <Kubernetes in Action ... 
- Docker学习笔记之一,搭建一个JAVA Tomcat运行环境
		Docker学习笔记之一,搭建一个JAVA Tomcat运行环境 前言 Docker旨在提供一种应用程序的自动化部署解决方案,在 Linux 系统上迅速创建一个容器(轻量级虚拟机)并部署和运行应用程序 ... 
- Docker 学习应用篇之一: 初识Docker
		Docker 自从2013年以来就非常的火热,无论是从github上的代码活跃度,还是Redhat在RHE6.5中集成对Docker的支持,等等.第一次接触Docker,还是老师给我们介绍的. 1.初 ... 
- Docker学习-Kubernetes - 集群部署
		Docker学习 Docker学习-VMware Workstation 本地多台虚拟机互通,主机网络互通搭建 Docker学习-Docker搭建Consul集群 Docker学习-简单的私有Dock ... 
- Docker学习总结之docker入门
		Understanding Docker 以下均翻译自Docker官方文档 ,转载请注明:Vikings翻译. What is Docker? Docker 是一个开源的平台,设计目标是可以方便开发, ... 
- docker学习资料整理(持续更新中..)
		docker最近可以说火得一踏糊涂,跟 51大神在交流技术的时候这个东西会多次被提到,当我们还玩vm+linux/freebsd的时候,人家已经上升到更高层次了,这就是差距,感觉好高大上的样子,技术之 ... 
- Docker学习总结之Run命令介绍
		Docker学习总结之Run命令介绍 本文由Vikings(http://www.cnblogs.com/vikings-blog/) 原创,转载请标明.谢谢! 在使用Docker时,执行最多的命令某 ... 
- 优秀的云计算工程师需要学什么?云计算Docker学习路线
		云计算工程师要学什么?随着互联网的快速发展,云计算这个词大家并不陌生,但是云计算究竟是做什么的,想要从事云计算要学习什么,很多都不知道,那么今天就给大家讲一下云计算. 云计算是基于互联网的相关服务的增 ... 
随机推荐
- yii2.0 高级版 restful api使用
			1.复制任意个目录(backend)为api 2.打开api下的main.php 修改 id=>app-api,'controllerNamespace' => 'api\controll ... 
- Servlet自动加载
			--初始化数据库连接 在<servlet>标签下 <servlet-name>ServletDemo</servlet-name> <servlet-clas ... 
- flowable DmnEngine和DmnEngineConfiguration
			一.DmnEngineConfiguration创建实例 DmnEngineConfiguration 提供了7个公共的静态方法,用于创建自身实例. 其中5个是使用spring的机制加载配置文件. 另 ... 
- Vim技能修炼教程(14) - 写个ex命令吧
			写个ex命令吧 我们第二节开始就写了语法高亮的插件.这一节,我们学习第二种插件的写法,就是写个我们自己的ex命令. 自定义ex命令的命令是:command,我们在~/.vim/下建立一个plugin目 ... 
- java入门学习(4)— 类,对象理解,如何创建类,对象
			1.什么是类?具有一定相同的属性的对象的集合就叫类.2.对象:类的具体实例,就是类的实例化.比如学生是一个类(student),那学生里面的小红就是一个对象,一个有学生的属性的对象.3.如何定义一个类 ... 
- Luogu 3806 点分治1
			Luogu 3806 点分治 要分清楚各个函数的作用及互相调用的关系. 因为是无根树,找重心的时候,父亲一边的所有节点也可以看做是一颗子树. #include<bits/stdc++.h> ... 
- 如何创建一个基于 MSBuild Task 的跨平台的 NuGet 工具包
			MSBuild 的 Task 为我们扩展项目的编译过程提供了强大的扩展性,它使得我们可以用 C# 语言编写扩展:利用这种扩展性,我们可以为我们的项目定制一部分的编译细节.NuGet 为我们提供了一种自 ... 
- Java--数组转成list,list转数组
			数组转成list: 方法一: String[] userid = {"aa","bb","cc"}; List<String> ... 
- ASP.NET导入导出Excel方法大全
			本文介绍下,C#实现的可以导出与导入excel的代码一例,有需要的朋友,参考下吧. C#实现导出与导入excel.代码1: 复制代码 代码示例:#region 导出Excel /// <su ... 
- BZOJ4543 [POI2014]Hotel加强版
			题意 有一个树形结构,每条边的长度相同,任意两个节点可以相互到达.选3个点.两两距离相等.有多少种方案? 数据范围:n<=100000 分析 参照小蒟蒻yyb的博客. 我们先考虑一个\(O(n^ ... 
