传统虚拟机和Docker架构图

  • 对比图中Docker和应用同级别并且在靠边的位置
  • 用户在容器里的应用进程,跟宿主机上的其他进程一样,都由宿主机操作系统统一管理
  • 只不过这些被隔离的进程拥有额外设置过的Namespace参数
  • Docker在这里扮演的更多是旁路是的辅助和管理工作

KVM虚拟机和容器的性能

  • 一个运行CentOS的KVM虚拟机在不做优化的情况下,虚拟机自己就要占用100-200MB内存
  • 用户应用会被宿主机操作系统拦截和处理,损耗性能
  • 容器化的应用依然是宿主机的一个进程,不存在虚拟化带来的性能损耗
  • 使用Namespace作为隔离手段的容器并不需要单独的Guest OS,容器额外资源占用几乎不存在
  • "敏捷"和"高性能"是容器对比虚拟机的最大优势

容器的隔离不彻底

  • 宿主机上的多个容器之间使用的还是同一个宿主机的操作系统内核
  • 很多资源和对象不能被Namespace化,比如时间

Cgroups资源限制

  • blkio 为块设备设定I/O限制,一般用于磁盘等设置
  • cpuset 为进程分配单独的CPU核和对应的内存节点
  • memory 为进程设定内存使用的限制

容器是单进程模型

  • 容器的本质就是一个进程,用户的应用进程实际上就是容器里的PID=1的进程
  • 也是其他后续的所有进程的父进程
  • 在一个容器中,只能实现找到一个公共的PID=1的程序来充当两个不同应用的父进程
  • 这就是为什么很多人会使用systemd或者supervisord这样的软件来替代应用本身作为容器的启动进程

容器编排与容器生命周期

  • 容器本身的设计是希望容器和应用能够同生命周期
  • 否则一旦出现容器是正常运行的,但是应用早就挂了的情况
  • 在容器编排处理起来就很麻烦了

Cgroups不完善的地方/proc文件系统

  • Linux下的/proc目录存储是记录当前内核运行状态的一系列特殊文件
  • 用户能通过这些文件,查看系统以及当前正在运行的进程的信息,
  • 比如CPU使用,内存占用等,这些信息是top命令的主要信息来源
  • 如果你在容器中执行top指令,就会发现它显示的是宿主机的CPU和内存数据,并不是当前容器的数据
  • 因为/proc文件系统并不知道用户通过Cgroups给这个容器做了什么资源限制
  • 即/proc文件系统并不了解Cgroup限制的存在
  • 生产环境中必须修正这个问题,否则应用程序在容器里读取到的CPU核数,可用内存等信息都是宿主机上的数据
  • 会给应用的运行带来非常大的风险和困惑,这是容器化相较于虚拟机不尽人意的地方
最后修改:2019 年 08 月 05 日 05 : 09 PM