Patch docker-compose 防止启动时卡住
source link: https://phuker.github.io/patch-for-docker-compose-hanging.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
本文主要解决 docker-compose
命令启动时,随机卡住几秒至几分钟才有反应的问题。本文主要复制/翻译洒家在这个 issue 中的评论。
TL;DR¶
如果你只在 Linux 本机使用 docker-compose,不使用 docker-compose 的远程功能(例如 -H
参数,DOCKER_HOST
环境变量),按下面方式 patch 1 行代码即可解决问题。
首先定位 docker-compose
使用的 docker
库文件位置。根据 Python 的版本,一般位于 /usr/local/lib/
[YOUR_PYTHON_VERSION]
/dist-packages/docker/transport/__init__.py
。如果找不到,可以按下文提到的方法定位此文件。
编辑此文件,将 from .sshconn import SSHHTTPAdapter
替换为 SSHHTTPAdapter = None
即可。
try:
# add this line
SSHHTTPAdapter = None
# # comment this line
# from .sshconn import SSHHTTPAdapter
except ImportError:
pass
运行 docker-compose version
测试,你会发现再也不会卡了,而且在低配机器上启动速度还快了不少。
附:顺腾摸瓜定位文件¶
以洒家的某台虚拟机为例,运行命令:
# docker-compose version
docker-compose version 1.25.4, build unknown
docker-py version: 3.7.3
CPython version: 2.7.17
OpenSSL version: OpenSSL 1.1.1 11 Sep 2018
docker-compose
是在 Python 2.7.17 上安装的。用相同版本的 Python 运行 pip:
# python2 -m pip show docker
Name: docker
Version: 3.7.3
Location: /usr/local/lib/python2.7/dist-packages
根据上述命令输出的 Location
,找到目标文件 /usr/local/lib/python2.7/dist-packages/docker/transport/__init__.py
。
附:暴力定位文件¶
搜索整个根目录:
# find / -type f -name __init__.py 2>/dev/null | grep docker/transport/__init__.py
/usr/local/lib/python2.7/dist-packages/docker/transport/__init__.py
解释¶
即使只是运行一条简单的 docker-compose version
命令,docker-compose
也会加载所有可能用到的库。docker-compose
依赖 docker
库,为了实现远程 SSH 功能,docker
库依赖 paramiko
库,paramiko
又依赖 pynacl
库。pynacl
是对 libsodium
的封装。在 libsodium
初始化的时候,系统随机数熵(entropy)需要高于 160,否则会一直等待。
查看当前系统随机数熵值:
# cat /proc/sys/kernel/random/entropy_avail
105
使用性能分析工具可以看到各种库的加载过程,以及卡住的位置:
# python2 -m cProfile `which docker-compose` --version
docker-compose version 1.24.1, build 4667896
130382 function calls (126780 primitive calls) in 112.339 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 <string>:1(<module>)
1 0.000 0.000 0.000 0.000 <string>:1(ArgInfo)
......
2 0.001 0.000 112.085 56.043 __init__.py:15(<module>)
1 0.001 0.001 112.142 112.142 __init__.py:20(<module>)
1 0.005 0.005 112.152 112.152 auth.py:1(<module>)
2 0.001 0.000 112.153 56.077 build.py:1(<module>)
2 0.003 0.001 112.211 56.106 client.py:1(<module>)
1 0.000 0.000 112.144 112.144 decorators.py:1(<module>)
1 0.001 0.001 112.343 112.343 docker-compose:3(<module>)
1 0.000 0.000 112.087 112.087 ed25519key.py:17(<module>)
1 0.003 0.003 112.333 112.333 main.py:1(<module>)
1 0.000 0.000 112.086 112.086 signing.py:15(<module>)
1 0.000 0.000 112.084 112.084 sodium_core.py:21(_sodium_init)
1 0.000 0.000 112.084 112.084 sodium_core.py:27(sodium_init)
1 0.000 0.000 112.142 112.142 sshconn.py:1(<module>)
1 0.000 0.000 112.143 112.143 tls.py:1(<module>)
1 0.004 0.004 112.139 112.139 transport.py:22(<module>)
4 0.000 0.000 112.144 28.036 utils.py:1(<module>)
1 112.084 112.084 112.084 112.084 {built-in method sodium_init}
1 0.000 0.000 112.084 112.084 {method 'init_once' of 'CompiledFFI' objects}
......
因此,直接 patch 代码,防止这一堆和 SSH、密码学有关的不必要的库加载和初始化即可解决问题。洒家测试过的 docker
库版本有:3.7.3
和 4.2.0
。
另一种方案:安装 haveged
¶
Haveged 可以解决在某些情况下,系统熵过低的问题。在 Debian、Ubuntu 等系统直接安装即可:
apt-get update && apt-get install -y haveged
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK