Docker之Namespace与Cgroup
更新:HHH   时间:2023-1-7


博文大纲:
一、Docker概述
二、Namespace概念
三、Cgroup基本概念与示例

一、Docker概述

1.Docker简介

Docker作为开源社区最火爆的项目,它是在Linux容器里运行应用的开源工具,是一种轻量级的“虚拟机”,docker的全部源代码都在https://github.com/docker 进行相关维护,其官网是:https://www.docker.com 。

Docker的Logo设计为蓝色鲸鱼,拖着许多集装箱。如图:


如图所示:鲸鱼可以看作宿主机,而集装箱可以理解为相互隔离的容器,每个集装箱中都包含自己的应用程序。正如 Docker的设计宗旨一样:Buid、 Ship and Run Any App、 Anywhere,即通过对应用组件的封装、发布、部署、运行等生命周期的管理,达到应用组件级别的“一次封装,到处运行”的目的。这里的组件,既可以是一个应用,也可以是一套服务,甚至是一个完整的操作系统。

2.Docker和虚拟机的区别

作为一种轻量级的虚拟化方式,Docker与传统虚拟机相比具有显著的优势。如图:

Docker之所以拥有众多优势,与操作系统虚拟化自身的特点是分不开的。传统虚拟机需要有额外的虚拟机管理程序和虚拟操作系统层,而Docker容器是直接在操作系统层面之上实现的虚拟化,如图:

3.Docker的使用场景

现在需要能方便地创建运行在云平台上的应用,必须要脱离底层的硬件,同时还需要任何时间、地点可获取这些资源,这正是Docker所能提供的。

Docker的容器技术可以在一条主句上轻松为任何应用创建一个轻量级的、可移植的、自给自足的容器。通过这种容器打包应用程序,意味着简化了重新部署、调试这些琐碎的重复工作,极大地提高了工作效率。

比如:服务器从腾讯云迁移到阿里云,如果采用了Docker容器技术,迁移只需要在新的服务器上启动需要的容器即可。

4.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

———————— 本文至此结束,感谢阅读 ————————

返回云计算教程...