博文大纲:
一、Docker概述
二、Namespace概念
三、Cgroup基本概念与示例
一、docker容器技术与传统虚拟化技术的比较
Docker容器技术是一个与传统的虚拟化技术有些本质上的差别,传统的虚拟化技术,是站硬件物理资源的基础上,虚拟出多个OS,然后在OS的基础上构建相对独立的程序运行环境,而Docker则是在OS的基础上进行虚拟,所以,Docker轻量很多,因此其资源占用、性能消耗相比传统虚拟化都有很大的优势。
docker容器很快,启动和停止可以在秒级实现,比传统的虚拟化技术要快很多,docker核心解决的问题是利用容器来实现类似VM的功能,从而节省更多的硬件资源,docker容器除了运行其中的应用之外,基本不消耗额外的系统资源,从而在保证性能的同时,减小系统开销,同时,它还可以达到“一次封装,到处运行”的目的。
Docker和传统虚拟化的区别如下:
Docker之所以拥有众多优势,与操作系统虚拟化自身的特点是分不开的。传统虚拟机需要有额外的虚拟机管理程序和虚拟操作系统层,而Docker容器是直接在操作系统层面之上实现的虚拟化,如图:
Docker的使用场景
-
现在需要能方便地创建运行在云平台上的应用,必须要脱离底层的硬件,同时还需要任何时间、地点可获取这些资源,这正是Docker所能提供的。
-
Docker的容器技术可以在一条主句上轻松为任何应用创建一个轻量级的、可移植的、自给自足的容器。通过这种容器打包应用程序,意味着简化了重新部署、调试这些琐碎的重复工作,极大地提高了工作效率。
- 比如:服务器从腾讯云迁移到阿里云,如果采用了Docker容器技术,迁移只需要在新的服务器上启动需要的容器即可。
Docker的优势:灵活性:在复杂的应用都可以被容器化; 轻量级:容器利用共享的是主机的内核; 即时性:可以随时部署更新和升级; 通用性:一次封装,到处运行; 伸缩性:控制容器副本数量来任意伸缩;
二、Namespace概念
虚拟化的技术就是用来解决宿主机与虚拟机之间的耦合问题(简称“解耦”),传统虚拟化技术是属于完全解耦的,而docker这种虚拟化技术是属于半解耦的。
耦合:就是指两个或两个以上的体系或两种运动形式间通过相互作用而彼此影响以至联合起来的现象;
解耦:接触耦合、冲突现象;
Docker是如何解耦的呢?这就需要使用到——Namespace(命名空间)。
Namespace(命名空间):是Linux为我们提供的用于分离进程树、网络接口、挂载点以及进程间通信等资源的方法。
Namespace(命名空间)在docker中主要实现了六项隔离,如图:
Docker通过使用Namespace(命名空间)这项技术实现了容器与容器之间、容器与docker host之间的隔离。
当Docker创建一个容器时,它会创建新的以上六种NameSpace的实例,然后把容器中的所有进程放到这些NameSpace之中,使得容器这个父进程只对自己的子进程有感知,而对于宿主机其他进程一无所知,从而产生一种它就是一个独立的系统的“错觉”。
如果docker 宿主机是centos系统,运行docker容器时,容器也是centos 系统,所必需的目录、文件就是通过docker宿主机进行软连接提供的,包括宿主机的内核;但如果运行的docker容器是Ubuntu系统,其中目录、文件与centos 系统始终是会有一些区别的,那么这就需要使用到——Busybox(欺骗层)。
如果需要使用虚拟机来部署一些服务时,这些服务对内核版本有要求,那么就不太适合使用docker这种虚拟化技术,建议使用KVM等虚拟化技术。
docker这种服务本身并不占用端口,只是保持后台运行。
三、Cgroup基本概念与示例
Cgroup(控制组):是Linux内核提供的一种限制Docker容器使用Docker宿主机资源的一种机制。
Cgroup四大功能:
1)资源限制;Cgroup可以对进程组使用的资源总额进行限制;
2)优先级分配;通过分配的CPU时间片数量以及硬盘IO带宽大小,实际相当于控制了进程运行的优先级别;
3)资源统计;Cgroup可以统计系统资源使用量,比如CPU使用时间,内存使用量等,用于按量计费。同时还支持挂起功能,也就是说通过cgroup吧所有资源限制起来,对资源都不能使用,注意这并不意味说我们的程序不能使用了,只是不能使用资源,处于等待状态;
4)进程控制;可以对进程组执行挂起、恢复等操作;
通过Cgroup,我们就可以具体地控制对系统资源的分配、优先顺序、拒绝、管理和监控。这样就可以避免在docker容器中服务受到外部干扰时,可以将其限制在容器之中,而不会影响宿主机或其他容器的运行的,提高了安全性。
Docker是通过以下几个方面对容器使用的资源进行限制:
* 对CPU进行限制;
* 对内存、SWAP进行限制;
* 对block IO进行限制;
示例如下:
1.对CPU进行限制
[root@localhost ~]# cat /sys/fs/cgroup/cpu/cpu.shares
1024
//查看宿主机默认的CPU权重为1024
[root@localhost ~]# docker run -it --name test centos:7 //随便创建一个容器进行测试
[root@6afc120f16e1 /]# cat /sys/fs/cgroup/cpu/cpu.shares
1024
//可以看到默认情况下,docker容器默认的CPU权重也是1024
如果不对容器进行限制的话,是非常危险的,因为Docker宿主机与Docker容器对CPU的权重值是一样的,这样,它们在对CPU资源进行抢占时,比例为1:1。显然在生产环境中需要对其做一些限制,方法如下:
[root@localhost ~]# docker run -it --name test1 -c 512 centos:7
//基于centos镜像运行一个名为test1的容易,其CPU使用的权重为512
//设置方法相对来说,十分简单,就是添加了一个“-t”的选项而已!
[root@fc842b8af840 /]# cat /sys/fs/cgroup/cpu/cpu.shares
512
//验证是否设置是否成功
2.对物理内存、Swap进行限制
容器内存主要包括两部分:物理内存与Swap(交换分区)
可以通过以下参数控制容器对内存的使用情况:
* -m或--memory:设置内存的使用限额;
* --memory-swap:设置内存+swap的使用限制;
[root@localhost ~]# cat /sys/fs/cgroup/memory/memory.limit_in_bytes
9223372036854771712
//查看宿主机对内存的使用情况,单位是字节,这么大的数字表示没有限制
[root@localhost ~]# docker run -it --name test2 centos:7
[root@d65dd3da663c /]# cat /sys/fs/cgroup/memory/memory.limit_in_bytes
9223372036854771712
//创建容器,查看容器对宿主机内存的使用情况,单位是字节,这么大的数字表示没有限制
通过以下可以看出这样是不安全的,所以需要使用以下方法对其进行限制,方法如下:
[root@localhost ~]# docker run -it --name test4 -m 200M --memory-swap 300M centos:7
//创建一个容器,并限制容器最多使用200M内存和100M的交换分区
//--memory-swap:这个值是物理内存加Swap的值
[root@3de51b7474c5 /]# cat /sys/fs/cgroup/memory/memory.limit_in_bytes
209715200
//查看物理内存是否生效,单位是字节,可以自行进行换算验证
[root@3de51b7474c5 /]# cat /sys/fs/cgroup/memory/memory.memsw.limit_in_bytes
314572800
//查看物理内存和交换分区内存是否生效,单位是字节,这个值是物理内存加Swap分区的值
3.对block IO进行限制
block IO:磁盘的读写性能。
docker中可以通过设置权重,限制bps和iops的方式控制容器读写磁盘的IO。
* bps:每秒读写的数据量
* iops:每秒IO的次数
默认情况下,所有容器都能平等的读写磁盘,也可以通过“--blkio-weight"参数改变容器的block IO的优先级。
常用的选项有:
* --device-read-bps:显示读取某个设备的bps;
* --device-write-bps:显示写入某个设备的bps;
* --device-read-iops:显示读取某个设备的iops;
* --device-write-iops:显示写入某个设备的iops;
默认运行一个容器,不对其进行限制:
[root@3de51b7474c5 /]# time dd if=/dev/zero of=test.out bs=1M count=800 oflag=direct
//oflag=direct用来指定directIO方式写入文件,这样才会使--device-write-bps生效,主要测试读写性能
800+0 records in
800+0 records out
838860800 bytes (839 MB) copied, 1.6379 s, 512 MB/s //不进行限制,结果为每秒写入512MB
real 0m2.022s
user 0m0.001s
sys 0m1.146s
[root@localhost ~]# docker run -it --name test5 --device-write-bps /dev/sda:30M centos:7
//创建一个容器对其限制为每秒为30M
[root@f5bd3f122881 /]# time dd if=/dev/zero of=test.out bs=1M count=800 oflag=direct
800+0 records in
800+0 records out
838860800 bytes (839 MB) copied, 26.6317 s, 31.5 MB/s //虽然有点超出限制,但是并没有限制强太多
real 0m26.633s
user 0m0.004s
sys 0m2.097s