Docker实验(九)Docker安全讲解(对cpu,内存和交换分区进行资源限制)

一.Docker安全的相关概念

  • Docker容器的安全性,很大程度上依赖于Linux系统自身,评估Docker的安全性时,主要考虑以下几个方面:
    (1)Linux内核的命名空间机制提供的容器隔离安全
    (2)Linux控制组机制对容器资源的控制能力安全。
    (3)Linux内核的能力机制所带来的操作权限安全
    (4)Docker程序(特别是服务端)本身的抗攻击性。
    (5)其他安全增强机制对容器安全性的影响。
  • 命名空间隔离的安全
    (1)当docker run启动一个容器时,Docker将在后台为容器创建一个独立的命名空间。命名空间提供了最基础也最直接的隔离。
    (2)与虚拟机方式相比,通过Linux namespace来实现的隔离不是那么彻底。
    (3)容器只是运行在宿主机上的一种特殊的进程,那么多个容器之间使用的就还是同一个宿主机的操作系统内核。
    (4)在 Linux 内核中,有很多资源和对象是不能被 Namespace 化的,比如:时间。
  • 控制组资源控制的安全
    (1)当docker run启动一个容器时,Docker将在后台为容器创建一个独立的控制组策略集合。
    (2)Linux Cgroups提供了很多有用的特性,确保各容器可以公平地分享主机的内存、CPU、磁盘IO等资源。
    (3)确保当发生在容器内的资源压力不会影响到本地主机系统和其他容器,它在防止拒绝服务攻击(DDoS)方面必不可少。
  • 内核能力机制
    (1)能力机制(Capability)是Linux内核一个强大的特性,可以提供细粒度的权限访问控制。
    (2)大部分情况下,容器并不需要“真正的”root权限,容器只需要少数的能力即可。
    (3)默认情况下,Docker采用“白名单”机制,禁用“必需功能”之外的其他权限。
  • Docker服务端防护
    (1)使用Docker容器的核心是Docker服务端,确保只有可信的用户才能访问到Docker服务。
    (2)将容器的root用户映射到本地主机上的非root用户,减轻容器和主机之间因权限提升而引起的安全问题。
    (3)允许Docker 服务端在非root权限下运行,利用安全可靠的子进程来代理执行需要特权权限的操作。这些子进程只允许在特定范围内进行操作。
  • 其他安全特性
    (1)在内核中启用GRSEC和PAX,这将增加更多的编译和运行时的安全检查;并且通过地址随机化机制来避免恶意探测等。启用该特性不需要Docker进行任何配置。
    (2)使用一些有增强安全特性的容器模板。
    (3)用户可以自定义更加严格的访问控制机制来定制安全策略。
    (4)在文件系统挂载到容器内部时,可以通过配置只读模式来避免容器内的应用通过文件系统破坏外部环境,特别是一些系统运行状态相关的目录。
  • 容器资源控制
    (1)Linux Cgroups 的全称是 Linux Control Group。它是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等等。对进程进行优先级设置、审计,以及将进程挂起和恢复等操作。
    (2)Linux Cgroups 给用户暴露出来的操作接口是文件系统。它以文件和目录的方式组织在操作系统的 /sys/fs/cgroup 路径下。执行此命令查看:mount -t cgroup
    (3)在 /sys/fs/cgroup 下面有很多诸如 cpuset、cpu、 memory 这样的子目录,也叫子系统。
    (4)在每个子系统下面,为每个容器创建一个控制组(即创建一
    个新目录)。
    (5)控制组下面的资源文件里填上什么值,就靠用户执行 docker run 时的参数指定。

二.系统基础安全实验

1.首先可以发现容器内的内存和虚拟机中的内存大小是一样的

[root@server1 ~]# docker run -it --name vm1 ubuntu
root@38ead985c8d6:/# ls
#容器内的内存大小
root@38ead985c8d6:/# free -m
root@38ead985c8d6:/# [root@server1 ~]# 
#虚拟机中的内存大小
[root@server1 ~]# free -m

Docker实验(九)Docker安全讲解(对cpu,内存和交换分区进行资源限制)_第1张图片
2.发现容器进程只有6个namespace

[root@server1 ~]# docker inspect vm1 | grep Pid
[root@server1 ~]# cd /proc/
[root@server1 proc]# cd 1576/
[root@server1 1576]# cd ns/
[root@server1 ns]# ll

Docker实验(九)Docker安全讲解(对cpu,内存和交换分区进行资源限制)_第2张图片
3.查看针对整个容器的资源控制的目录(cpu和内存)

#查看其cgroup服务的路径

[root@server1 ns]# mount -t cgroup

Docker实验(九)Docker安全讲解(对cpu,内存和交换分区进行资源限制)_第3张图片
#依次查看cpu,内存和容器的目录下的文件

[root@server1 ns]# cd /sys/fs/cgroup/
[root@server1 cgroup]# ls
[root@server1 cgroup]# cd cpu
[root@server1 cpu]# ls
[root@server1 cpu]# cd ../memory/
[root@server1 memory]# ls
[root@server1 memory]# cd docker/
[root@server1 docker]# ls

Docker实验(九)Docker安全讲解(对cpu,内存和交换分区进行资源限制)_第4张图片
4.当在memory目录下新建目录时直接会从上级目录继承

[root@server1 docker]# cd ..
[root@server1 memory]# ls
[root@server1 memory]# mkdir x1
[root@server1 memory]# ls

Docker实验(九)Docker安全讲解(对cpu,内存和交换分区进行资源限制)_第5张图片
5.证明:容器的id的使用可以使用一部分,只要是唯一的即可

[root@server1 docker]# docker ps
[root@server1 docker]# ls
[root@server1 docker]# docker rm -f 38
[root@server1 docker]# docker ps

Docker实验(九)Docker安全讲解(对cpu,内存和交换分区进行资源限制)_第6张图片
6.新创建一个容器时会在容器的资源控制下生成一个新的目录,以其id命名

[root@server1 ~]# docker run -it --name vm1 ubuntu
root@437a24dd1945:/# [root@server1 ~]# 
[root@server1 ~]# cd /sys/fs/cgroup/memory/docker/
[root@server1 docker]# ls

Docker实验(九)Docker安全讲解(对cpu,内存和交换分区进行资源限制)_第7张图片
7.:查看内存发现是没有限制的,虽然有数字,但事实上是没有限制的

[root@server1 docker]# cd 437a24dd19459aff58ed70ba5d24140ef2d2045b21b4a225aee2da28bcc96ce3/
[root@server1 437a24dd19459aff58ed70ba5d24140ef2d2045b21b4a225aee2da28bcc96ce3]# cat memory.limit_in_bytes

在这里插入图片描述
8.:linux系统中对模块(cpu,内存)的限制可以通过以下文件进行修改

[root@server1 ~]# cd /etc/security/limits.d/
[root@server1 limits.d]# vim /etc/security/limits.conf 
[root@server1 limits.d]# ls

在这里插入图片描述

三.对cpu进行资源限制

(一)cpu独占

查看资源cpu相关的内容,限制多少,-1表示没有限制

[root@server1 ~]# cd /sys/fs/cgroup/cpu
[root@server1 cpu]# mkdir x1
[root@server1 cpu]# cd x1/
[root@server1 x1]# ls

#限制的长度

[root@server1 x1]# cat cpu.cfs_period_us

#没有时间限制

[root@server1 x1]# cat cpu.cfs_quota_us

#占用cpu

[root@server1 x1]# dd if=/dev/zero of=/dev/null &

#查看cpu的占有百分比,发现全部被占用(此时只有一个cpu)

[root@server1 x1]# top

Docker实验(九)Docker安全讲解(对cpu,内存和交换分区进行资源限制)_第8张图片
补充:
如果有两个cpu的话需要进行以下处理

[root@server1 x1]# cd /sys/devices/system/cpu/
[root@server1 cpu]# ls
[root@server1 cpu]# cd cpu0/
[root@server1 cpu0]# ls
[root@server1 cpu0]# cd ../cpu1/
[root@server1 cpu1]# ls
[root@server1 cpu1]# cd ..
#将0输入到online中,此时资源就会独占一个cpu
[root@server1 cpu]# cat onine^C
[root@server1 cpu]# echo 0 > online^C
#查看cpu的个数(虽然此时显示了两个,但是只用了一个,所以不用理睬,如果top中显示两个,那么需要进行以上操作)
[root@server1 cpu]# lscpu

Docker实验(九)Docker安全讲解(对cpu,内存和交换分区进行资源限制)_第9张图片

注意:
1.如果不对cpu进行限制,即不修改/sys/fs/cgroup/cpu/cpu.cfs_quota_us(文件内容默认是-1,表示不限制)文件中的内容。那么执行命令"dd if=/dev/zero of=/dev/null &"时,会占用100%的cpu。
2.cpu.cfs_period_us:cpu分配的周期(微秒),默认为100000。
3.cpu.cfs_quota_us:表示该control group限制占用的时间(微秒),默认为-1,表示不限制。如果设为50000,表示占用50000/100000=50%的CPU。

(二)对cpu进行资源限制(针对某一个进程)

#修改对cpu限制的长度为20000
[root@server1 cpu]# cd /sys/fs/cgroup/cpu
[root@server1 cpu]# cd x1/
[root@server1 x1]# cat cpu.cfs_period_us 
#占用"20000/100000=20%"的CPU
[root@server1 x1]# echo 20000 > cpu.cfs_quota_us
[root@server1 x1]# cat cpu.cfs_quota_us
#查看cpu时发现占有率依旧时100%,没有发生改变
[root@server1 x1]# top

Docker实验(九)Docker安全讲解(对cpu,内存和交换分区进行资源限制)_第10张图片
#写入dd命令的进程号,对该进程进行限制,再次查看时会发现cpu使用率减少到了20%

[root@server1 x1]# echo 1823 > tasks
[root@server1 x1]# top

Docker实验(九)Docker安全讲解(对cpu,内存和交换分区进行资源限制)_第11张图片
#当dd命令对应的进程杀掉之后,tasks文件中的进程号,也会随之消失

[root@server1 shm]# kill -9 1823
[root@server1 ~]# cd /sys/fs/cgroup/cpu/x1/
[root@server1 x1]# cat tasks 

在这里插入图片描述
在这里插入图片描述

注意:
/sys/fs/cgroup/cpu目录中的文件,不能用vim进行编辑,利用vim进行编辑,无法进行保存退出(即使使用"wq!",也不能保存退出。)

(三)对cpu进行资源限制(针对docker容器)

1.首先清除掉之前的环境,即将所有的容器都删除

[root@server1 ~]# docker rm -f vm1
[root@server1 ~]# docker rm -f vm2
[root@server1 ~]# docker ps -a

Docker实验(九)Docker安全讲解(对cpu,内存和交换分区进行资源限制)_第12张图片
2.创建一个容器并限制其cpu占用,然后使用top命令查看cpu使用率时,发现没有使用
#cpu_period 和 cpu_quota 这两个参数需要组合使用,用来限制进程在长度为 cpu_period 的一段时间内,只能被分配到总量为 cpu_quota 的CPU 时间,以上设置表示20%的cpu时间。

[root@server1 ~]# docker run -it --name vm1 --cpu-period=100000 --cpu-quota=20000 ubuntu
root@1d39b4e6f8ab:/# top

Docker实验(九)Docker安全讲解(对cpu,内存和交换分区进行资源限制)_第13张图片
3.使用dd命令占用cpu

root@1d39b4e6f8ab:/# dd if=/dev/zero of=/dev/null &

在这里插入图片描述
4.退出后发现此时的cpu使用率为20%左右

[root@server1 ~]# top

Docker实验(九)Docker安全讲解(对cpu,内存和交换分区进行资源限制)_第14张图片
5.进入cpu的文件中查看cpu限制是否设置,发现成功设置

[root@server1 ~]# cd /sys/fs/cgroup/cpu/docker/
[root@server1 docker]# ls
[root@server1 docker]# cd
[root@server1 1d39b4e6f8ab2feda63130fe5fd01c98530e293d60591ec286cd75422c8ef56c]# cat cpu.cfs_quota_us 

Docker实验(九)Docker安全讲解(对cpu,内存和交换分区进行资源限制)_第15张图片
6.再次创建一个容器,此时不限制cpu的占有

[root@server1 1d39b4e6f8ab2feda63130fe5fd01c98530e293d60591ec286cd75422c8ef56c]# docker run -it --name vm2 ubuntu
root@f1e2c2df2504:/# dd if=/dev/zero of=/dev/null &

在这里插入图片描述
7.退出容器后,使用top命令查看时发现没有限制cpu速率的容器此时的cpu使用率高达100%

[root@server1 ~]# top

Docker实验(九)Docker安全讲解(对cpu,内存和交换分区进行资源限制)_第16张图片
8.删除容器并连接vm1,查看容器vm1的cpu的速率,发现依旧是20%

[root@server1 ~]# docker rm -f vm2
[root@server1 ~]# docker attach vm1
root@1d39b4e6f8ab:/# 
root@1d39b4e6f8ab:/# top

Docker实验(九)Docker安全讲解(对cpu,内存和交换分区进行资源限制)_第17张图片

四.对内存和交换分区进行资源限制

容器可用内存包括两个部分:物理内存和swap交换分区。
–memory设置内存使用限额
–memory-swap设置swap交换分区限额

(一)对内存进行资源限制

1.对mem进行资源限制

[root@server1 x1]# cd ..
[root@server1 cpu]# cd ../memory/
[root@server1 memory]# mkdir x2
[root@server1 memory]# cd x2/
[root@server1 x2]# cat memory.limit_in_bytes
[root@server1 x2]# echo 314572800 > memory.limit_in_bytes

Docker实验(九)Docker安全讲解(对cpu,内存和交换分区进行资源限制)_第18张图片
注意:
1.如果直接修改/sys/fs/cgroup/memory中的文件的内容,会报错。所以需要创建一个目录
2.314572800单位为BB

补充:
可以使用计算机计算大小

[root@foundation66 Desktop]# bc
300*1024*1024

Docker实验(九)Docker安全讲解(对cpu,内存和交换分区进行资源限制)_第19张图片

2.使用dd在shm下新建一个400M的文件并查看内存的剩余空间,删除掉文件后,发现少了400M且/dev/shm的使用率降低了40%

[root@server1 shm]# dd if=/dev/zero of=bigfile bs=1M count=400
[root@server1 shm]# df
[root@server1 shm]# free -m
[root@server1 shm]# rm -f bigfile 
[root@server1 shm]# df
[root@server1 shm]# free -m
[root@server1 shm]# pwd

Docker实验(九)Docker安全讲解(对cpu,内存和交换分区进行资源限制)_第20张图片

(二)设置swap和内存总共的大小(针对系统中的某个进程)

1.首先需要安装cgroup服务,因为其可以提供cgexec命令,可以同时查看内存的占有

[root@server1 shm]# yum search cgroup
[root@server1 shm]# yum install libcgroup-tools.x86_64 -y

Docker实验(九)Docker安全讲解(对cpu,内存和交换分区进行资源限制)_第21张图片
2.发现在此目录下给swap分区分了100M左右(因为之前给内存中设置的最大内存是300M,如果超出了,则会给swap分区分一部分内存,最大占用内存数和最大占用swap分区的内存数一样。表明最大可用内存为300M,可用swap为0M。即限制了内存+交换分区<=300M)

[root@server1 ~]# cd /dev/shm
[root@server1 shm]# cgexec -g memory:x2 dd if=/dev/zero of=bigfile bs=1M 
[root@server1 shm]# free -m
[root@server1 shm]# cgexec -g memory:x2 dd if=/dev/zero of=bigfile bs=1M
[root@server1 shm]# free -m

Docker实验(九)Docker安全讲解(对cpu,内存和交换分区进行资源限制)_第22张图片

注意:
1.一定要在/dev/shm目录下进行,因为在该目录下进行操作,相当于直接占用内存
2.如果不对内存和swap分区进行限制,即不修改/sys/fs/cgroup/memory/memory.limit_in_bytes和/sys/fs/cgroup/memory/memory.memsw.limit_in_bytes文件中的内容。那么不管要生成的bigfile文件的大小为多少,dd命令永远会成功。
3.如果不限制交换分区的话,只限制了内存,那么当内存使用到额度后,就会占用交换分区,这也是为了创建400M的文件时,会占用约100M的交换分区

3.进入x2目录下查看内存的限制和swap,内存总共的大小限制

[root@server1 memory]# cd /sys/fs/cgroup/memory/x2/
[root@server1 x2]# cat memory.limit_in_bytes
[root@server1 x2]# cat memory.memsw.limit_in_bytes
#尝试进行更改,发现无法更改,报错的原因是因为设备在忙(-bash: echo: write error: Device or resource busy),此时需要将之前的文件删除
[root@server1 x2]# echo 314572800 > memory.memsw.limit_in_bytes

Docker实验(九)Docker安全讲解(对cpu,内存和交换分区进行资源限制)_第23张图片
4.删除掉bigfile文件并查看内存

[root@server1 shm]# rm -rf bigfile 
[root@server1 shm]# free -m

Docker实验(九)Docker安全讲解(对cpu,内存和交换分区进行资源限制)_第24张图片
5.再次设置swap和内存总共的大小,发现可以成功设置

[root@server1 shm]# cd -
[root@server1 x2]# echo 314572800 > memory.memsw.limit_in_bytes

在这里插入图片描述

注意:
之前设置了内存的大小,现在设置了内存和交换分区总共的大小,即限制了内存+交换分区<=300M

6.再次在/dev/shm目录下创建文件,发现此时不会从swap分区取内存

[root@server1 x2]# cd -
[root@server1 shm]# ls
[root@server1 shm]# cgexec -g memory:x2 dd if=/dev/zero of=bigfile bs=1M
[root@server1 shm]# free -m

Docker实验(九)Docker安全讲解(对cpu,内存和交换分区进行资源限制)_第25张图片
7.删除掉bigfile文件并查看内存

[root@server1 shm]# rm -rf bigfile 
[root@server1 shm]# free -m

在这里插入图片描述
注意:
1.使用cgroup可以同时查看内存的占有,以前的话是写进去后就无法查看
2.M和byte都可以使用,M会自动转换

(三)设置swap和内存总共的大小(针对docker容器)

1.创建一个镜像,内存的限制为300m,内存和swap分区的限制为300m并查看

#使用ctrl+q+p让退出,不要让容器停掉
[root@server1 shm]# docker run -it --name vm2 --memory=300M --memory-swap=300M ubuntu
root@92400896ef23:/# free -m
root@92400896ef23:/# df

Docker实验(九)Docker安全讲解(对cpu,内存和交换分区进行资源限制)_第26张图片
2.可以发现容器vm2的id号和文件内的一样

[root@server1 x2]# docker inspect vm2 | grep Pid
[root@server1 x2]# cd /sys/fs/cgroup/memory/docker/92400896ef23d3d213e74fededdcb7f04e8a9b7be50ac75cacf8892103bcfe10/
[root@server1 92400896ef23d3d213e74fededdcb7f04e8a9b7be50ac75cacf8892103bcfe10]# cat tasks 

在这里插入图片描述
注意:
–memory可以单独使用,但是–memory-swap是必须要与–memory一起使用的
(四).设置用户对内存的访问权限

1.查看内存的大小以及内存和swap分区总和的大小,发现是300M

[root@server1 ~]# cd /sys/fs/cgroup/memory/x2/
[root@server1 x2]# cat memory.limit_in_bytes
[root@server1 x2]# cat memory.memsw.limit_in_bytes

在这里插入图片描述
2.创建一个用户devops并查看其id

[root@server1 x2]# useradd devops
[root@server1 x2]# id devops

在这里插入图片描述
3.编辑cgrures服务的配置文件,此文件用于设置用户的访问权限,并开启cgred服务

[root@server1 x2]# vim /etc/cgrules.conf 
[root@server1 x2]# systemctl start cgred.service
文件/etc/cgrules.conf内的内容如下如下:
devops  memory  x2/

在这里插入图片描述
在这里插入图片描述
4.切换到devops用户的环境下并查看/dev/shm是否挂载

[root@server1 x2]# su - devops
[devops@server1 ~]$ df

Docker实验(九)Docker安全讲解(对cpu,内存和交换分区进行资源限制)_第27张图片
5.进入/dev/shm目录下,查看是否有权限

[devops@server1 ~]$ cd /dev/shm/
[devops@server1 shm]$ ll -d .

在这里插入图片描述
6.分别创建一个200M的文件和一个400M的文件,发现创建200M的文件成功,但是创建400M的文件失败,其原因是devops用户在创建文件时被限制了内存的大小(即继承了宿主机server1中对内存的设置)

[devops@server1 shm]$ dd if=/dev/zero of=bigfile bs=1M count=200
[devops@server1 shm]$ dd if=/dev/zero of=bigfile bs=1M count=400
[devops@server1 shm]$ du -h bigfile 

Docker实验(九)Docker安全讲解(对cpu,内存和交换分区进行资源限制)_第28张图片
补充:
在限制内存和内存与swap分区总和的大小时,要注意,要先限制内存的大小,继而才可以限制swap分区总和的大小,反过来是错误的
在这里插入图片描述

五.Block IO限制

  • 限制写设备的bps
  • 目前的block IO限制只对direct IO有效。(不使用文件缓存)

1.首先以普通用户身份运行容器,发现无法查看磁盘的相关信息

[root@server1 ~]# docker run -it --name vm1 ubuntu 
root@093d11d02d16:/# fdisk -l

在这里插入图片描述
2.再次运行容器,此时给予容器全部的权限并查看磁盘的相关信息,发现可以成功查看,主要查看boot分区的路径

[root@server1 ~]# docker run -it --rm --privileged=true ubuntu
root@47056319aacc:/# fdisk -l

Docker实验(九)Docker安全讲解(对cpu,内存和交换分区进行资源限制)_第29张图片
3.再次以写入速率为20M/s限制运行容器

[root@server1 ~]# docker run -it --rm --device-write-bps /dev/sda:20MB ubuntu
#截取300M的名为file的文件。其中参数oflag=direct表示跳过内存缓存,直接存在磁盘中。必须加该参数,否则测试会失败。当看到速率为21.1 MB/s时说明限制成功
root@ae8dba65e130:/# dd if=/dev/zero of=file bs=1M count=300 oflag=direct

在这里插入图片描述

总结(Docker安全):
1.是通过linux base隔离的,其无法做到所有的隔离
2.docker安全就是linux内核,是无法做到绝对隔离的
3.有时候即使做了一个资源限制,但是没有隔离
4./proc无法做隔离(内存中的数据),关机时就清掉了
5.容器进程只有6个namaspace
6.针对整个容器的资源控制
7.直接会从上级目录继承
8.可以使用id控制容器,只要唯一即可
9.电脑的模块
10.如果物理内存不够用,就会使用交换分区,无法对内存限制
11.可以在白名单中添加权限和删除权限
12.cpuset:进程和cpu之间的绑定
13.cpu是时间分配机制
14.限制多少,-1表示没有限制
15.要看有几个cpu,都要占核心进程,这样才会争抢
16.数据都是在内存中,不能用vim,用echo
17.dd只占cpu
18.tmpfs shms中挂载的就是物理的1/2内存,开机会自动挂载
19.memory的dd进程是已经成功写进去了
20.表示执行的时候用的是哪个控制器
21.内存跑的快,但是数据量不够
22.有100M到达了swap
23.当内存被占用时,可以使用swap做缓存
24.内存加swap分区总共的分区(之后不会给swap,限制了内存的使用)
25.available会统计可用的内存量
26.资源限制没有问题,但是隔离有问题

你可能感兴趣的:(项目)