唠唠背景
自我工作以来就一直听到周围人在谈docker和容器,记得真正第一次接触docker是17年在上海,我当时被外派到某大型外资硬件提供商做云计算工程师, 主要做的工作就是负责维护原有的openstack云平台和ceph集群,以及日常服务器的一些上下架和维护工作。因为我之前的项目中openstack都是以传统服务来部署的,日常运维什么的基本没啥问题,而这次面对的环境是容器化后的openstack(kolla实现),也算是逼自己要好好看看docker这块儿的东西了,当时九州云属于kolla项目的主要贡献者,也和我们有很多合作关系,所以期间有很多不太理解的地方也是请教了相关的几位大佬。
18年离开了上海,入职了北京某家金融领域解决方案提供商,主要做的也一直是容器化相关的事,从docker到k8s,从慢慢摸索到推出适合本公司产品的定制化容器云平台,期间我会有很多时候需要向甲方以及公司同事介绍我们在做的事儿,以及用到的技术、行业的现状等等,借着最近时间充裕,打算写一篇关于介绍docker的文章,如果有幸被您看到,也请提出宝贵的意见,十分感谢。
以下内容多属于普及性文字,不会涉及太多技术点,如果有时间会抽专门的章节来具体阐述。
什么是容器
纵观整个IT界历史长河,一个新兴技术能够火爆与当时的市场痛点是息息相关的,就比如当初如日中天的AWS和Openstack提供了云计算的模式,使得万物云化,资源按需使用,大大的提高了服务器的资源利用率,降低了人力物力的成本。慢慢的人们发现,当申请好一批虚拟机后,通过手工或者自动化脚本部署自己的应用时会出现各种奇奇怪怪的问题,因为本地环境与云端虚拟机环境不一致,所以导致了大量的排错过程。后面PaaS理念的一经提出(应用托管),赢得了广大开发者的关注,而docker项目的发布为应用打包问题提供了一份近乎完美的解决方案。
容器与操作系统
我们经常把容器叫做docker,但其实容器还有coreOS的rkt。在介绍容器前,大家可以先想想操作系统是如何管理进程的,我们登录到一个操作系统内执行
1 | ps -elf |
可以看到各种进程,这些进程包括了系统自带的和用户部署的,并且进程间可以互相看到,也可以互相通信,这些进程共享着同一份的文件系统,意味着他们可以操作同一份文件,最后他们还使用着同样的系统资源。
上述这些特点会产生一系列的问题:
- 具有高级权限的进程可以攻击其他进程
- 具有高级权限的进程可以对其他进程所需的文件增删改查
- 应用之间会存在资源争抢问题
容器本质上是把系统中为同一个业务目标服务的相关进程合成一组,放在一个叫做namespace的空间中,同一个namespace中的进程能够互相通信,但看不见其他namespace中的进程。每个namespace可以拥有自己独立的主机名、进程ID系统、IPC、网络、文件系统、用户等等资源。使得容器这个父进程只对自己的子进程有感知,而对于宿主机其他进程互不感知。
linux提供了chroot的系统调用方式可以把一个子目录变为根目录,容器会在chroot的帮助下获得一个独立的文件系统,这样进程对文件系统的增删改查都不会影响到其他进程的使用。
此外,为了限制namespace对物理资源的使用,对进程能使用的CPU、内存、io等资源需要做一定的限制。这就是Cgroup技术。
总结:
基于传统应用部署方式的痛点,docker通过linux的namespaces实现了资源视图的隔离,通过chroot来提供独立的文件系统,通过cgroup控制资源使用率。
容器与虚拟机
提容器不得不提虚拟机,他们都是为应用提供封装和隔离的。
- 虚拟化层:虚拟机有Hypervisor层和GuestOS,Docker省去了Hypervisor,其虚拟化技术是基于内核的Cgroup和Namespace技术,Docker通过libcontainer与内核交互,所以在很多方面,它的性能与物理机非常接近。
- 启动速度:docker启动快速属于秒级别。虚拟机通常需要几分钟去启动。
- 隔离性:docker属于进程之间的隔离,那么多个容器还是使用着同一个操作系统内核,所以docker的隔离性更弱,虚拟机可实现系统级别隔离。
- 迭代:虚拟机可以通过导出模板实现环境交付的一致性,但镜像分发无法体系化;Docker在Dockerfile中记录了容器构建过程,可在集群中实现快速分发和快速部署,快速回滚。
- 系统支持量:同样配置的服务器支持的容器数是虚拟机的十倍以上。
docker的优势
- 更快速的交付和部署;开发者可以使用一个标准的镜像来构建一套开发容器,开发完成之后,运维人员可以直接使用这个容器来 部署代码。 Docker 可以快速创建容器,快速迭代应用程序,并让整个过程全程可见,使团队中的其他成员 更容易理解应用程序是如何创建和工作的。 Docker 容器很轻很快!容器的启动时间是秒级的,大量地节约 开发、测试、部署的时间。
- 更高效的虚拟化;不需要额外的hypervisor 支持,它是内核级的虚拟化,因此可以实现更高的性能和效率。
- 更轻松的迁移和扩展;Docker 容器几乎可以在任意的平台上运行,包括物理机、虚拟机、云平台、服务器等。 这种兼容性可以让用户把一个应用程序从一个平台直接迁移到另外一个。
- 更简单的管理;使用 Docker,只需要小小的修改,就可以替代以往大量的更新工作。所有的修改都以增量的方式被分发和 更新,从而实现自动化并且高效的管理。