《你好架构师之 压榨硬件价值的利器容器 (Docker)》
无论你选择吃下红药丸还是蓝药丸,世界总是强者恒强。如腾讯、阿里这样的互联网帝国,总是生长在过剩的硬件资源之上。为了能够将这些在如双十一之外的日子里闲置的资源加以利用,勤俭持家的工程师们提议将它们打包成产品销售给大众。那么应该如何将硬件资源量化从而产生出最终售卖的产品呢。此刻应想起我们滴第一条架构废物理论:
任何混乱复杂的架构,都可以通过增加中间层来简化
而这个硬件与操作系统之间的层就是"虚拟化"。其技术特点就是通过增加虚拟化层,为运行在其上的操作系统,模拟出一整套完整的硬件体验,而运行在虚拟环境中的应用程序对硬件资源的调度,都通过这个中间层传导,并最终实现硬件资源的调度。
当然你也听出了问题所在,这一过程是需要消耗额外的性能的。更直观的感受是,通常所见的虚拟化环境的操作系统,如vmware的虚拟系统文件足有2~4G之巨。
有浪费就有勤俭的手段,为了省去虚拟程序在应用程序与硬件资源之间的中间商赚差价,也为了更加有效的利用硬件资源的能力,就有了如今常见的“容器”技术。它也被称之为“轻量级虚拟化技术”。
请记住: 一个个“轻量”虚拟化技术的产物:容器实例。在系统层面依然是一个的进程。这是容器与虚拟化的技术最大的区别。
换言之,容器技术其实就是对进程级别进行的资源限制、系统文件(视图限制,如PID、挂载目录...)限制这类技术的总称。仅此而已。
如何验证?
容器内,认为自己是1号进程
而真实情况他的PID:8662进程,
以上现象也就证实了容器不过是操作系统中的一个简单进程。
如何实现对容器进程的视图限制呢?
这种屏蔽真实进程号的技术,就是Linux的Namespace机制。该机制其实是Linux创建新进程时的一个可选参数。在Linux系统中创建线程的系统调用时clone()
int pid = clone(main_function, stack_size, SIGCHLD,NULL);
该函数在系统调用后将会为我们创建一个新的进程,并且返回它的进程号pid。调用时指定CLONE_NEWPID参数,新创建的这个进程就会看到一个全新的进程空间,它的PID是1。
int pid = clone(main_function, stack_size, CLONE_NEWPID | SIGCHLD, NULL);
而除了这里的PID Namespace,Linux系统还提供了Mount、UTS、IPC、Network、User这些Namespace,用来对各种不同的进程上下文进行“障眼法”操作。
Mount Namespace,用于让被隔离进程只看到当前Namespace里的挂载点信息;
Network Namespace,用于让被隔离进程看到当前Namespace里网络设备和配置;
我以为我就是根目录
我以为我用是eth0
以上的“障眼法”只能影响到应用进程如何看待整个计算机的“视图”,但资源依然共享着整个计算机的资源。
那么对进程的资源限制是如何实现的呢?
它就是Linux Control Group。它的主要作用,就是限制一个进程组能够使用的资源上限,包括CPU、内存、磁盘、网络带宽等等。
此外Cgroups还能对进程进行优先级设置、审计,以及将进程挂起和恢复等操作。
mount -t cgroup
mount -t cgroup 可以用于查询系统中已经mount 的cgroup的文件系统,这里的t表示type
ls -l /sys/fs/cgroup
我们来尝试控制镜像的资源吧?
1. 创建contianer目录,自动添加一下内容
root@ubuntu:/sys/fs/cgroup/cpu$ mkdir container
root@ubuntu:/sys/fs/cgroup/cpu$ ls container/
输出:
cgroup.clone_children cpu.cfs_period_us cpu.rt_period_us cpu.shares notify_on_releasecgroup.procs cpu.cfs_quota_us cpu.rt_runtime_us cpu.stat tasks
2.其中cpu.cfs_quota_us和cpu.cfs_period_us,表示container控制组里的CPU quota没有任何限制(即:-1),CPU period则是默认100ms(100000us)
--cpu-period(周期),--cpu-quota(配额)
例如: --cpu-period=1000000 --cpu-quota=500000 1秒周期内能使用0.5秒(50%的CPU使用权)
建立测试脚本: 假设脚本PID为226
while : ; do : ; done &[1] 226
将cfs_quota修改为20ms(20000us):在每100ms时间里,该控制组限制的进程只能使用20ms的CPU时间,也就是这个进程只能使用到20%的CPU带宽
echo 20000 > /sys/fs/cgroup/cpu/container/cpu.cfs_quota_us
将task文件内容修改为脚本的PID: 之前修改的设置会对写入task进程生效
echo 226 > /sys/fs/cgroup/cpu/container/tasks
可以查看到的现象: CPU的使用率立刻降到了20%
除了CPU子系统外,Cgroups的每一项子系统都拥有独有的资源限制能力,例如:
blkio,为块设备设定I/O限制,一般用于磁盘设备;
cpuset,为进程分配单独的CPU核和对应的内存节点;
memory,为进程设定内存使用的限制;
好了到此先打住。
填充的架构板块:
架构黑话之一:任何混乱复杂的架构,都可以通过增加中间层来简化
版权声明: 本文为 InfoQ 作者【再见小飞侠】的原创文章。
原文链接:【http://xie.infoq.cn/article/d24ba9f039d029245a16d14f1】。
本文遵守【CC BY-NC】协议,转载请保留原文出处及本版权声明。
评论