点击围观!腾讯 TAPD 助力金融行业研发提效、敏捷转型最佳实践! 了解详情
写点什么

Docker Compose 的 4 种错误使用方式

  • 2021-02-20
  • 本文字数:2752 字

    阅读完需:约 9 分钟

Docker Compose的4种错误使用方式

本文最初发布于 Earthly 博客,经原作者授权由 InfoQ 中文站翻译并分享。


告诉我,这是不是听起来很熟悉?有人要把 docker-compose 介绍给你,你可能是自愿的,也可能是被迫的。你用了一段时间,但发现它很不灵活。我要告诉你,你可能用错了。


这可能有点夸张。我不认为存在 100%正确或错误的使用方法:自主构建和开发设置往往有各种奇怪的要求,所以标准可能不符合需求。如果你的情况并不完全相符,请带着适当的怀疑态度阅读本文。


本文介绍了我自己使用 docker-compose 犯的一些错误。


我将重点关注与集成测试相关的用例,以及使用 docker-compose 作为开发环境。对于生产使用,我认为 docker-compose 通常并不适合。

问题 1:使用主机网络


新用户遇到的第一个麻烦是 Docker 网络的使用。在你了解了 docker build docker run 的基础知识后,这是你需要学习的另一层知识……坦白说,为什么你还需要了解 Docker 网络呢?通过主机网络,一切工作正常,这对吗?错了!


使用主机网络意味着你必须为使用的各种微服务保留特定端口。如果你碰巧打开两个有端口冲突的栈,那你就倒霉了。如果你想打开同一个栈的两个版本,那也会倒霉。当某个服务有多个副本时,你想测试它的行为吗?这会非常艰难……


在默认情况下,docker-compose 在一个名为<project-name>_default 的独立网络上启动其容器(其中<project-name>为默认的目录名)。所以,你无需做任何特殊的事情就可以利用 Docker 网络。


这个网络立马能给你带来很多好处:


  • 它是一个比主机网络更加独立的网络——因此,系统环境的小问题就不太会导致 compose 设置的行为差异。你可以访问互联网,但是你希望从主机访问的任何端口都要使用端口绑定来声明。

  • 如果一个服务开始监听 0.0.0.0(容器应该这样),那么主机网络设置将在 WLAN 上打开那个端口。如果你使用 Docker 网络,它只会将该端口暴露给该网络。

  • 你可以通过使用服务的 compose name 作为主机名来实现服务之间的通信。因此,如果你有一个名为 db 的服务,在其内部有一个侦听端口 5432 的服务,那么你可以从任何其他服务通过 db:5432 访问它。这通常比 localhost:5432 更直观。而且,由于不存在本地主机端口冲突的风险,因此,在跨不同项目使用时,它可能会更加一致。

  • 大多数端口不需要向主机开放——这意味着,如果你需要通过--scale增加副本的话,它们不会竞争全局资源。

问题 2:强端口绑定到主机 0.0.0.0 上


这种做法随处可见,你肯定也见过很多,每个人都见过很多:将端口绑定为 8080:8080。乍一看,这似乎没什么问题。但魔鬼在细节中。这种极其常见的端口绑定不仅仅是将一个容器端口转发到本地主机——它还将其转发到系统上的每个网络接口上,包括用于连接互联网的任何接口。


换言之,你的开发容器很可能一直在监听你的无线局域网——当你在家、在办公室或在麦当劳时。它总是可以访问。这可能很危险。不要这样做。


“但是 Vlad,我用了 ufw,我的端口默认是不能访问的”。


这也许没错——但如果你在团队中使用这样的 docker-compose 设置,你的队友可能没有在他们的笔记本电脑上安装防火墙。


修复方法非常简单:只需在前面添加 127.0.0.1:,例如 127.0.0.1:8080:8080。这是告诉 docker 只向回环网络接口公开端口,不包括其他网络接口。

问题 3:使用 sleep 来协调服务启动


我要坦白一件事。关于这一点,我是百分百有错的。


这个问题之所以如此复杂,主要原因是 Docker 或 Docker Compose 没有提供支持解决这个问题。Docker-compose 文件格式的 2.1 版本中有一个名为 condition depends_on 选项,可以设置为 service_healthy。而且,每个服务都可以有一个 healthcheck 命令,可以告诉 docker-compose“健康”是什么意思。这在3.0版本中不再可用,也没有提供替换项


Docker 文档的基本建议是,服务要在其他服务暂时离线的情况下具有弹性,因为这在生产环境中可能会发生,例如出现短暂的网络不稳定,或者一个服务重新启动。这是无可争辩的。


当你运行一个集成测试,而用于初始化测试环境的例程(例如预先用一些测试数据填充数据库)在其他服务准备就绪之前无法恢复启动,就会变得有点麻烦。因此,关于“至少它在生产环境中会有弹性”的论点在这里并不适用,因为用测试数据填充数据库的代码从未在生产环境中使用。


对于这种情况,你需要等待服务就绪。Docker 建议使用wait-for-itDockerizewait-for。但是,请注意,端口就绪并不总是表示服务已经准备好可供使用。例如,在使用具有特定模式的特定 SQL DB 的集成测试中,当数据库初始化时,端口变为可用,但是,测试可能只有在特定模式迁移完成之后才能开始。你可能需要在前面进行特定于应用程序的检查。

问题 4:在 docker-compose 中运行数据库,但在主机上测试


有这样一种情况:你想运行一些单元测试,但这些测试依赖于一些外部服务。可能是数据库,可能是 Redis,也可能是另外一个 API。简单:让我们把这些依赖放在 docker-compose 中,并让单元测试连接到它们。


这很好——但请注意,你的测试不再仅仅是单元测试,它们现在是集成测试了。除术语之外,现在还需要考虑一个重要的区别:你需要考虑测试环境的设置和清理。通常,最好在测试代码之外执行设置/清理操作——主要原因是可能有多个不同的包依赖于这些外部服务。但你的情况可能不太一样。


如果你最终将测试设置和清理分开,那么你需要多做一些工作,将集成测试容器化。


容器化测试意味着:


  • 你在同一个 Docker 网络上,所以连接设置与你在 compose 中运行服务时相同。配置变得更简洁。

  • 在设置和清理过程中,你可以重用用于等待其他服务就绪的代码。

  • 集成测试不依赖于任何其他的本地系统配置或环境设置,例如你的 JFrog 凭证或任何构建依赖项。容器是隔离的。

  • 如果另一个团队需要针对测试所依赖的服务的更新版本运行你的测试,那么你只需要共享集成测试镜像——不需要他们编译或设置一个构建工具链。

  • 如果你最终使用了多个单独的集成测试容器,那么你通常可以并行地运行所有这些容器。


使用容器化集成测试的一个技巧是,为它们使用一个独立的 docker-compose 定义。例如,如果你的大部分服务都存在于 docker-compose.yml 中,那么可以添加一个包含集成测试定义的 docker- composition .test.yml 文件。这意味着 docker-compose up 会提供你常用的服务,而 docker-compose -f docker-compose.yml -f docker-compose.test.yml up 会启动集成测试。要了解完整的实现示例,请参阅 Ardan Labs 提供的这个优秀的docker-compose集成测试库


说这是错误有点不公平。在许多情况下,不容器化是更可取的。举个简单的例子,许多语言都与 IDE 深度集成,这使得在语言和 IDE 之间插入容器几乎不可能。有很多正当的理由不这样做。

小结


对本地开发来说,Docker Compose 是一个非常棒的工具。尽管它有一些缺陷,但通常,它会给许多工程团队带来很多生产力方面的好处,尤其是在与集成测试一起使用时。


原文链接:


https://blog.earthly.dev/youre-using-docker-compose-wrong/

2021-02-20 15:453121
用户头像

发布了 594 篇内容, 共 293.2 次阅读, 收获喜欢 1380 次。

关注

评论

发布
暂无评论
发现更多内容

直播预告 | 对谈谷歌云 DORA 布道师:聊聊最关键的四个 DevOps 表现指标

思码逸研发效能

DevOps

Java高手速成 | 对象-关系的映射、映射对象标识符与JPA API的级联操作

TiAmo

Java jpa API 编排

【从零开始学爬虫】采集全球海关进出口新闻数据

前嗅大数据

大数据 爬虫 海关

无锡正规等级测评公司有几家?分别叫什么?

行云管家

等保 堡垒机 网路安全 等级保护 无锡

DAPP马蹄链合约模式系统开发(搭建)

l8l259l3365

GaussDB(DWS)迁移:一种执行高效的TereData的marco迁移方案

华为云开发者联盟

数据库 后端 华为云 企业号 2 月 PK 榜 华为云开发者联盟

聚焦能碳数智化 百度智能云度能亮相2022世界物联网大会

Geek_2d6073

实现订单到期未支付自动关闭不会写?这6种方案任你挑选

程序员拾山

Java 技术方案 关闭订单

ToB软件遇上ChatGPT,没有天翻地覆

ToB行业头条

盘点导致sql执行速度慢的几种情况,都是生产环境踩过的坑

程序员拾山

MySQL

提高IT运维效率,深度解读京东云AIOps落地实践(异常检测篇(二))

京东科技开发者

人工智能 运维 AIOPS 时间序列 企业号 2 月 PK 榜

NFT艺术品代币如何进行赋能?系统开发定制

开发微hkkf5566

前端工程师leetcode算法面试必备-二分搜索算法(中)

js2030code

JavaScript LeetCode

前端工程师leetcode算法面试必备-二分搜索算法(下)

js2030code

JavaScript LeetCode

业务流程将因生成式AI变革,ChatGPT引领的AIGC正在改变组织运营

王吉伟频道

人工智能 业务流程优化 AIGC ChatGPT 生成式AI

led显示屏升级这些技术才能更节能

Dylan

广告 LED LED显示屏

​网易游戏实时 HTAP 计费风控平台建设

PingCAP

TiDB

Apifox 自动化测试新增流程控制条件,复杂测试场景不再是问题!

Apifox

测试 测试工具 程序员‘ 测试管理工具

好用的研发管理看板工具有哪些?10款主流看板管理软件盘点

PingCode

项目管理 产品经理 管理软件

全栈角度看分页处理

京东科技开发者

数据库 前端 Web 开发 框架

你知道2023年堡垒机报价是多少吗?谁能回答!

行云管家

网络安全 等保 堡垒机 等级保护

Docker Compose的4种错误使用方式_容器_VLAD A. IONESCU_InfoQ精选文章