我将使用Kubernetes Python客户端进行翻译。如果在我的代码启动时Kubernetes不可用,我希望重试连接。
但尽管如此:
当客户端无法连接时,它会引发似乎是urllib3.exceptions.MaxRetryError
异常,因此我从以下内容开始:
import time
import urllib3
import kubernetes
kubernetes.config.load_kube_config()
api = kubernetes.client.CoreV1Api()
while True:
try:
w = kubernetes.watch.Watch()
for event in w.stream(api.list_pod_for_all_namespaces):
print event
except urllib3.exceptions.HTTPError:
print('retrying in 1 second')
time.sleep(1)
但这完全失败了;它好像没有except
语句一样,然后就会停止运行并出现以下错误信息:
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='192.168.122.140', port=8443): Max retries exceeded with url: /api/v1/pods?watch=True (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x2743110>: Failed to establish a new connection: [Errno 111] Connection refused',))
我觉得也许我对继承的理解不如我想象的那么好,所以我将上述内容替换为:
except urllib3.exceptions.MaxRetryError:
print('retrying in 1 second')
time.sleep(1)
同样的失败。为了弄清楚发生了什么,我添加了一个万能的 except
并调用了 pdb:
except Exception as err:
import pdb; pdb.set_trace()
从 pdb
提示符中,我们可以看到:
(Pdb) type(err)
<class 'urllib3.exceptions.MaxRetryError'>
这看起来很好,MRO也是如此:
(Pdb) import inspect
(Pdb) inspect.getmro(err.__class__)
(<class 'urllib3.exceptions.MaxRetryError'>, <class 'urllib3.exceptions.RequestError'>, <class 'urllib3.exceptions.PoolError'>, <class 'urllib3.exceptions.HTTPError'>, <type 'exceptions.Exception'>, <type 'exceptions.BaseException'>, <type 'object'>)
但尽管如此:
(Pdb) isinstance(err, urllib3.exceptions.MaxRetryError)
False
所有路径看起来都很合理:
(Pdb) urllib3.__file__
'/usr/lib/python2.7/site-packages/urllib3/__init__.pyc'
(Pdb) kubernetes.client.rest.urllib3.__file__
'/usr/lib/python2.7/site-packages/urllib3/__init__.pyc'
那么...这里到底发生了什么?
更新
以下是完整的堆栈跟踪:
Traceback (most recent call last):
File "testkube.py", line 13, in <module>
for event in w.stream(api.list_pod_for_all_namespaces):
File "/usr/lib/python2.7/site-packages/kubernetes/watch/watch.py", line 116, in stream
resp = func(*args, **kwargs)
File "/usr/lib/python2.7/site-packages/kubernetes/client/apis/core_v1_api.py", line 14368, in list_pod_for_all_namespaces
(data) = self.list_pod_for_all_namespaces_with_http_info(**kwargs)
File "/usr/lib/python2.7/site-packages/kubernetes/client/apis/core_v1_api.py", line 14464, in list_pod_for_all_namespaces_with_http_info
collection_formats=collection_formats)
File "/usr/lib/python2.7/site-packages/kubernetes/client/api_client.py", line 335, in call_api
_preload_content, _request_timeout)
File "/usr/lib/python2.7/site-packages/kubernetes/client/api_client.py", line 148, in __call_api
_request_timeout=_request_timeout)
File "/usr/lib/python2.7/site-packages/kubernetes/client/api_client.py", line 371, in request
headers=headers)
File "/usr/lib/python2.7/site-packages/kubernetes/client/rest.py", line 250, in GET
query_params=query_params)
File "/usr/lib/python2.7/site-packages/kubernetes/client/rest.py", line 223, in request
headers=headers)
File "/usr/lib/python2.7/site-packages/urllib3/request.py", line 66, in request
**urlopen_kw)
File "/usr/lib/python2.7/site-packages/urllib3/request.py", line 87, in request_encode_url
return self.urlopen(method, url, **extra_kw)
File "/usr/lib/python2.7/site-packages/urllib3/poolmanager.py", line 321, in urlopen
response = conn.urlopen(method, u.request_uri, **kw)
File "/usr/lib/python2.7/site-packages/urllib3/connectionpool.py", line 668, in urlopen
**response_kw)
File "/usr/lib/python2.7/site-packages/urllib3/connectionpool.py", line 668, in urlopen
**response_kw)
File "/usr/lib/python2.7/site-packages/urllib3/connectionpool.py", line 668, in urlopen
**response_kw)
File "/usr/lib/python2.7/site-packages/urllib3/connectionpool.py", line 639, in urlopen
_stacktrace=sys.exc_info()[2])
File "/usr/lib/python2.7/site-packages/urllib3/util/retry.py", line 388, in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='192.168.122.140', port=8443): Max retries exceeded with url: /api/v1/pods?watch=True (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x3d16110>: Failed to establish a new connection: [Errno 111] Connection refused',))
python -v testkube.py
来打开 import logging,看看是否有任何模块被初始化两次。 - user2357112requests.packages.urllib3
,我认为这是问题的根源,尽管我不清楚这是发生在哪里。 - larsksrequests
初始化requests.packages
的方式不同,而在这些版本中,requests.packages
确实会导致urllib3.exceptions
的重新加载。requests.packages
就是罪魁祸首! - user2357112