Docker入门——namespace 隔离容器的运行环境,cgroups 限制容器使用的资源

1. namespace 隔离容器的运行环境

  • Docker容器和LXC容器在实现上很相似,所提供的安全特性也基本–致。当用dockerrun启动一个容器时,Docker 将在后台为容器创建一个独立的命名空间。
    命名空间提供了最基础也是最直接的隔离,在容器中运行的进程不会被运行在本地主机上的进程和其他容器通过正常渠道发现和影响。
    例如,通过命名空间机制,每个容器都有自己独有的网络栈,意味着它们不能访问其他容器的套接字( sockets)或接口。当然,容器默认可以与本地主机网络连通,如果主机系统上做了相应的交换设置,容器可以像跟主机交互一样的和其他容器交互。启动容器时,指定公共端口或使用连接系统,容器可以相互通信了(用户可以根据配置来限制通信的策略)。
  • 从网络架构的角度来看,所有的容器实际上是通过本地主机的网桥接口(Docker0)进行相互通信,就像物理机器通过物理交换机通信一样。
    那么,Linux内核中实现命名空间(特别是网络命名空间)的机制是否足够成熟呢?
    Linux内核从2.6.15版本(2008年7月发布)开始引人命名空间,至今经历了数年的演化和改进,并应用于诸多大型生产系统中。
    实际上,命名空间的想法和设计提出的时间要更早,最初是OpenVZ项目的重要特性。OpenVZ项目早在2005年就已经正式发布,其设计和实现更加成熟。
    当然,与虚拟机方式相比,通过命名空间来实现的隔离并不是那么绝对。运行在容器中的应用可以直接访问系统内核和部分系统文件。因此,用户必须保证容器中应用是安全可信的(这跟保证运行在系统中的软件是可信的一一个道理),否则本地系统将可能受到威胁。实际上,Docker自1.30版本起对镜像管理引人了签名系统,用户可以通过签名来验证镜像的完整性和正确性。
    具体可参看:Docker 使用 Linux namespace 隔离容器的运行环境

2. 控制组资源控制的安全

  • 控制组是Linux容器机制中的另外一个关键组件,它负责实现资源的审计和限制。当用dockerrun启动一个容器时,Docker将在后台为容器创建一个独立的控制组策略集合。
    它提供了很多有用的特性;以及确保各个容器可以公平地分享主机的内存、CPU、磁盘O等资源;当然,更重要的是,控制组确保了当发生在容器内的资源压力不会影响到本地主机系统和其他容器。
    尽管控制组不负责隔离容器之间相互访问、处理数据和进程,但是它在防止拒绝服务攻击(DDoS)方面是必不可少的。尤其是在多用户的平台(比如公有或私有的PaaS)上,控制组十分重要。例如,当某些应用容器出现异常的时候,可以保证本地系统和其他容器正常运行而不受影响。
  • 在docker中的体现:
    • 默认情况下,Docker 启动一个容器后,会在 /sys/fs/cgroup 目录下的各个资源目录下生成以容器 ID 为名字的目录(group),比如:
      容器信息
      这里写图片描述
      /sys/fs/cgroup 中对应的信息:
      这里写图片描述
      下面以cgroup第资源的控制,来解释docker 容器对资源的限制

通过linux cgroup来进行说明
实验拓扑:linux rhel6.5 机器,安装libcgroup.x86_64 来进行实验

 [root@server1 ~]# /etc/init.d/cgconfig start
 Starting cgconfig service:                                 [  OK  ]
 # 进入此目录
 [root@server1 ~]# cd /cgroup/
 [root@server1 cgroup]# ls
 blkio  cpu  cpuacct  cpuset  devices  freezer  memory  net_cls
blkio — 这​​​个​​​子​​​系​​​统​​​为​​​块​​​设​​​备​​​设​​​定​​​输​​​入​​​/输​​​出​​​限​​​制​​​,比​​​如​​​物​​​理​​​设​​​备​​​(磁​​​盘​​​,固​​​态​​​硬​​​盘​​​,USB 等​​​等​​​)。
cpu — 这​​​个​​​子​​​系​​​统​​​使​​​用​​​调​​​度​​​程​​​序​​​提​​​供​​​对​​​ CPU 的​​​ cgroup 任​​​务​​​访​​​问​​​。​​​
cpuacct — 这​​​个​​​子​​​系​​​统​​​自​​​动​​​生​​​成​​​ cgroup 中​​​任​​​务​​​所​​​使​​​用​​​的​​​ CPU 报​​​告​​​。​​​
cpuset — 这​​​个​​​子​​​系​​​统​​​为​​​ cgroup 中​​​的​​​任​​​务​​​分​​​配​​​独​​​立​​​ CPU(在​​​多​​​核​​​系​​​统​​​)和​​​内​​​存​​​节​​​点​​​。​​​
devices — 这​​​个​​​子​​​系​​​统​​​可​​​允​​​许​​​或​​​者​​​拒​​​绝​​​ cgroup 中​​​的​​​任​​​务​​​访​​​问​​​设​​​备​​​。​​​
freezer — 这​​​个​​​子​​​系​​​统​​​挂​​​起​​​或​​​者​​​恢​​​复​​​ cgroup 中​​​的​​​任​​​务​​​。​​​
memory — 这​​​个​​​子​​​系​​​统​​​设​​​定​​​ cgroup 中​​​任​​​务​​​使​​​用​​​的​​​内​​​存​​​限​​​制​​​,并​​​自​​​动​​​生​​​成​​​​​内​​​存​​​资​​​源使用​​​报​​​告​​​。​​​
net_cls — 这​​​个​​​子​​​系​​​统​​​使​​​用​​​等​​​级​​​识​​​别​​​符​​​(classid)标​​​记​​​网​​​络​​​数​​​据​​​包​​​,可​​​允​​​许​​​ Linux 流​​​量​​​控​​​制​​​程​​​序​​​(tc)识​​​别​​​从​​​具​​​体​​​ cgroup 中​​​生​​​成​​​的​​​数​​​据​​​包​​​。​​​

1. 进行内存的限制

 [root@server1 cgroup]# cd memory/
 [root@server1 memory]# ls

这里写图片描述
编辑/etc/cgconfig.conf,进行限制

 [root@server1 memory]# vim /etc/cgconfig.conf
 group test1 {
         memory {
                 memory.limit_in_bytes = 209715200;   # 限制为200M
                 memory.memsw.limit_in_bytes = 209715200;
         }
 }
 编辑完成,重启服务 
 [root@server1 ~]# /etc/init.d/cgconfig restart

进行限制测试:
介绍一下 /dev/shm

  • /dev/shm/是一个使用就是tmpfs文件系统的设备,其实就是一个特殊的文件系统。redhat中默认大小为物理内存的一半,使用时不用mkfs格式化。
    tmpfs是Linux/Unix系统上的一种基于内存的虚拟文件系统。tmpfs可以使用您的内存或swap分区来存储文件(即它的存储空间在virtual memory 中, VM由real memory和swap组成)。由此可见,tmpfs主要存储暂存的文件。它有如下2个优势 : 1. 动态文件系统的大小。2. tmpfs 使用VM建的文件系统,速度当然快。3.重启后数据丢失。
    当删除tmpfs中的文件时,tmpfs会动态减少文件系统并释放VM资源,LINUX中可以把一些程序的临时文件放置在tmpfs中,利用tmpfs比硬盘速度快的特点提升系统性能。实际应用中,为应用的特定需求设定此文件系统,可以提升应用读写性能,如将squid 缓存目录放在/tmp, php session 文件放在/tmp, socket文件放在/tmp, 或者使用/tmp作为其它应用的缓存设备
    上面的内存限制,限制的就是此目录下
 [root@server1 shm]# cgexec -g memory:test1 dd if=/dev/zero of=file bs=1M count=300       # 超过200M的内存截取不出
 Killed
 [root@server1 shm]# cgexec -g memory:test1 dd if=/dev/zero of=file bs=1M count=190       # 小于200M则可以截取
 190+0 records in
 190+0 records out
 199229440 bytes (199 MB) copied, 0.0559904 s, 3.6 GB/s

2. 进行进程CPU的限制

可通过cgroup来限制进程cpu的占用率

 [root@server1 ~]# vim /etc/cgconfig.conf
 编辑/etc/cgconfig.conf

 group test2 {
         cpu {
                 cpu.shares = 100;   # 限制cpu占用率为1/10
         }
 }

 执行如下命令,然后查看cpu 占有率 : (此测试需要注意cpu的核数,若是4核,则需要建立8各项目,来进行cpu占有的压测试)
 限制过的
 [root@server1 ~]# cgexec -g cpu:test2 dd if=/dev/zero of=/dev/null &
 [1] 4123
 未限制的
 [root@server1 ~]# dd if=/dev/zero of=/dev/null &
 [2] 4124
 通过top 命令,动态检测cpu占有率
 [root@server1 ~]# top

这里写图片描述

3. 进程 I/O 的限制

可通过cgroup来限制进程I/O

  # 查看设备编号
 [root@server1 blkio]# ll /dev/vda   
 brw-rw---- 1 root disk 252, 0 Aug 21 22:24 /dev/vda

 [root@server1 ~]# vim /etc/cgconfig.conf
 group test3 {
         blkio {
                 blkio.throttle.read_iops_device = "252:0 1000000";
                               # 限制进程I/O的磁盘读速率为100M
                               # 252:0 为设备编号
         }
 }
 [root@server1 ~]# /etc/init.d/cgconfig restart 
                 # 重启服务  

进行测试

 切取文件,查看磁盘读写速率
 [root@server1 ~]# cgexec -g blkio:test3 dd if=/dev/zero of=/dev/null &
 [3] 13663
 [root@server1 ~]# iotop     # 进行查看

这里写图片描述

4. 进程的限制

可通过cgroup来限制进程的状态


 [root@server1 ~]# vim /etc/cgconfig.conf
 group test4 {
        freezer {

 }
 }
 [root@server1 ~]# /etc/init.d/cgconfig restart
                 # 重启服务

进行测试

 [root@server1 ~]# cgexec -g freezer:test4 dd if=/dev/zero of=/dev/null &
 [1] 5299
 [root@server1 ~]# cd /cgroup/freezer/
 [root@server1 freezer]# ls
 cgroup.event_control  cgroup.procs  notify_on_release  release_agent   tasks  test4
 [root@server1 freezer]# cd test4/
 [root@server1 test4]# ls
 cgroup.event_control  cgroup.procs  freezer.state  notify_on_release   tasks
 [root@server1 test4]# echo 5299 > tasks   # 将进程号写入tasks中
 [root@server1 test4]# cat freezer.state 
 THAWED         # 解冻
 [root@server1 test4]# echo FROZEN > freezer.state # 冻结task中的进程
                # FROZEN 冻结进程

冻结前进程状态
这里写图片描述
冻结后进程状态
这里写图片描述

5. Docker run 命令中 cgroups 相关命令

block IO:
      --blkio-weight value          Block IO (relative weight), between 10 and 1000
      --blkio-weight-device value   Block IO weight (relative device weight) (default [])
      --cgroup-parent string        Optional parent cgroup for the container
CPU:
      --cpu-percent int             CPU percent (Windows only)
      --cpu-period int              Limit CPU CFS (Completely Fair Scheduler) period
      --cpu-quota int               Limit CPU CFS (Completely Fair Scheduler) quota
  -c, --cpu-shares int              CPU shares (relative weight)
      --cpuset-cpus string          CPUs in which to allow execution (0-3, 0,1)
      --cpuset-mems string          MEMs in which to allow execution (0-3, 0,1)
Device:    
      --device value                Add a host device to the container (default [])
      --device-read-bps value       Limit read rate (bytes per second) from a device (default [])
      --device-read-iops value      Limit read rate (IO per second) from a device (default [])
      --device-write-bps value      Limit write rate (bytes per second) to a device (default [])
      --device-write-iops value     Limit write rate (IO per second) to a device (default [])
Memory:      
      --kernel-memory string        Kernel memory limit
  -m, --memory string               Memory limit
      --memory-reservation string   Memory soft limit
      --memory-swap string          Swap limit equal to memory plus swap: '-1' to enable unlimited swap
      --memory-swappiness int       Tune container memory swappiness (0 to 100) (default -1)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值