资源利用率更高:一台物理机可以运行数百个容器,但是一般只能运行数十个虚拟机
开销更小:不需要启动单独的虚拟机占用硬件资源。
启动速度更快,可以咋数秒内完成启动。
namespace是Linux系统的底层概念,在内核层实现,即有一些不同类型的命名空间被部署在内核,各个docker容器运行在同一个docker主进程并且功用同一个主机系统内核(宿主),各docker容器运行在宿主即的用户空间,每个容器都要有类似于一样的相互隔离的运行空间,但是容器技术是在一个进程内是现实运行指定服务的运行环境,并且还可以保护宿主机内核不受其他进程的干扰和影响,如文件系统空间、网络空间,进程空间等,目前主要通过以下技术实现容器运行空间的相互隔离
每个容器都要有独立的跟文件系统有独立的用户空间,以实现在容器里面启动服务并且使用容器的运行环境,即一个宿主机是Ubuntu的服务器,可以在里面启动一个centos运行环境的容器并且在容器里面启动一个Nginx服务,此Nginx运行时使用的运行环境就是centos系统目录的运行环境,但是在容器里面是不能访问宿主机的资源,宿主机是使用了chroot技术把容器锁定到一个指定的运行目录里面。
一个容器内的进程间通信,允许要给容器内的不同进程的(内存、缓存等)数据访问,但是不能跨容器访问其他容器的数据。
UTS namespace (UNIX Timesharing System 包含了运行内核的名称、版本
底层体系结构类型等信息)用于系统表示,其中包含了hostname和域名domainname,它使得一个容器拥有属于自己hostname标识,这个主机名标识独立于宿主机系统和其上的其他容器。
Linux系统中,有一个PID为1的进程(init/systemd)是其他所有进程的父进程,那么在每个容器内也要有一个父进程来管理其下属的紫禁城,那么多个容器的进程通 PID namespace 进程隔离(比如PID编号重复,器内使用top命令看到的PID为1的进程是nginx)
每一个容器都类似于虚拟机一样有自己的网卡,监听端口,TCP/IP协议栈等,Docker使用network namespace 启动一个vethX接口,这样你的容器将拥有它自己的桥接ip地址,通常是Docker0,而docker0实质就是Linux的虚拟网桥,网桥是在OSI七层模型的数据链路层的网络设备,通过mac地址对网络进行划分,并且在不同网络直接传递数据。
各个容器内可能会出现重名的用户和用户组名称,或重复的用户UID或者GID,那么怎么隔离各个容器内的用户空间呢?
User Namespace 允许在各个宿主机的各个容器空间内创建相同的用户名以及相同的用户UID和GID,只是会把用户的作用范围限制在每个容器内,即A容器和B容器可以有相同的用户名称和ID的账户,但是此用户的有效范围仅是当前容器内,不能访问另外一个容器内的文件系统,即相互隔离,相互影响,永不相见
在一个容器,如果不对其做任何资源限制,则宿主机会允许其占用无限大的内存空间,有时会应为代码BUG程序会一直申请内存,直到把宿主机内存占完,为了避免此类的问题出现,宿主机有必要对容器进行资源分配限制,比如CPU、内存等,Linux Cgroups的全称是Linux Control Groups,它最主要的作用,就是限制一个进程能够使用的资源上线,包括CPU、内存、磁盘、网络带宽等等。此外,还能够对进程进行优先级设置,以及将进程挂起和恢复等操作。
Cgroups在内核层默认已经开启,从centos和Ubuntu对比结果来看,显然内核较新的Ubuntu支持的功能更多。
cat /boot/config-版本号-generic