土豆不好吃

没事别在容器里装openssh-server,真的

文章目录[显示]

几天前,跑的好好的CI突然fail,报错信息看起来很奇怪,像是使用上的问题。

本地跑了一下这两个测试用例,并没有复现。以为是CI偶尔抽风了,就没管。

后来发现有点不对,怎么都跑不过。甚至直接在develop上跑CI都跑不过。这和GraphQL有什么关系啊?明明都能用的啊。让写这部分代码的同事帮忙看了下,发现他也能跑过。奇怪。

由于整套CI是跑在concourse上的,于是通过fly hijack进去,在对应失败的step中成功复现了这个问题。

再后来同事发现出问题的是urllib3/util/retry.py的Retry

max_retries = Retry(
    total=1,
    backoff_factor=0.1,
    status_forcelist=[500, 502, 503, 504],
    allowed_methods=None,
)

去比对了下,fly进去的容器中的urllib3版本和我测试的版本确实不一样。把fly进去的容器中的urllib3升级了之后,test case就可以过了。

啥?这啥情况?先在requirements.txt中写上urllib3==1.26.7临时解决一下这个问题。至少别耽误大家跑CI啊。

差异

fly进去的容器是用名为builder/Dockerfile构建的,我测试的是websvc是websvc/Dockerfile构建的,两者基本没什么差别。

我自己跑测试用例是用的websvc,而跑CI用的是builder。

可是问题来了,二者明明用了一样的requirements.txt,怎么会安装出来不一样的library?pip install -r requirements.txt 之后也没有安装别的,怎么就版本不一致了?

后来经过一步一步测试,最终发现了这背后的原因。

根本原因

builder/Dockerfile中,我们安装了openssh-server,先别管为啥……

openssh-server有非常多的依赖,如下图中选中的地方,就有python3-urllib3

apt中的python package的版本是相对而言比较老的,经过查看这种方式安装的urllib3的版本是1.22

requirements.txt 中,我们安装的是requests==2.25.1gql==3.0.0b0。这两个package对urllib3的版本要求比较宽泛,通过apt 安装的这个版本恰巧能够满足。

websvc这个image由于没有通过apt安装openssh-server,所以也没有python3-urllib3。在 pip install -r requirements.txt时,requests 2.25.1的要求是urllib3>=1.21.1,<1.27,也就安装了1.26.7(可用的版本)

综上所述,在构建之后,builder这个image中 urllib3的版本就是1.22;而websvc是1.26.7。这也就是为什么本机永远无法复现而只有在fly hijack之后才可以复现的原因

所以root cause是,在 builder中安装了openssh-server(容器里安装openssh-server干嘛🤣)

直接原因

direct cause是 gql==3.0.0b0 install_requires 没有要求urllib3的版本,也可能是graphql-core,或者说requiremens.txt应该写gql[all]==3.0.0.b0,但是很少有人这么写啊,真的是醉了。

间接原因

那为啥之前都一直没问题怎么突然就挂了?

一番实验之后也发现了原因。之前Base image升级到了Ubuntu 18.04,16.04的时候Ubuntu自带的python版本是3.5,所以哪怕安装了openssh-server,那也是py3.5的,而我们用的是从ppa安装的3.6所以无关联。

升级之后,18.04自带的Python是3.6,即使通过ppa安装其实也是“共享”的,因此…

修复方法

修复的办法包括

  1. patch掉graphql的调用
  2. requirements.txt中强制安装新版本urllib3
  3. builder/Dockerfileopenssh-server改成wget(安装openssh-server时会附带wget,后续我们需要wget

总结

  1. 升级升级到Ubuntu 18.04是我搞的,我背锅。境外势力已经够忙了,请不要诬陷境外势力。
  2. Dockerfile可以再更新一下了,把PPA去掉,一些重复的安装(指apt和pip)可以只保留pip了。openssh-server 也可以去掉,历史遗留问题。
  3. 为啥不用multi-stage build?估计也是历史遗留原因。
  4. 没事别在容器里安装openssh-server,真的。除非你知道你在干嘛。或者装降低熊。


文章版权归原作者所有丨本站默认采用CC-BY-NC-SA 4.0协议进行授权|
转载必须包含本声明,并以超链接形式注明原作者和本文原始地址:
https://dmesg.app/no-openssh-server-container.html
退出移动版