现在的位置: 首页 > 云计算 > 正文

Docker是做什么的?

2020年02月21日 云计算 ⁄ 共 3179字 ⁄ 字号 评论关闭

  自从Docker在2013年初上线以来,就与程序员及系统管理员之间产生了一种爱恨交加的奇妙关系。虽然与我交谈过的一些经验丰富的的开发人员都非常不喜欢容器化(稍后会详细介绍), 但是为什么许多大公司,包括eBay、Twitter、Spotify和Lyft在内,都在他们的生产环境中采用了Docker呢?

  Docker究竟是做什么的呢?

  不知道您是否曾使用过VMware、VirtualBox、Parallels或任何其他的虚拟化软件呢?Docker和这些软件差不多(尽管没有花哨的GUI), 它能创建出带有操作系统的虚拟机,并且可以绑定选定的web应用程序及其依赖项。

  虚拟机的速度不是很慢吗?

  虚拟化推动了云计算革命,我喜欢把Docker称为虚拟化的最后一步, 因为实际上,它执行着的正是您开发出来的业务逻辑。

  但是,通常意义上真正的虚拟机的速度是很慢的,而且,并不能将Docker所做的工作完全归类于虚拟化。

  相反,Docker通过使用runc(由Open Containers Initiative提供维护)在内核(对不同进程命名空间和设备命名空间提供的)支持的基础上建立额外的抽象层,从而能够共享很多主机系统的资源。因为在Docker容器和主机内核之间没有额外的虚拟化层,所以容器能够提供与主机相同的性能。

  完全虚拟化的系统会为其分配自己的资源,并且进行最小化程度的共享(如果需要的话),这会导致更多资源之间的隔离,但系统也会变得需要更多资源——然而,通过Docker,资源的隔离会减少,同时容器也会变得轻量级(需要的资源更少)。

  如果您要运行一个需要在保证资源的基础上完全隔离的系统(例如,游戏服务器),那么或许该选择基于KVM或OpenVZ的虚拟机。但是,如果您只是想要将各个进程隔离开来,将其运行在一个大小适中的主机上,同时又不致力于把自己搞破产,那么Docker将会是您的不二选择。

  不能直接将应用程序上传到云服务器上吗?

  如果不在意基础设施、环境一致性、可扩展性或可用性这类东西的话,是可以这样做的。

  设想一下:您管理着12个Java服务,并将它们全部部署到了运行着Ubuntu和Java 8的独立服务器上,以用于开发、质量保证、预发布及生产环境。即使您应用程序的使用程度并不高,也需要管理至少48个服务器(12个服务*4个环境)。

  假设现在需要您的团队带头更改策略,将运行环境升级到Java 11。那么您需要登录并手动更新48个服务器。即使是使用Chef或Puppet这类的工具,工作量也非常大。

  有什么更简便的解决方案呢?

  Docker能够帮助您创建所需操作系统的快照,并只在其上安装所需的依赖项。这样一来,您可以管理或省去所有的“臃肿软件”。您可以最小化安装Linux(我推荐Alpine Linux,但在本文中,我将继续使用Ubuntu),并且只在上面安装Java 8。

  在需要更新时,只需要在您Java映像的Dockerfile文件中说明使用Java 11,构建并推送到容器存储库(如Docker Hub或Amazon ECR)中。此后,您只需修改您的应用程序容器基础镜像标签,引用新的快照并重新部署即可。

  以下示例罗列了在Ubuntu 18.04最小操作系统之上构建Docker容器的要点:

  我将使用标签oracle-jdk-ubuntu-18.04:1.8.0_191来构建此映像并将其推送至Docker Hub账户damian, 然后用它来为我的服务构建另一个容器:

  # Instructs Docker to build this container on top of this snapshot

  FROM damian/oracle-jdk-ubuntu-18.04:1.8.0_191

  # Copys the application JAR to the container

  COPY build/hello-world.jar hello-world.jar

  # Executes this command when the container starts

  CMD java -jar hello-world.jar

  现在,如果我需要将服务更新到Java 11,那么需要做的只是:发布安装了兼容JRE的Java快照新版本,在服务容器中的FROM声明中更新标签,令容器使用新的基础映像。完成!接下来,您的所有服务都会随着Ubuntu和Java的更新而更新。

  但是这对我的开发来说有什么意义呢?

  我最近开始在单元测试中使用Docker。假设您有成千上万的测试用例(如果真是这样的话,相信我,我对您的痛苦感同身受),这些用例都连接到一个数据库,其中每个测试类都需要一个数据库的新副本,并且每个测试用例都将对数据执行CRUD操作。

  通常来讲,在每次测试之后,都需要使用类似Redgate的Flyway之类的工具来重置数据库,但是这就意味着您的测试必须按顺序运行,该过程会花费很多时间(我见过要因此而花20分钟才能完成的单元测试套件)。

  在Docker中,您可以轻松地创建您数据库的映像(我建议使用TestContainers),在容器中为每个测试类运行一个数据库实例,然后并行运行整个测试套件。因为所有测试类都是并行运行的,并且都链接单独的数据库, 所以它们都可以同时在同一主机上运行并且快速完成(假设您的CPU能扛住的话)。

  我在用Golang编码时也会使用Docker。与其直接在开发机器上安装GO,我更喜欢采用类似于Konstantin Darutkin的方法:通过安装Go和依赖项来维护Dockerfile文件,可以将其配置为在对源文件进行修改时实时重新加载项目。

  这样一来,我已经有了自己的项目和Dockerfile版本控制文件,如果我要修改自己的开发机器或将其格式化,我只需要重新安装Docker,从上次停留的地方继续就可以了。

  总结

  如果您经营着一家初创公司,还没有决定要用什么来支撑您的新技术栈,又或者您是一家成熟的服务提供商,正在考虑将您的产品和非产品环境容器化,但又不敢在“未经测试的”海域上航行,那么可以考虑以下的几个问题。

  1、一致性

  您可能有整个行业中最棒的一群开发人员,但是在所有这些不同的操作系统中,每个人都有自己喜欢的设置方式。如果您已经用Docker配置了完善的本地环境,那么新开发人员只需安装,用该应用程序生成一个容器,然后启动即可。

  2、调试

  您可以轻松地隔离并消除整个团队环境中的问题,而无需了解团队成员计算机的设置方式。一个很好的应用实例是:当我们必须通过从ntpd迁移到Chrony来修复服务器上的一些时间同步问题时,我们只需要更新基础映像(不需要通知开发团队)。

  3、自动化

  目前,包括Jenkins、CircleCI、TravisCI等在内的大部分CI/CD工具都被完全集成到了Docker中,因此您可以轻松地将从一个环境应用到另一个环境。

  4、云端支持

  要想了解您的服务器和DataDog上运行着什么,就需要持续监视和控制容器。一家云监视公司曾说道:

  容器的短寿命和密度增加对基础设施的监控具有重要意义。它们代表需要单独监视的事物数量的数量级增加。

  自我管理的云编排工具(例如,Docker Swarm和Kubernetes)以及由供应商管理的工具(例如,AWS的Elastic Container Service和Google Kubernetes Engine)提供了针对这一问题的解决方案,这些工具可以监视和管理容器集群和调度。

  随着Docker的广泛使用以及与AWS和Google Cloud等云服务提供商的紧密集成,Docker正在迅速成为处理您新应用程序或现有应用程序的明智之选。

抱歉!评论已关闭.