DeBug——Docker应用随机且高频报错500(Internal server error)——关于DockerCompose同网段服务冲突问题

前言

由于目前服务器上的大部分docker应用都是通过端口映射暴露服务,虽然有通过nginx进行反向代理从而无法通过ip加端口直接访问,但理论上更具安全性的最佳实践做法是取消容器端口映射转而通过加入同一个docker网络利用compose定义的容器/服务名来完全替代ip,于是我计划把服务器上部署的所有docker应用都进行上述优化,当然在代码世界的神奇悖论中旧问题的解决总是伴随着新Bug的产生`(>﹏<)′,诸君请看(👉゚ヮ゚)👉

Bug概述及思路分析

一个成熟的bug一定不会让应用无法运行,而是会让程序介于完美与瑕疵之间,在薛定谔态见证调试者的不知所措,实在与今天的bug太过贴切,见图↓

msedge_6kD2vBXsaQ

可以看到每次请求触发bug是呈现随机性的,当然在最初生产环境下图片中下半部分400错误以及调用栈都是默认隐藏的,按照惯常的思路我首先利用docker logs xxx简单查看了一下容器日志并且调整容器级别至开发环境,下图是app服务日志,至于db服务则未提示任何错误

image-20250306150157393

可以看到日志中只提示了异常调用栈且与网页显示一致,并没有提供额外信息,那么只能从仅剩的报错信息入手

image-20250306151802625

SQL报错1045可以基本定位到是用户名或密码不正确亦或没有数据库访问权限,那么接下来正式进入矛盾核心,首先从随机的正常访问而非彻底无法访问可以明确数据库运行正常、用户名及密码正确且无权限问题的,那么似乎理应没有报错1045的可能,于是不出意外在这里我也陷入卡顿,查找了国内外的很多社区也没有同类问题报告,在尝试了一些诸如清理容器缓存的万金油操作后着实是有点捉襟见肘了,刚好赶上饭点,决定先放轻松等待灵感到来,或是冥冥天意,正上楼时突然想到或许app服务意外连接的不是自家的数据库而另一数据库并不存在该用户名于是给出了Access Deny,就像用正确的钥匙尝试打开错误的门,那么当然会被拒之门外。至于其随机性,应该是由于DNS在解析两个数据库时竞争冲突导致的,至此问题现象有了一个合理的解释,藉此顺藤摸瓜便可拨云见日。

Bug实质及解决方案

有了方向下一步就是找到问题的根源,docker中DNS解析结果会随机指向两个数据库之一那么一定是在某处他们的标识:容器名称/服务名称完全一致从而产生了歧义,由于每个容器我都自定义了其container_name因而歧义只会发生在docker-compose.yml定义的的服务名(service name)上,由于我习惯在compose中将主应用命名为app将其数据库命名为db,因此有多个容器的数据库服务名称都是db,其实这个命名逻辑本身并没有问题,因为通常情况下我习惯让容器间通过容器名(container name)相互访问而非服务名(service name),但是问题出在了chevereto的compose配置文件上,见图

image-20250306164827445

事实上,在之前各服务之间网络独立的情况下,DB_HOST项(下方红框)配置为db并无问题,但是将所有应用放入同一网段时由于多个应用的数据库服务名都为db导致了DNS解析轮询歧义,从而导致bug诞生,如此解决方案也是显而易见的,最简单的就是将DB_HOST改为上方绿框中的容器名即chevereto-db进行解析来保证DNS解析独立无歧义。

延伸及启示

关于服务名与容器名

服务名称并非是docker原生的而是在Docker-Compose中引入的,其主要目的是与容器名解耦(容器名全局唯一),实现服务名的复用并且可以参与DNS解析,当然这是因为Docker Compose会默认为每个项目创建独立网络,而上述bug的发生主要是因为将多个项目放在了同一网络中。

关于容器名能否参与DNS解析要分两种情况,如果是在默认的桥接网络中,容器名并不会参与DNS解析,而在自定义docker网络中则可以参与解析

Docker Compose官方更推荐使用服务名称来进行容器间通信,其具有更好的稳定性并且利于标准和自动化

启示

在一般的Docker-compose项目中(指无需在同一网络下)可以沿用之前的命名法(毕竟服务名设计之初就是为了多项目复用的嘛~),但是在特殊的应用场景下,比如本文中所有应用都被部署在了一个网络下,就需要特别注意服务名的唯一性,可以简单的让服务名与容器名保持一致即可,当然也可以干脆通过容器名进行通信,因为其独立性是docker强制保证的,但是正如4.1所说,Docker Compose并不推荐使用容器名互访,因此大家可以自己权衡利弊~

日志

2025-3-6 初稿

版权声明:除特殊说明,博客文章均为SATAKAUI原创,依据CC BY-SA 4.0许可证进行授权,转载请附上出处链接及本声明。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇