最后更新:2020-03-14 11:43
最近,我构建了一个本地开发环境,并使用Docker进行了一些关键的集成测试当我完成工作时,我意识到在开始工作之前,我没有考虑到以下深刻的影响:
要求开发人员拥有Docker和Docker-Cost;在本地机器上;真正可用需要相当多的配置环境。我编写了shell脚本来“缓解”这些配置问题,但是混淆了系统的实际工作方式。我写的shell脚本最后看起来也很短视——它在某些环境下运行良好,但是如果你在Windows中工作,你只能依靠自己。我花了大部分时间解决一些简单的数据库连接问题,发现我的数据库容器配置不正确。在我投入这项工作的所有时间里,结果确实让我的团队受益匪浅,并最终帮助我们解决了集成测试中的一些挑战。但对我来说,更有趣的是它带来的挑战,更不用说在最终合并之前对我的拉请求的激烈讨论了。
更重要的是,这个环境最终服务于一个目的——为集成测试提供清晰性,而不是像我最初希望的那样提供一个整体开发环境最终结果是,我们从开发人员的机器中移除了环境,并最终以创建集成测试资源的容器的形式将其部署到云提供商。除了这个亮点,我的努力基本上失败了,尤其是考虑到我最初的动机。
我怎么会出错?我所有的努力仅仅是为了一个奇特的测试环境吗?我决定更深入地研究这个基于容器的开发环境问题。从那以后,我学到的东西极大地改变了我将来处理这个问题的方式。
199集装箱的现状大量调查表明,码头工人的使用将继续增长,特别是随着基础设施的增长和复杂性。2018年6月的一项Datadog调查显示,约25%的公司使用Docker部署了某种形式的基础设施。这些环境中有一半是以某种方式精心规划的,从2017年到2018年部署增加了75%。根据这些消息来源,码头工人的“革命”正如火如荼地进行着,没有任何放缓或停止的迹象。(我仍然对75%的公司在部署中使用什么感到好奇,这与问题无关。)DataDog在2018年的调查中提到,最广泛使用的Docker图像是“Nginx、Redis和Postgres”我认为这是合理的,因为运行应用程序依赖项的容器似乎是容器化的第一步Docker Compose为多容器应用程序提供了一个相对简单的工具;对于开发人员来说,它似乎也是一个很好的工具,可以为他们自己的环境运行特定的底层基础设施。换句话说,当您在项目中准备好一个docker-compose.yml文件时,您就可以开始了。
199家公司中有25%在生产环境中运行Docker。他们中有多少人使用Docker作为开发工具?根据2019年堆栈溢出调查报告,38.4%的受访者在开发工作中使用容器,但大约一半的受访者目前不使用任何容器技术。我想知道是否有办法进一步理解为什么开发人员不像我最初想象的那样频繁地使用Docker。我已经决定深入研究,粗略了解一下Docker上开发人员的观点。许多开发人员讨厌在他们自己的环境中使用Docker,这是有充分理由的——容器的引入似乎减缓了开发人员和他们正在构建的环境之间的反馈循环。开发环境的容器化似乎也为操作人员创造了一个不必要的抽象,要求他们能够直接进入代码、运行时环境,甚至更低级别的操作系统——所有这些都是在他们构建特性的时候。支持Docker作为开发工具的人说这样做仍然是有益的。使用容器的开发环境也可以实现开发团队之间的一致性。如果每个人都将容器用于他们的数据库、缓存或各种其他基础设施,那么准备代码将会非常简单,因为完整的开发环境触手可及。假设您的团队愿意在本地运行容器,您将永远不会在开发环境和生产环境之间产生差异。运行brew升级时,不会有更多令人不快的惊喜-容器将始终与您的需求保持同步。坦白地说,我对这两种人都有同感。作为一个脚踏实地的开发人员,我认为运行容器有很大的好处。然而,我不认为这些好处可以清楚地映射到开发人员的工作流程中我认为这不同于在开发环境中使用Docker的经验,因为Docker不是开发人员的工具。然而,我不认为这意味着开发团队不应该考虑使用Docker来满足他们自己的需求。然而,我认为使用Docker作为另一种操作工具可以帮助减轻在本地开发环境中运行Docker的痛苦。
容器是开发者友好的抽象吗?
根据Docker的官方定义,容器是
,这是一个标准的软件单元,它对代码及其所有依赖项进行打包,以便应用程序可以快速、可靠地从一个计算环境迁移到另一个计算环境上运行。低于
是一个更好的定义:
容器是应用层的抽象,它将代码和依赖项打包在一起
听起来不错,不是吗?是的,尤其是当您试图部署代码时换句话说,如果我的主要问题是让我们的代码在任何地方运行,容器似乎是最好的抽象——但是我不需要知道我们运行的代码,相反,我需要能够预见我们如何运行它。这对运营商来说非常强大。
作为开发人员,这种抽象可能会引起一些麻烦容器本身并不关心运行的是什么。操作系统是有意抽象的,就像任何运行容器所必需的依赖一样。应用层本身和底层操作系统一样短,访问这些抽象层需要理解Docker希望如何运行代码。
关于容器的预期用途我已经说了很多,但是我认为说容器只为操作团队准备是错误的。我认为开发人员可以受益于将他们环境的某些部分集装箱化挑战在于创建一个真正对开发人员友好的、基于容器的工作流
基于Docker的开发环境中的常见陷阱
最后,我选择在自己的开发工作中广泛使用Docker这对我非常有效,尤其是对我每天做的工作。在测试双,我主要从事开发和SRE,所以在日常工作中使用容器是非常有意义的。
当然,这可能不适合您的团队。然而,如果你真的想探索在开发环境中使用Docker,我想提醒你一些我个人经历过的常见陷阱。
假设容器是包含性的
在容器化开发环境中,最大的陷阱可能是假设部署中获得的好处与开发人员在本地体验到的好处相同
同样,假设一个团队想要广泛使用Docker,这个假设可能不适用于您团队的工作模式。如果开发人员相对独立于操作,那么假设他们每天都想在本地使用容器是不安全的。但是,如果您在一个团队中工作,其中开发人员也做一些操作和维护工作,如果您在容器开发环境之外提供其他选项,可能会对您的团队有好处。
本地运行容器的现实是它们消耗大量资源在一个典型的工作日,Docker仅在我的机器上就占用了大约36GB的存储空间对于我的特定品牌和型号的工作站来说,这不是一个惊人的系统使用,但是我可以很容易地推断,当我在工作流中包含更多容器时,它将显著增加。Docker也总是在我的CPU、内存和磁盘资源活动监视器前面。
更重要的是,虽然这可能不会对我的机器造成很大的阻力,但这并不意味着它也不会影响其他机器。将如此多的资源分配给Docker的最终决定应该取决于开发人员自己的个人偏好。换句话说,您的笔记本电脑不是服务器,它可能根本不需要根据服务器标准构建的容器资源。
,但是,即使不包括系统资源,开发环境也不能与任何运行代码的系统很好地匹配。过去,差距非常大,以至于我们经常不得不通过隧道技术连接到与生产服务器完全相同的环境。如果有问题,一些人(包括我自己在内)甚至被迫在网上修改这些系统的代码。
开发人员需要专注于编写可维护、可靠且经过良好测试的代码我相信在有限的环境中工作可以带来更好的代码实践和决策——你不得不依赖于编写干净、可维护和可行的代码,而不是试图配置服务器来处理性能瓶颈和低效的实现。
将技术堆栈的部分内容加载到容器中。挑战在于减少运行容器所需的认知开销。开发人员需要在工作中构建和维护许多上下文。如果本地Docker环境破坏了这个上下文,例如,为了确定一个容器是否正在运行,这只会导致长期的失望。
同样,要求开发人员使用docker run命令跳转到容器会增加上下文切换的认知开销这不仅与开发人员在自己的本地环境中开发时构建的模式背道而驰,而且还需要额外的docker CLI知识,这给开发人员实现目标带来了负担。当我不得不跳到Docker容器去调试一些东西时,我不禁感到有些奇怪。正如我前面提到的,这有点违背直觉:通过隧道技术连接到生产服务器
其他服务也是如此如果您在一个完全依赖于微服务的团队中工作,而其他团队需要各种服务来构建他们自己的特性,那么在提供这些图像作为容器时,您需要非常小心。在这些情况下,团队使用自己的环境来支持服务可能比将服务与容器混淆起来更有优势。
具体来说,对于这些内部服务,审核它们的文档可能比将它们加载到容器中更有价值维护不善的文档和容器的组合可能会导致相当大的认知失调,从而导致Docker环境的废弃。此外,我认为我们所有人都应该更仔细地查看文档,更频繁地审核它们,而不是创建新的文档。
我上面提到的调查结果指出,在使用容器的团队中,Nginx、Redis和Postgres非常受欢迎。它们如此受欢迎的原因显而易见。除非您的团队正在编写自己的RDBMS或网络服务器/负载平衡器,否则在您的技术堆栈中引入这样的开源应用程序会让您受益匪浅。
但是在集装箱化之前,运营团队获得的利益可能与开发团队在决定将他们纳入技术堆栈时希望获得的利益不匹配通过将这些依赖封装到容器中,操作团队可以受益于类似的加速器,类似于开发人员无需编写自己的RDBMS就可以获得的好处。
集装箱邮政为部署、监控和扩展这种重要的依赖性提供了大量的选项它还减少了系统更新、升级和管理的开销这对运营团队来说是好的,但是它满足开发者的需求吗?
字,不符合即使设置应用程序堆栈像运行docker-compose up -d一样简单,它也不适合大多数开发人员本地运行环境的心理模型。这两种工作流之间的区别是一个根本的区别。
开发人员希望能够深入研究他们需要的抽象,并要求团队使用全新的工具和完全不同的方法来运行他们的本地环境,这是一个大问题。具体来说,开发人员需要能够运行数据库迁移,跳转到数据库命令行界面,并跟踪数据库日志对于技术堆栈中的任何关键组件都是如此
这并不意味着没有开发人员愿意在本地使用Docker来处理各种事情但是我敢打赌,使用Docker的开发人员已经找到了在他们的工作流程中无缝工作的方法,不管他们是刚刚做了习惯性的改变,还是已经编写了脚本来使它更符合他们自己的环境。
围绕容器命令编写新脚本
说到脚本,如果您正在构建一个类似这样的本地环境,并且您正在尝试降低开发人员在Docker上运行各种东西的成本,您的最初想法(像我一样)可能是编写许多与容器工作相关的重复任务的脚本。
这种偏好不一定会引起误解毕竟,我们被教导使用脚本来解决重复的任务,这样我们就可以专注于较少重复的任务。但是,请注意不要编写太多的脚本,尤其是当您的团队对容器领域还比较陌生的时候。如果不同团队中的许多开发人员采用这种方法,那么您必须考虑您的团队维护定制bash脚本的积极性和兴趣,以便他们在本地环境中运行容器。
我提到过使用docker CLI有一些费用,但是如果一组开发人员愿意使用容器,那么给他们时间、培训他们,让他们使用docker自己的工具,而不是潜在地混淆Docker自己的内部工作,会更合理。这的确是一个必须掌握的工具,但不要围绕这些命令编写新的脚本,这样可以减轻故障诊断的认知压力,并对工具本身有更广泛的了解。
这也是我最担心的。定制容器包装并围绕容器编写新的脚本会添加更多的代码,因此需要维护更多的东西。你的团队应该承担这些费用。如果您的团队认为这是他们工作流程的净收益,那么继续我们想要避免的陷阱是一个被放弃的定制shell脚本,对于那些试图在您的环境中工作的人来说,这是一个潜在的时间陷阱,尤其是当新的人员刚刚开始参与开发工作时。
包含但没有选择
如果您有兴趣迁移到一个容器化的开发环境,我认为您应该花大量时间为本地运行的系统构建简单的替代方案换句话说,不要认为在本地环境中使用Docker是一个绝望的决定。记录在标准本地部署中设置应用程序的步骤,并为那些对运行容器感兴趣的人提供替代方案让您的团队决定这个工作流程是否合适
总之,如果不知道开发环境的权衡,开发团队的工作将很难在没有选择的情况下进行。结论没有所谓的建立开发环境的正确方法虽然鼓励团队采用容器可能会带来一些额外的好处,但最终目标是改进开发人员的工作流程。如果我们牺牲了为技术抽象写好代码的能力,那么我们就是在制造低效。
,像其他任何事情一样,最终的决定应该由团队做出,任何环境,无论是传统的还是容器,都不应该保留给个人偏好。与您的团队合作,找出当地发展中的难点,您将实现良好的平衡。
本文由 在线网速测试 整理编辑,转载请注明出处。