一 相关说明
Docker容器的安全性,很大程度上依赖于Linux系统自身!
生产环境中评估Docker的安全性时,主要考虑以下几个方面:
#(1)Linux内核的命名空间机制提供的容器隔离安全
#(2)Linux控制组机制对容器资源的控制能力安全
#(3)Linux内核的能力机制所带来的操作权限安全,Docker程序(特别是服务端)本身的抗攻击性。
二 相关概念的理解
什么是(what)cgroup
Cgroups 是 control groups(控制组) 的缩写,是Linux内核提供(主体)的一种可以限制、记录、隔离进程组(process groups)所使用的物理资源(cpu、memory、IO等)的机制。最初由 google 的工程师提出,后来被整合进 Linux 内核。Cgroups 也是 LXC 为实现虚拟化所使用的资源管理手段,可以说没有cgroups就没有LXC!
干什么(do)
限制进程组可以使用的资源数量(Resource limiting )
# memory子系统可以为进程组设定一个memory使用上限,一旦进程组使用的内存达到限额再申请内存,就会出发OOM(out of memory)
优先级控制(Prioritization )
# 比如可以使用cpu子系统为某个进程组分配特定cpu share
资源数量(Accounting )
# 比如可以使用cpuacct子系统记录某个进程组使用的cpu时间
进程组隔离(Isolation)
# 比如使用ns子系统可以使不同的进程组使用不同的namespace,以达到隔离的目的,不同的进程组有各自的进程、网络、文件系统挂载空间
控制(Control)
# 比如使用freezer子系统可以将进程组挂起和恢复
四个概念
# (1)Subsystems: 称之为子系统,一个子系统就是一个资源控制器,比如 cpu子系统就是控制cpu时间分配的一个控制器
# (2)Hierarchies: 可以称之为层次体系也可以称之为继承体系,指的是Control Groups是按照层次体系的关系进行组织的
# (3)Control Groups: 一组按照某种标准划分的进程。进程可以从一个Control Groups迁移到另外一个Control Groups中,同时Control Groups中的进程也会受到这个组的资源限制
# (4)Tasks: 在cgroups中,Tasks就是系统的一个进程
三 命名空间隔离的安全
(1)当docker run启动一个容器时,Docker将在后台为容器创建一个独立的命名空间
结论1:命名空间提供了最基础也最直接的隔离,但是与虚拟机方式相比,通过Linux namespace来实现的隔离不是那么彻底!
结论2:容器只是运行在宿主机上的一种特殊的进程,那么多个容器之间使用(共享)一个宿主机的操作系统内核
补充:在 Linux 内核中,有很多资源和对象是不能被 Namespace 化的,比如:时间
核心:我们无法控制资源的共享,但是可以控制资源的上限!
内核的命名空间起到隔离的作用,但是内核是共享的,所以无法做隔离!可以操作操作系统上所有挂接的group!
明确:默认对容器是没有控制的,但是每个控制器(控制项)都有一个docker目录,直接复制上级得来的!
小知识:Linux中其它的限制模块:limits security、pam 等其他控制模块!
四 控制组资源控制的安全
(1)当docker run启动一个容器时,Docker将在后台为容器创建一个独立的控制组策略集合。
- 通过新建文件夹创建一个cpu控制族群:mkdir x1,即新建了一个cpu控制族群:x1
- 新建x1之后,可以看到目录下自动建立了相关的文件,这些文件是伪文件
补充一个实验:通过容器的创建删除看对应目录下docker的变化!
回顾
1)CPU的限制
(1)聊一聊系统层面CPU的限制
说明:双核不会争抢,可以做CPU的绑定,默认三个才会争抢
相关参数的说明
# pu.cfs_period_us:cpu分配的周期(微秒),默认为100000。
# cpu.cfs_quota_us:表示该control group限制占用的时间(微秒),默认为-1,表示不限制。
# 如果设为50000,表示占用50000/100000=50%的CPU
现象:此时CPU的负载情况仍然没有发生变化,因为没有关联Pid的原因!
[root@docker1 x1]# dd if=/dev/zero of=/dev/null &
[1] 2962
[root@docker1 x1]# echo 2962 > tasks
2)聊一聊对Docker容器的限制
优先级:在争抢的时候生效(默认是1024)!
(2)聊一聊对内存的限制
1)对系统进程的内存限制
说明:可用内存包括两个部分,物理内存和swap交换分区,如果物理内存不够,swap来补充!
Swap作用:操作系统没有物理内存,才会使用,加快用户和硬件的响应!
# 安装相应的软件包
yum install libcgroup-tools.x86_64
# 说明:下一步是在上一步做内存限制的基础上!
进一步:做swap的限制
2)看对Docker的限制
# 容器可用内存包括两个部分:物理内存和swap交换分区。
#(1)--memory设置内存使用限额
#(2)--memory-swap设置swap交换分区限额
cd 9612325e96f8faec6c6c1b2f8933eb9b2f4d152dfdff386f496bd2822c60e3a4
[root@docker1 9612325e96f8faec6c6c1b2f8933eb9b2f4d152dfdff386f496bd2822c60e3a4]# cat memory.memsw.usage_in_bytes
3698688
[root@docker1 9612325e96f8faec6c6c1b2f8933eb9b2f4d152dfdff386f496bd2822c60e3a4]# cat memory.usage_in_bytes
3698688
注意:但是此时无法以root用户删除x2的目录,需要特殊工具命令
cgdelete -g memory:x2
注意:最好不要删除,以免后面再创建,当然也可以删除,然后,再创建!
(3)对用户使用内存的限制(补充)
说明:由于linux是多用户的,所以对于某些不守规则的人要进行相应的内存限制!
(4)对I/O的限制
## 了解这几个参数的含义!
read_bps (每妙I/O读的速率)
read_iops (每妙i/o的写次数)-->吞吐量的含义!
write_bps(每妙I/O写的速率)
write_iops(每妙i/o读的次数)-->吞吐量的含义!
# 目前的block IO限制只对direct IO有效,所以必须指明,不使用文件缓存!
(5)对容器状态的控制
生产环境中:有些顽固进程不能去kill掉,可以挂起或者暂停,不耗费资源!
总结:Linux Cgroups提供了很多有用的特性,确保各容器可以公平地分享主机的内存、CPU、磁盘IO等资源
目的:确保当发生在容器内的资源压力不会影响到宿主机系统和其他容器,它可以防止拒绝服务攻击(DDoS)!
(6)资源隔离
上述引入:在容器内部和宿主机中看到内存是一样的,由于资源隔离没有做好(虽然内存生效)!
明确:但是看到的是虚假的,隔离的不好!
原因:直接挂载/proc -->跟宿主机一样!
如何做呢?利用LXCFS增强docker容器隔离性和资源可见性
(7)用户权限(内核能力机制)
问题:资源太大
解决:黑白名单
[root@docker1 proc]# docker run --help|grep cap
--cap-add list Add Linux capabilities
--cap-drop list Drop Linux capabilities
[root@docker1 proc]#
# 说明:需要在Docker 服务开启之前,进行初始化--->chroot
[root@docker1 docker]# ls -ld /var/lib/docker
drwx--x--x 14 root root 182 Aug 8 2019 /var/lib/docker
补充: 其他安全特性
(6)安全加固
镜像的角度
容器的角度
(7)Docker的安全遗留问题
(8)顶尖的开源工具