背景
新建了一个python3环境镜像,在打镜像时将网络代理url以环境变量的形式存入镜像的环境中;代理url:http_proxy=‘http://10.223.94.15:8089’
新建的镜像起容器后,需要在容器中用python3以get方式访问一个http服务;服务地址:‘http://10.238.3.142:5006/trans_cls’
已知:
容器所在物理机与服务提供服务器端口畅通
网络代理的服务器10.223.94.15与服务提供服务器10.238.3.142端口不通
现象
在容器中使用requests的get方法访问http服务后,较长时间后得到response[503];反馈结果表明,容器请求服务没有得到响应
分析
从debug内容中查看到,由于容器环境变量中配置了代理信息,连接信息connection的代理池会默认获取到代理url从而通过代理去访问目的服务;由于代理服务器与服务提供服务不通,所以response为503也是合情合理
下面源码则记录了使用代理url构建服务请求ProxyManager对象的过程
class ProxyManager(PoolManager):
"""
Behaves just like :class:`PoolManager`, but sends all requests through
the defined proxy, using the CONNECT method for HTTPS URLs.
:param proxy_url:
The URL of the proxy to be used.
:param proxy_headers:
A dictionary containing headers that will be sent to the proxy. In case
of HTTP they are being sent with each request, while in the
HTTPS/CONNECT case they are sent only once. Could be used for proxy
authentication.
Example:
>>> proxy = urllib3.ProxyManager('http://localhost:3128/')
>>> r1 = proxy.request('GET', 'http://google.com/')
>>> r2 = proxy.request('GET', 'http://httpbin.org/')
>>> len(proxy.pools)
1
>>> r3 = proxy.request('GET', 'https://httpbin.org/')
>>> r4 = proxy.request('GET', 'https://twitter.com/')
>>> len(proxy.pools)
3
"""
def __init__(
self,
proxy_url,
num_pools=10,
headers=None,
proxy_headers=None,
**connection_pool_kw
):
if isinstance(proxy_url, HTTPConnectionPool):
proxy_url = "%s://%s:%i" % (
proxy_url.scheme,
proxy_url.host,
proxy_url.port,
)
proxy = parse_url(proxy_url)
if not proxy.port:
port = port_by_scheme.get(proxy.scheme, 80)
proxy = proxy._replace(port=port)
if proxy.scheme not in ("http", "https"):
raise ProxySchemeUnknown(proxy.scheme)
self.proxy = proxy
self.proxy_headers = proxy_headers or {}
总结
打镜像时应考虑代理与访问服务之间的关系,防止出现意外的使用代理访问服务的情况。