应用最好不要跑在特权用户( root )底下git
Docker 默认全部的应用都会跑在容器的 root user 底下,可是这样会形成一些潜在的安全隐患。在 production 环境跑的 Container 最好是经过 USER 命令跑在非特权用户底下。docker
隐患在哪,求补充。数据库
安全隐患是说若是这个 container 被 compromise 了,那么若是是 root 在跑这个 container 更可能使系统出现问题。可是用 root user 自己应该是没问题的。promise
是指的若是用 root 跑 container 会有问题吗?那为何推荐用 USER 命令来改变 docker 的非 root ?缓存
就是 Docker 的隔离效力有限,若是一个 container 里的应用是恶意的,并且是 root ,那若是它改了系统配置( root 权限,好比 unload 某个系统 module ,更改了某个系统文件),也会影响其余的 container ( share 一个 kernel )。安全
避免使用 apt-get upgrade运维
Upgrade 命令是用来升级当前基础镜像的。非特权用户没法 Upgrade 一些核心的应用。并且 Upgrade 命令会打乱已经缓存的镜像,使得编译时间加长。在通常状况下,选用正确的基础镜像是不须要升级的,若是真的须要,最好联系基本镜像的维护方,这样全部使用者都能从中获益。若是只是须要更新某个程序 foo ,那么使用 apt-get install – y foo 就能到达这个目的。优化
尽可能合并命令get
Dockerfile 中的每个命令都会建立一个新的 layer ,而一个容器可以拥有的最多 layer 数是有限制的。因此尽可能将逻辑上连贯的命令合并能够减小 layer 的层数,合并命令的方法能够包括将多个能够合并的命令( EXPOSE , ENV , VOLUME , COPY )合并。it
Dockerfile 中的每个命令都会建立一个新的 layer ,而一个容器可以拥有的最多 layer 数是有限制的。因此尽可能将逻辑上连贯的命令合并能够减小 layer 的层数,这也能够加快编译速度?
将多个能够合并的命令( EXPOSE , ENV , VOLUME , COPY )合并,好比:
使用“&&”来链接 RUN 命令,好比:
不过过分合并命令可能会影响 Dockerfile 的可读性,因此须要在优化代码和可读性之间作出权衡。
合理安排命令的顺序
命令的顺序会影响编译所须要的时间。每个命令都会产生一个 layer 。若是一个 layer 已经在缓存中,那么生成这个 layer 所须要的时间就很短。从第一个不在缓存的 layer 起,全部之后的命令都会被从新编译。由于这个缘由,咱们推荐将不常变更的命令放在前面,这样可使得更多的 layer 被成功缓存,从而减小编译时间。
避免在容器中存储数据
容器须要是无状态的,这样方便启动新的 Container 来替代 down 掉的 Container 。若是容器中包含状态,那么就须要额外的运维人员来恢复 down 掉 Container 的状态。
使用.dockerignore
使用.dockerignore 能够减小拷贝没必要要的文件到 Container ,这样能够减小镜像大小。好比不少地方都有.git 文件,可是这个文件就不须要拷贝到 Container 里面。
避免安装没必要要的软件
安装没必要要的软件既浪费空间又增长编译时间。好比一个数据库的 Container 就没有必要安装文字编辑软件。 更进一步,若是程序可以在本地编译,那么就不用在 Container 里安装编译程序所须要的软件和 lib 了。直接把本地编译好的 binary 拷贝到 Container 里就好。