1.首先可以发现容器内的内存和虚拟机中的内存大小是一样的
[root@server1 ~]# docker run -it --name vm1 ubuntu
root@38ead985c8d6:/# ls
#容器内的内存大小
root@38ead985c8d6:/# free -m
root@38ead985c8d6:/# [root@server1 ~]#
#虚拟机中的内存大小
[root@server1 ~]# free -m
[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
#查看其cgroup服务的路径
[root@server1 ns]# mount -t cgroup
[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
[root@server1 docker]# cd ..
[root@server1 memory]# ls
[root@server1 memory]# mkdir x1
[root@server1 memory]# ls
[root@server1 docker]# docker ps
[root@server1 docker]# ls
[root@server1 docker]# docker rm -f 38
[root@server1 docker]# docker ps
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
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相关的内容,限制多少,-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
[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
注意:
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
#写入dd命令的进程号,对该进程进行限制,再次查看时会发现cpu使用率减少到了20%
[root@server1 x1]# echo 1823 > tasks
[root@server1 x1]# top
#当dd命令对应的进程杀掉之后,tasks文件中的进程号,也会随之消失
[root@server1 shm]# kill -9 1823
[root@server1 ~]# cd /sys/fs/cgroup/cpu/x1/
[root@server1 x1]# cat tasks
(三)对cpu进行资源限制(针对docker容器)
1.首先清除掉之前的环境,即将所有的容器都删除
[root@server1 ~]# docker rm -f vm1
[root@server1 ~]# docker rm -f vm2
[root@server1 ~]# docker ps -a
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
root@1d39b4e6f8ab:/# dd if=/dev/zero of=/dev/null &
[root@server1 ~]# top
[root@server1 ~]# cd /sys/fs/cgroup/cpu/docker/
[root@server1 docker]# ls
[root@server1 docker]# cd
[root@server1 1d39b4e6f8ab2feda63130fe5fd01c98530e293d60591ec286cd75422c8ef56c]# cat cpu.cfs_quota_us
[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
8.删除容器并连接vm1,查看容器vm1的cpu的速率,发现依旧是20%
[root@server1 ~]# docker rm -f vm2
[root@server1 ~]# docker attach vm1
root@1d39b4e6f8ab:/#
root@1d39b4e6f8ab:/# top
容器可用内存包括两个部分:物理内存和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
注意:
1.如果直接修改/sys/fs/cgroup/memory中的文件的内容,会报错。所以需要创建一个目录
2.314572800单位为BB
补充:
可以使用计算机计算大小
[root@foundation66 Desktop]# bc
300*1024*1024
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
(二)设置swap和内存总共的大小(针对系统中的某个进程)
1.首先需要安装cgroup服务,因为其可以提供cgexec命令,可以同时查看内存的占有
[root@server1 shm]# yum search cgroup
[root@server1 shm]# yum install libcgroup-tools.x86_64 -y
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
注意:
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
[root@server1 shm]# rm -rf bigfile
[root@server1 shm]# free -m
[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
[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
[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
[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
[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
补充:
在限制内存和内存与swap分区总和的大小时,要注意,要先限制内存的大小,继而才可以限制swap分区总和的大小,反过来是错误的
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
[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.资源限制没有问题,但是隔离有问题