docker安全之容器资源控制 安全加固

目录

一、cgroup简介

二、 容器资源控制

1、内存限制

​2、cpu限额

​3、Block IO限制

​三、docker 安全加固


在使用 docker 运行容器时,默认的情况下,docker没有对容器进行硬件资源的限制,当一台主机上运行几百个容器,这些容器虽然互相隔离,但是底层却使用着相同的 CPU、内存和磁盘资源。如果不对容器使用的资源进行限制,那么容器之间会互相影响,小的来说会导致容器资源使用不公平;大的来说,可能会导致主机和集群资源耗尽,服务完全不可用。

docker 作为容器的管理者,自然提供了控制容器资源的功能。正如使用内核的 namespace 来做容器之间的隔离,docker 也是通过内核的 cgroups 来做容器的资源限制;包括CPU、内存、磁盘三大方面,基本覆盖了常见的资源配额和使用量控制

一、cgroup简介

   Linux Cgroups 的全称是 Linux Control Group。 是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等等。 对进程进行优先级设置、审计,以及将进程挂起和恢复等操作。 Linux Cgroups 给用户暴露出来的操作接口是文件系统。 它以文件和目录的方式组织在操作系统的 /sys/fs/cgroup 路径下。 执行此命令查看:mount -t cgroup   

   在 /sys/fs/cgroup 下面有很多诸如 cpuset、cpu、 memory 这样的子目录,也叫子系统。 在每个子系统下面,为每个容器创建一个控制组(即创建一个新目录)。 控制组下面的资源文件里填上什么值,就靠用户执行 docker run 时的参数指定。

docker ps
docker run -d --name demo nginx ##运行一个容器
docker ps
docker inspect demo ##查看demo信息
docker inspect demo | grep Pid ##可以看到pid为3904,是一个进程
cd /proc/3904/
ls
cd ns
 ls ##可以看到有6种ns
ll -d /var/lib/docker/  #docker所有信息都在这个目录中,继承超级用户权限
rpm -qa | grep docker ##有无根模式

 

二、 容器资源控制

1、内存限制

docker run --help | grep memory
docker ps
docker rm -f demo
docker run --rm -it --memory 200M busybox ##运行容器限制使用内存200M
free -m  ##容器内和宿主机 的内存信息共享
ll -d /proc/meminfo ##内存信息存储目录

docker ps
docker inspect 8eaf11fb38be ##可以看到设置的内存200M
docker ps
docker rm -f  brave_driscoll 

docker run -d --name demo -m 200M nginx
docker ps
mount -t cgroup ##可以看到以文件和目录的方式组织在操作系统的 /sys/fs/cgroup 路径下
cd /sys/fs/cgroup/
 ls
 cd memory/
ls
cd docker/
ls ##可以看到运行的容器
cd ee9e314442a1946014927017f4f34bfd956d8e780bb531c494607b8df49dddb3
 ls
cat memory.limit_in_bytes##查看内存控制的资源限制,200M说明已经受限

docker run -d --name demo2 nginx ##再开一个容器不做内存限制
cd - #切换到之前的目录
cd ..
ls ##可以看到demo2容器id
cd 3955d8631839ffc805157981b147aab75fd4008e68974d438c1483be9b769743
ls
cat memory.limit_in_bytes ##查看内存限制,没有限制
cd ..
pwd 所有的docker 容器都在这个docker 目录中,这个目录里面的信息都是继承父级memory子系统的
 ls
cd ..
ls
cat memory.limit_in_bytes
mkdir x1##创建x1控制器
cd x1/
ls 里面内容继承父级子系统的
cat  memory.limit_in_bytes
echo 209715200 > memory.limit_in_bytes 给予200M内存使用量
cat  memory.limit_in_bytes

cd
df #可以看到tmpfs挂接的是物理机的1/2的内存
cd /dev/shm/
ls
free -m ##查看内存
dd if=/dev/zero of=bigfile bs=1M count=100 ##在此目录下写数据耗费的是内存
free -m ##空闲少了100M内存
ls
rm -f bigfile
free -m #删除刚建立的文件,物理内存还原
vmstat ##此命令也可以查看内存使用量
free -m

dd if=/dev/zero of=bigfile bs=1M count=300
free -m ##可以看到少了300M
cd /sys/fs/cgroup/memory/x1/
ls
cat memory.limit_in_bytes #可以看到设置的内存限制为200M
id ##因为使用的是超级用户,不受限制
cd -
 ls
rm -f bigfile
free -m
cd -
ls
cat tasks ##要使之生效,必须将其加入到进程任务中
yum search cgroup
yum  install -y libcgroup-tools.x86_64
cd -
ls
cgexec -g memory:x1 dd if=/dev/zero of=bigfile bs=1M count=300 ###内存子系统x1控制器
控制物理内存不能超过200

free -m #可以看到物理内存少了200M,但是swap分区也使用了100M
rm -f bigfile
free -m
cgexec -g memory:x1 dd if=/dev/zero of=bigfile bs=1M count=300
 free -m ##swap交换分区是物理内存不够用时备用的

rm -f bigfile
cd -
ls
 docker run --help | grep memory
cat  memory.memsw.limit_in_bytes#内存和swap总共限制资源
cat memory.limit_in_bytes
echo 209715200 > memory.memsw.limit_in_bytes ##给予200M
 cat  memory.memsw.limit_in_bytes
cd -
cgexec -g memory:x1 dd if=/dev/zero of=bigfile bs=1M count=300 ##命令被kill,swap不可用
free -m
du -h bigfile ##文件大小为200M

docker ps
docker inspect demo | grep Pid ##过滤出demo的pid
cd /sys/fs/cgroup/memory/ 进入memory控制器
ls
cd docker/
 ls 可以看到运行容器ID
cd ee9e314442a1946014927017f4f34bfd956d8e780bb531c494607b8df49dddb3 进入demo
ls
cat tasks ##容器内所有的进程都可以看到
cd ..
ls
cd 3955d8631839ffc805157981b147aab75fd4008e68974d438c1483be9b769743 进入demo2
ls
cat tasks #容器的进程还有容器内nginx其他进程,都是自动添加
docker inspect demo2 | grep Pid
cd
docker run --help | grep cpu ##针对cpu 的限制
docker run --help | grep devi ##还有设备io的

  2、cpu限额

Linux 通过 CFS(Completely Fair Scheduler,完全公平调度器)来调度各个进程对 CPU 的使用。CFS 默认的调度周期是 100ms。

我们可以设置每个容器进程的调度周期,以及在这个周期内各个容器最多能使用多少 CPU 时间。使用--cpu-period即可设置调度周期,使用--cpu-quota即可设置在每个周期内容器能使用的 CPU 时间。两者一般配合使用。

 cd /sys/fs/cgroup/
ls
cd cpu
 ls
mkdir x2
cd x2/  ##继承父级子系统的文件
ls
cat cpu.cfs_quota_us #-1 表示没有任何限制
cat cpu.cfs_period_us
echo 20000 >  cpu.cfs_quota_us ##表示20%的cpu运行时间每100ms
cat cpu.cfs_quota_us
dd if=/dev/zero of=/dev/null & ##此动作会直接占据cpu
top ##top命令查看cpu占用
cd /sys/devices/system/
 ls
cd cpu/
 ls ##cpu0不可以被关闭
cd cpu1/
 ls
cat online
echo 0 > online 设置关闭cpu1
 cat online
top ##按“1”可以看到只有cpu0运行,cpu1被关闭
echo 1 > online ##重启开启cpu1
top

 cd /sys/fs/cgroup/
 ls
cd cpu/ ##进入cpu进程
cd x2/
ls
echo 6205 > tasks #把dd进程id直接放入task 中
cat tasks
top #查看到%cpu为20%
kill 6205 #不需要时可以kill
top

cd
docker ps
docker rm -f demo
docker rm -f demo2
docker run -d  --cpu-period=100000 --cpu-quota=20000 --name demo nginx##运行容器将 CFS 调度的周期设为 100000,将容器在每个周期内的 CPU 配额设置为 20000,表示该容器每 100ms 可以得到 20% 的 CPU 运行时间
docker ps
cd /sys/fs/cgroup/
ls
cd cpu
cd docker/
ls
 cd def37a843dfc59e92d781f7e7e7ec0ee6831202d6cb3154175d93e15159f83d8
ls
 cat cpu.cfs_quota_us 自动设置CPU 配额为 20000

3、Block IO限制

docker run -it --device-write-bps /dev/vda:30MB centos:7 ##--device-write-bps限制写设备的bps速率为30MB/s

--/# dd if=/dev/zero of=/bigfile bs=1M count=200 oflag=direct #目前的block IO限制只对direct IO有效。(不使用文件缓存)

可以看到速率为31.6MB/s

docker run -it centos:7 ##不加速率限制运行,可以看到速率达到863MB/s
docker container prune
docker ps -a
docker rm -f demo

三、docker 安全加固

 

在容器内查看内存时显示的是宿主机的内存信息,为了安全起见有时候需要做限制

docker run --rm -it --memory 200M busybox

/ # free -m #给了200M但是swap出现的还是2G
*proc是没有做隔离的,所以容器和宿主机看到的是一样的【直接访问的是根下的proc】

cd /proc/
 ls
cd
 ls
yum install -y   lxcfs-2.0.5-3.el7.centos.x86_64.rpm
 lxcfs /var/lib/lxcfs & ##运行软件打入后台
 ps ax
 cd  /var/lib/lxcfs/  默认的数据目录:/var/lib/lxcfs/
ls    #会生成相应的cgroup和proc

cd cgroup/
ls
cd ..
cd proc/
 ls  #可以看到每一个文件都分别代表宿主机的6样信息

把lxcfs-2.0.5-3.el7.centos.x86_64.rpm从真机中传到docker1

利用LXCFS增强docker容器隔离性和资源可见性 

 

docker run  -it -m 256m       -v /var/lib/lxcfs/proc/cpuinfo:/proc/cpuinfo:rw       -v /var/lib/lxcfs/proc/diskstats:/proc/diskstats:rw       -v /var/lib/lxcfs/proc/meminfo:/proc/meminfo:rw       -v /var/lib/lxcfs/proc/stat:/proc/stat:rw       -v /var/lib/lxcfs/proc/swaps:/proc/swaps:rw       -v /var/lib/lxcfs/proc/uptime:/proc/uptime:rw centos:7  ##此时运行容器,运行时将lxcfs数据目录下的内容挂载到容器内

--/# free -m   #可以看到swap分区有200M

docker container prune
docker run --rm -it busybox

--/ # ip addr
--/ # ip link set down dev eth0  #执行命令没有操作权限,不允许
--/ # id  #可以看到是超级用户默认在运行容器时容器内的用户并不是真正的root用户

设置特权级运行的容器:--privileged=true 有的时候我们需要容器具备更多的权限,比如操作内核模块,控制swap交换分区,挂载USB磁盘,修改MAC地址等 

docker run --rm -it --privileged=true busybox##可以执行ip link set

这个权限比较大,接近于宿主机的root用户,为了防止用户权限的滥用,需要增加权限,只提供给容器必须的权限。此时Docker提供了权限白名单的机制,使用–cap-add添加必要的权限。
docker run --rm -it --cap-add=NET_ADMIN busybox ##容器具有网络管理的权限

-/ # fdisk -l  #看不到磁盘分区

docker run --rm -it --privileged=true busybox ##可以查看磁盘

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值