Docker容器实战十三:容器安全的最佳实践

Posted 运维老兵Alex

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Docker容器实战十三:容器安全的最佳实践相关的知识,希望对你有一定的参考价值。

一. 容器配置

1. 禁止使用特权容器

使用--privileged启动容器时,会将所有内核功能赋予容器,从而覆盖Capability的能力限制。在这种情况下,容器可执行主机层面能做的大部分事情,从而给系统带来较大的安全隐患,所以应该被禁止。

$ docker run -d --privileged nginx


2. 限制容器的资源使用

默认情况下,主机上的容器对于资源的访问并没有受到限制。此时,当某个容器被攻击或者程序出错时,将可能因为过多占用资源而影响到主机和其他容器的运行。

因此,可以通过Cgroup的特性来设置容器的资源使用限制,这样得以最大程度减少因此类问题而产生的影响 。

示例1:限制CPU可以使用的最大核数为1 。

$ docker run -d --cpus 1 nginx

示例2:限制容器可以使用特定的CPU,如宿主机有4个CPU,我们只允许容器使用第一个CPU,可以设置如下 :

$ docker run -d --cpuset-cpus 0 nginx

示例3:限制容器最大内存使用量为512M。

$ docker run -d -m 512m  nginx


3. 隔离容器网络

Docker默认使用bridge网络,该网络会创建一个虚拟网桥,连接在同一个网桥之间的容器可以互相访问。为了提升网络安全性,建议不要依赖默认的docker0网络,而是通过自定义网络方式进行容器网络的划分,这样可保证对宿主机中的容器之间做到访问隔离。

另外,在主机层面也应尽可能进行网络划分,不同的主机运行不同安全性要求的容器,如开发环境、测试环境和生产环境的宿主机应该彼此隔离。


4. 禁止挂载主机系统目录

主机中与系统相关的目录,包含 /boot、/dev、/etc、/proc、/sys、/usr等,应该明令禁止被挂载到容器中。尤其是在读写模式下,这种情况会导致容器具有对主机系统进行修改的能力,从而给主机系统带来极大的安全隐患。

遗憾的是,目前在Docker层面并没有相关的技术方案来限制此类行为,只能通过审计等手段进行发现。


5. 将容器的根文件系统挂载为只读

将容器的根文件系统挂载为只读模式,这种模式可以避免对根文件系统带来任何的修改,从而保证了容器的安全性。当然,只读的模式也会带来不便 ,需要结合挂载存储来使用,将输出的内容写到持久化存储中。

配置只读的方式很简单,在启动容器时添加 --read only 选项,如下:

$ docker run -it  --read-only  nginx sh
# echo test > /root/1.txt
sh: 2: cannot create /root/1.txt: Read-only file system


6. 禁止共享主机的网络栈

在启动容器时,使用--network host 可以让容器与主机共享网络栈,此时,容器会使用主机的IP及其他的网络配置,并自动将容器的端口映射到主机。

这种方法虽然带来了一定的便利性,但也给容器带来了风险。在这种模式下,容器内可对主机的网络栈进行操作,所以并不建议使用。

$ docker run -d --network host  nginx


二. 镜像管理

1. 禁止在镜像中存储机密信息

容器中程序在正常运行的过程中,通常需要使用到一些机密信息,如数据库账号密码、access token等。诸如此类的敏感信息,不应被保存到镜像中,不然会造成机密信息泄露风险。

可以使用配置中心等方案,将这些信息移到外部进行管理。


2.选用最小化的基础镜像

在使用Dockerfile构建应用镜像时,需要选择一个镜像来作为基础镜像。对于该镜像的选择,应避免使用功能大而全的镜像,而采用最小化满足的模式。

这样可以带来两个好处:

  1. 最大程度减少安全漏洞。
  2. 减少对于资源的占用。


3. 扫描并验证镜像

在 2019 年时,作为安全公司的Snyk 发现,10大最流行的 Docker 镜像中,每个镜像至少有 30 个安全漏洞。这足以引起我们对于镜像安全的警觉。

Docker容器实战十三:容器安全的最佳实践_docker


通过对Docker镜像进行漏洞扫描,可以让开发和运维人员清楚镜像的安全状态,并采取措施修复发现的问题,从而实现更安全的部署。

目前支持镜像扫描的开源方案有Docker scan、Clair、Anchore等,其中Docker Scan已集成到最新的Docker版本中,可以开箱即用。


4. 使用多阶段构建 

在旧的版本中,构建镜像的操作通常在一个Dockerfile流程中完成,在这种模式下构建的镜像会包含很多冗余的文件,如源码文件、下载的依赖包、打包产生的临时文件等。

为了解决这个问题,Docker在17.05 版本开始支持使用多阶段构建(Multi-stage builds)。使用这种模式构建镜像时,我们可以第一阶段完成代码的打包等工作流程,然后在第二阶段选择合适的运行镜像,并将上个阶段生成的包拷贝到镜像中配置运行。

多阶段构建具有速度快、镜像体积更小、安全性更高等特点,建议采用此种方式来进行镜像的构建 。

示例:

#阶段一:编译打包
FROM maven:3.5.0-jdk-8-alpine AS builder
ADD ./pom.xml pom.xml
ADD ./src src/
RUN mvn clean package

# 阶段二:配置运行
From openjdk:8-jre-alpine
COPY --from=builder target/my-app-1.0-SNAPSHOT.jar my-app-1.0-SNAPSHOT.jar
EXPOSE 8080
CMD ["java", "-jar", "my-app-1.0-SNAPSHOT.jar"]


三. 管理规范

1. 限制用户对容器主机的访问

运行容器的主机应该存放在安全、可靠的环境中,如IDC机房,这可以在物理上保证机器的安全性。同时 ,做好系统登录权限的管控,只允许可信任的用户登录访问主机,这样能够减少由于人为影响而出现的故障。


2. 定期更新Docker版本

过时的版本由于已发现的漏洞,容易受到安全攻击。新版本通常会修复旧版本出现的Bug和程序错误,有利于更好地保证容器安全。作为容器的管理员,需要定期进行Docker版本的更新,并维持着较新的版本。


3.完善容器监控

如何合理有效的利用好监控是容器管理员的重要工作,一套完善的监控系统有利于帮助我们及时发现容器的问题,例如资源负载高、容器退出等。

关于容器的监控,目前比较常用的方案有cAdvisor+Prometheus+Grafana+Alertmanager组合,该方案集成监控、展示和告警等系列功能,可以有效发现容器问题。



 专注于Devops、SRE、运维开发等技术分享,扫码关注公众号,获取更多精彩内容!

Docker容器实战十三:容器安全的最佳实践_devops_02

以上是关于Docker容器实战十三:容器安全的最佳实践的主要内容,如果未能解决你的问题,请参考以下文章

Prometheus监控运维实战十三:Docker容器监控

运维实战 容器部分 Docker安全

运行容器的最佳实践 - 每天5分钟玩转 Docker 容器技术(24)

运行容器的最佳实践 - 每天5分钟玩转 Docker 容器技术(24)

在 Elasticbeanstalk for Scala Apps 中为 Docker 多容器环境部署和托管工件的最佳实践是啥?

docker最佳实践-----美团点评的分享