繁体   English   中英

无法在带有 Ubuntu 的 docker 容器内安装 pip 包

[英]Can't install pip packages inside a docker container with Ubuntu

我正在按照图指南使用 docker 和 python 应用程序,但是当 docker 开始执行命令时

RUN pip install -r requirements.txt

我收到以下错误消息:

Step 3 : RUN pip install -r requirements.txt
 ---> Running in fe0b84217ad1
Collecting blinker==1.3 (from -r requirements.txt (line 1))
  Retrying (Retry(total=4, connect=None, read=None, redirect=None)) after connection broken by 'ProtocolError('Connection aborted.', gaierror(-2, 'Name or service not known'))': /simple/blinker/

这重复了几次,然后我收到另一条消息:

Could not find any downloads that satisfy the requirement blinker==1.3 (from -r requirements.txt (line 1))
  No distributions at all found for blinker==1.3 (from -r requirements.txt (line 1))

因此,由于某种原因,pip 无法从 docker 容器内访问任何包。 我需要做些什么来允许它访问互联网吗?

然而 pip 可以很好地在 docker 容器之外安装东西,即使使用精确的 package (不是问题blinker==1.3 )也可以正常工作。 此外,此问题并非特定于 package。 对于任何 package 的任何pip install命令,我都会遇到相同的问题。

有谁知道这里发生了什么?

你的问题来自于Docker没有使用正确的DNS服务器。 您可以通过三种不同的方式修复它:

1.将Google DNS添加到本地配置

修改/etc/resolv.conf并在末尾添加以下行

# Google IPv4 nameservers nameserver 8.8.8.8 nameserver 8.8.4.4

如果要添加其他DNS服务器,请查看此处

但是,此更改不会是永久性的(请参阅此主题 )。 要使其永久化: $ sudo nano /etc/dhcp/dhclient.conf使用prepend domain-name-server取消注释和编辑该行: prepend domain-name-servers 8.8.8.8, 8.8.4.4;

重启dhclient: $ sudo dhclient

2.修改Docker配置

正如文档中解释的那样

在桌面上运行Ubuntu或Ubuntu衍生产品的系统通常使用127.0.0.1作为/etc/resolv.conf文件中的默认名称服务器。

要指定供Docker使用的DNS服务器:

1. Log into Ubuntu as a user with sudo privileges.

2. Open the /etc/default/docker file for editing :

    $ sudo nano /etc/default/docker

3. Add the following setting for Docker.

    DOCKER_OPTS="--dns 8.8.8.8"

4. Save and close the file.

5. Restart the Docker daemon :

    $ sudo systemctl restart docker

3.运行Docker时使用参数

运行--dns 8.8.8.8 ,只需添加以下参数: - --dns 8.8.8.8

好的,重新启动我的docker-machine正在解决问题。 谢谢 - ismailsunni

这是我的解决方案:

docker-machine restart <machine-name>

我有同样的问题,它困扰了我一段时间,我在网上尝试了很多解决方案但无济于事。 但是我最终解决了它如下:

运行:

Ubuntu 16.04 
docker Server 18.03.0-ce
  1. 发现DNS服务器的地址。

    运行以下命令,发现DNS服务器的地址:

     $: nmcli dev show | grep 'IP4.DNS' IP4.DNS[1]: 192.168.210.2 
  2. 更新Docker守护程序

    /etc/docker/daemon.json.创建一个/etc/docker/daemon.json.配置文件/etc/docker/daemon.json. 如果您还没有 )并将以下内容添加到文件中:

     { "dns": ["192.168.210.2", "8.8.8.8"] } 

    如果您的网络的DNS不可用,则阵列的第一项是您的网络的DNS服务器,第二项是谷歌的DNS服务器作为后备。

    保存该文件,然后重新启动docker服务

     $: sudo service docker restart 

对我来说,只需重启docker守护进程帮助。

service docker restart

我需要在我的docker build命令中添加--network = host:

docker build --network=host -t image_name .

对于Ubuntu用户

您需要在docker配置中添加新的DNS地址

sudo nano /lib/systemd/system/docker.service

在ExecStar之后添加dns。

--dns 10.252.252.252 --dns 10.253.253.253

看起来应该是这样的:

ExecStart=/usr/bin/dockerd -H fd:// --dns 10.252.252.252 --dns 10.253.253.253

然后做:

systemctl daemon-reload
sudo service docker restart

应该管用。

对我来说,这是因为我在 VPN 上,而 docker 找不到我的私人 PYPI 的路线。 如果您需要留在 VPN 上,请使用docker build --network=host

在我的情况下,在Ubuntu 16.04下使用docker version 1.13.0docker version 1.13.0 docker-machine 0.9.0 ,我不得不稍微修改Tanzaho的答案(2.修改Docker配置),如下所示:

  1. 以具有sudo权限的用户身份登录Ubuntu。

  2. 打开/ etc / default / docker文件进行编辑:

     sudo vim /etc/default/docker 
  3. 为Docker添加以下设置。

     DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4" 
  4. 保存并关闭文件。

  5. 重启Docker守护进程:

     sudo service docker restart 

对我来说,由于Docker的DNS配置不正确,我无法安装pip。 我已经尝试了上述步骤,但是,将docker DNS配置为Google DNS对我的笔记本电脑不起作用。 仅当我将其DNS设置为笔记本电脑的已分配IP时,才能正确配置Docker的DNS。

如果您使用Ubuntu,则可以使用以下步骤配置docker的DNS:

  1. 找出您设备的分配IP。 你可以找到这个

    • ifconfig检查以太网或wlan的inet addr
    • nmcli dev show | grep 'DNS'选择任何地址nmcli dev show | grep 'DNS' nmcli dev show | grep 'DNS'
  2. /etc/docker/daemon.json编辑dns(如果以前不存在,则创建此文件)

     { "dns": ["your_ip_in_step_1"] } 
  3. 重启docker: sudo service docker restart

作为一个Docker新手,当我在关注Docker的教程时,我遇到了一个以这种方式表现出来的问题:

https://docs.docker.com/get-started/part2

我在企业局域网上使用Docker 17.03.1-ce。

我检查并仔细检查了我的DNS设置。 我使用了各种方法配置我在互联网搜索中找到的DNS。 有些在启动时导致错误。 我最终决定配置DNS的方法是上面链接的故障排除Linux部分中的方法,其中DNS是通过/ etc / docker目录中的daemon.json文件配置的。

但是,我仍然有同样的问题。 最终解决了我的问题是通过http_proxy和https_proxy环境变量配置代理 我在Dockerfile中指定了它们,但在RUN pip命令之前我忽略了这一点。

尽管它似乎是一个DNS问题,但在RUN命令之前移动这些ENV命令对我来说是不同的。 如果这对有这个问题的人有帮助。

我不知道原因,但错误意味着pip正在尝试解析/simple/blinker/作为DNS主机名而不是pypi.python.org部分,这似乎很奇怪,因为我甚至无法提出任何URL urlparse可以将这样的字符串作为主机名部分返回。 我要检查~/.pip/pip.conf是否有问题

如果有人正在使用docker-compose阅读此内容。 我设法通过更改我的yaml文件解决此问题,如下所示

version: 3.4
service: my-app
  build:
  context: .
  network: host

这相当于写作

docker build . --network host

让它运行。 有时pypi会出现连接问题,这些问题会让你觉得它已经破了。 只是为了确定,让它滚动,你可能会发现它可以自行解决。

尽管存在这些红色错误行,但底线是“成功构建”

$ docker build .
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM docker-registry.aws.example.com:5000/cmcrc/python2:20160517120608
 ---> 1e5034711aa9
Step 2 : RUN pip install prometheus-client requests
 ---> Running in f3c580fc93ae
Collecting prometheus-client
  Retrying (Retry(total=4, connect=None, read=None, redirect=None)) after connection broken by 'NewConnectionError('<pip._vendor.requests.packages.urllib3.connection.HTTPConnection object at 0x7fe15a1d8610>: Failed to establish a new connection: [Errno -2] Name or service not known',)': /pypi/prometheus-client/
  Retrying (Retry(total=3, connect=None, read=None, redirect=None)) after connection broken by 'NewConnectionError('<pip._vendor.requests.packages.urllib3.connection.HTTPConnection object at 0x7fe15a1d87d0>: Failed to establish a new connection: [Errno -2] Name or service not known',)': /pypi/prometheus-client/
  Retrying (Retry(total=2, connect=None, read=None, redirect=None)) after connection broken by 'NewConnectionError('<pip._vendor.requests.packages.urllib3.connection.HTTPConnection object at 0x7fe15a1d8990>: Failed to establish a new connection: [Errno -2] Name or service not known',)': /pypi/prometheus-client/
  Retrying (Retry(total=1, connect=None, read=None, redirect=None)) after connection broken by 'NewConnectionError('<pip._vendor.requests.packages.urllib3.connection.HTTPConnection object at 0x7fe15a1d8b50>: Failed to establish a new connection: [Errno -2] Name or service not known',)': /pypi/prometheus-client/
  Retrying (Retry(total=0, connect=None, read=None, redirect=None)) after connection broken by 'NewConnectionError('<pip._vendor.requests.packages.urllib3.connection.HTTPConnection object at 0x7fe15a1d8d10>: Failed to establish a new connection: [Errno -2] Name or service not known',)': /pypi/prometheus-client/
  Downloading prometheus_client-0.0.13.tar.gz
Collecting requests
  Retrying (Retry(total=4, connect=None, read=None, redirect=None)) after connection broken by 'NewConnectionError('<pip._vendor.requests.packages.urllib3.connection.HTTPConnection object at 0x7fe159e9d4d0>: Failed to establish a new connection: [Errno -2] Name or service not known',)': /pypi/requests/
  Retrying (Retry(total=3, connect=None, read=None, redirect=None)) after connection broken by 'NewConnectionError('<pip._vendor.requests.packages.urllib3.connection.HTTPConnection object at 0x7fe159e9da10>: Failed to establish a new connection: [Errno -2] Name or service not known',)': /pypi/requests/
  Retrying (Retry(total=2, connect=None, read=None, redirect=None)) after connection broken by 'NewConnectionError('<pip._vendor.requests.packages.urllib3.connection.HTTPConnection object at 0x7fe159e9dc50>: Failed to establish a new connection: [Errno -2] Name or service not known',)': /pypi/requests/
  Retrying (Retry(total=1, connect=None, read=None, redirect=None)) after connection broken by 'NewConnectionError('<pip._vendor.requests.packages.urllib3.connection.HTTPConnection object at 0x7fe159e9de10>: Failed to establish a new connection: [Errno -2] Name or service not known',)': /pypi/requests/
  Retrying (Retry(total=0, connect=None, read=None, redirect=None)) after connection broken by 'NewConnectionError('<pip._vendor.requests.packages.urllib3.connection.HTTPConnection object at 0x7fe159e9dfd0>: Failed to establish a new connection: [Errno -2] Name or service not known',)': /pypi/requests/
  Downloading requests-2.10.0-py2.py3-none-any.whl (506kB)
Building wheels for collected packages: prometheus-client
  Running setup.py bdist_wheel for prometheus-client: started
  Running setup.py bdist_wheel for prometheus-client: finished with status 'done'
  Stored in directory: /root/.cache/pip/wheels/04/94/f5/b803b2ff65e8344e99ca99b7f7cb8194224017167809a32b78
Successfully built prometheus-client
Installing collected packages: prometheus-client, requests
Successfully installed prometheus-client-0.0.13 requests-2.10.0
 ---> 19c5e3cfe08f
Removing intermediate container f3c580fc93ae
Successfully built 19c5e3cfe08f

我有同样的问题。错误的原因是代理。

所以,我编辑Dockerfile如下

RUN pip install -r /app/requirements.txt --proxy=http://user:pass@addr:port

将docker DNS配置为Google DNS(8.8.8.8)或10.0.0.2在我的公司环境中无效。

运行:$ drill @ 8.8.8.8 www.amazon.com或@ 10.0.0.2确认了这一点。

为了找到一个可行的DNS我运行:$ drill www.amazon.com它给了我在我的网络中使用的DNS IP。

然后我使用以下步骤在Ubuntu中设置它以配置docker的DNS。

在/etc/docker/daemon.json中更改了dns

{
    "dns": ["the DNS ip from step1"]
}

Restart docker: sudo service docker restart

我是Docker的新手并尝试了这里提到的所有方法,但仍然没有做到正确。 Docker版本是18,ubuntu版本是16.我尝试了这种方法: - 首先我用公司的互联网建立docker。 这个网络阻止了一些网站或者某些东西在这里没有进展顺利。 所以其次我连接到我自己的网络(例如我在手机中使用)并尝试过。 事情进展顺利。 requirements.txt已成功安装,并且已构建docker。

对我来说,这是因为我的大学VPN连接。 断开“解决”问题。

我猜您尝试在不允许从公共存储库直接访问/安装的私有环境中运行 pip 安装。 如果是这种情况,您可以将 --index-url 和 --trusted-host 添加到 requirements.txt 中,如下所示:

要求.txt:

--index-url https://pypi.internal.org/api/pypi/org.python.pypi/simple
--trusted-host pypi.internal.org pypi.python.org pypi.org files.pythonhosted.org
blinker==1.3

TL;博士

更新 docker 守护程序的默认 MTU。

  1. 通过ip link获取物理接口的 MTU。
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 72:bd:50:24:5e:a9 brd ff:ff:ff:ff:ff:ff
  1. 创建/etc/docker/daemon.json ,输入物理接口的MTU值:
{
   "mtu": 1480
}
  1. 重启 docker 服务:
sudo service docker restart

解释

我在 Linux VM 上运行 docker 时遇到了同样的问题。 设置-network=host解决了问题,但不是一个令人满意的解决方案,因为我不知道它为什么起作用。

经过几个小时的搜索,我发现问题是由于容器中物理接口的MTU和虚拟接口的MTU不匹配造成的。 虚拟接口的 MTU 必须小于或等于物理接口的 MTU 大小,否则容器将无法接收大于物理 MTU 大小的数据包。

就我而言,物理接口 (VM) 的 MTU 配置为1480 Docker 的默认 MTU 是1500

关于pip ,问题表现为似乎停滞的 SSL 握手(无法读取服务器 hello),从而导致重复的ReadTimeout错误。

这里描述了问题,尽管我使用了这里描述的解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM