【问题标题】:How can I install matplotlib for my AWS Elastic Beanstalk application?如何为我的 AWS Elastic Beanstalk 应用程序安装 matplotlib?
【发布时间】:2015-03-21 21:36:41
【问题描述】:

我在 AWS Elastic Beanstalk 上部署 matplotlib 非常开心。 I gather 我的问题来自某些依赖项以及 EB 部署使用 PIP 安装的软件包的方式,并已尝试按照 instructions here on SO 解决问题。

我首先尝试按照链接答案中的建议逐步部署,方法是将 matplotlib 包堆栈的各个部分分阶段添加到我的 requirements.txt 文件中。但这需要 forever(对于每个阶段)并且容易出现故障和超时(这似乎会使构建目录落后于后续的软件包安装)。

所以答案末尾随便提到的简单解决方案对我很有吸引力:只需eb ssh,使用

激活 virtialenv
source /opt/python/run/venv/bin/activate

pip install 手动打包。但我也不能让它工作。首先,我经常遇到左侧构建目录(如上所述)

pip can't proceed with requirement 'xxxx' due to a pre-existing build directory.
 location: /opt/python/run/venv/build/xxxx
This is likely due to a previous installation that failed.
pip is being responsible and not assuming it can delete this.
Please delete it and try again.

但即使在删除这些之后,我也一直得到 ​​p>

Exception:
Traceback (most recent call last):
  File "/opt/python/run/venv/lib/python2.7/site-packages/pip/basecommand.py", line 122, in main
    status = self.run(options, args)
  File "/opt/python/run/venv/lib/python2.7/site-packages/pip/commands/install.py", line 278, in run
    requirement_set.prepare_files(finder, force_root_egg_info=self.bundle, bundle=self.bundle)
  File "/opt/python/run/venv/lib/python2.7/site-packages/pip/req.py", line 1197, in prepare_files
    do_download,
  File "/opt/python/run/venv/lib/python2.7/site-packages/pip/req.py", line 1375, in unpack_url
    self.session,
  File "/opt/python/run/venv/lib/python2.7/site-packages/pip/download.py", line 582, in unpack_http_url
    unpack_file(temp_location, location, content_type, link)
  File "/opt/python/run/venv/lib/python2.7/site-packages/pip/util.py", line 625, in unpack_file
    untar_file(filename, location)
  File "/opt/python/run/venv/lib/python2.7/site-packages/pip/util.py", line 533, in untar_file
    os.makedirs(location)
  File "/opt/python/run/venv/lib64/python2.7/os.py", line 157, in makedirs
    mkdir(name, mode)
OSError: [Errno 13] Permission denied: '/opt/python/run/venv/build/xxxx'

响应pip install xxxx(并且sudo pip 失败并返回sudo: pip: command not found)。

我可以做些什么来让它在 AWS-EB 上运行?特别是,我需要做什么才能使简单的 SSH+PIP 方法正常工作;还是有其他更好的——更简单的! — 我应该尝试的方法。


FWIW,我有一个 .ebextensions/software.config

packages:
  yum:
    gcc-c++: []
    gcc-gfortran: []
    python-devel: []
    atlas-sse3-devel: []
    lapack-devel: []
    libpng-devel: []
    freetype-devel: []
    zlib-devel: []

还有一个以

结尾的requirements.txt
pytz==2014.10
pyparsing==2.0.3
python-dateutil==2.4.0
nose==1.3.4
six>=1.8.0
mock==1.0.1

numpy==1.9.1

matplotlib==1.4.2

大约 4 小时后,我已经达到了 numpy 的程度(由 EB virtualenv 中的pip list 报告)。

并且(如果重要的话)进行 SSH 的用户属于具有策略的组

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "elasticbeanstalk:*",
        "ec2:*",
        "elasticloadbalancing:*",
        "autoscaling:*",
        "cloudwatch:*",
        "s3:*",
        "sns:*",
        "cloudformation:*",
        "rds:*",
        "sqs:*",
        "iam:PassRole"
      ],
      "Resource": "*"
    }
  ]
}

【问题讨论】:

    标签: numpy amazon-web-services matplotlib pip amazon-elastic-beanstalk


    【解决方案1】:

    我使用了许多方法在 Windows 和 Linux 系统上构建和部署 numpy/scipy/matplotlib。我使用过系统提供的包管理器(aptitude、rpm)、第 3 方包管理器(pypm)、Python 包管理器(easy_install、pip)、源代码版本,使用过不同的构建环境/工具(GCC,还有 Intel MKL、OpenMP )。在此过程中,我遇到了许多非常烦人的情况,但也学到了很多关于每种方法的优缺点。

    我没有使用 Elastic Beanstalk (EB) 的经验,但我有使用 EC2 的经验。我看到您可以通过 SSH 连接到一个实例并四处寻找。因此,我在下面进一步提出的建议是基于

    • 上述经验及其他内容
    • 关于 Beanstalk 等的或多或少明显的边界条件
    • 您的应用场景,在关于 SO 和 on 的另一个问题中进行了描述
    • 您只想让事情快速运行

    我的建议:首先不要自己构建这些东西。不要使用点子。如果可能,请尝试使用 Linux 发行版的包管理器,让它为您处理所需的一切的安装,只需一个命令(例如sudo apt-get install python-matplotlib)。

    缺点:

    • 可能是旧的软件包版本,取决于使用的 Linux 发行版
    • 未优化的构建(例如,未针对例如英特尔 MKL 构建或未利用 OpenMP 功能或未使用特殊指令集)

    优点:

    • 下载速度很快,因为软件包很可能缓存在您的计算机附近
    • 它可以快速安装(这些包是预构建的,不涉及编译)
    • 效果很好

    所以,我希望您可以在这些机器上使用 aptitude 或 rpm 或其他任何东西,并继承分发包维护人员在幕后为您所做的伟大工作。

    一旦您对自己的应用程序充满信心并确定了一些瓶颈或问题,您可能有理由使用 更新 版本的 numpy/matplotlib/... 或者您可能有理由使用 更快的版本,通过创建优化的构建。

    编辑:概述方法的 EB 相关细节

    与此同时,我们了解到 EB 默认运行基于 Red Hat Enterprise Linux 的 Amazon Linux。同样,它使用yum 作为包管理器,并且包是 RPM 格式。

    亚马逊提供有关可用软件包的文档。在 Amazon Linux 2014.09 中,这些包可用:http://aws.amazon.com/de/amazon-linux-ami/2014.09-packages/

    在这个列表中我们发现

    • numpy-1.7.2
    • python-matplotlib-0.99.1.2

    这个版本的 matplotlib 已经很老了,根据 changelog 是从 2009 年 9 月开始的:“2009-09-21 Tagged for release 0.99.1”。

    我没想到它会这么老,但它仍然可能足以满足您的需求。所以我们继续我们的计划(但我会理解这是否是一个阻碍)。

    现在,我们have learned 系统 Python 和 EB Python 是相互隔离的。这并不意味着 EB Python 不能访问系统 Python 站点包。我们只需要它告诉我们。一个简单而干净的方法是使用 EB Python 应该可以访问的包设置适当的目录结构,并通过 sys.path 将该目录传达给 EB Python。

    显然,我们需要自定义 EB 容器的引导阶段。此处记录了可用的工具:http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/customize-containers-ec2.html

    显然,我们希望使用packages 方法,并告诉EB 通过yum 安装numpypython-matplotlib 软件包。所以相应的配置文件部分应该包含:

     packages:  
      yum:  
       numpy: []  
       python-matplotlib: []  
    

    可能没有必要明确提及numpy,它可能是python-matplotlib的依赖项。

    另外,我们需要使用commands 部分:

    您可以使用 commands 键在 EC2 实例上执行命令。 这些命令按名称按字母顺序处理,它们运行 在设置应用程序和 Web 服务器以及应用程序之前 版本文件被提取。

    以下三个命令创建上述目录,并设置指向 numpy/mpl 安装路径的符号链接(希望这些路径在这些命令执行时可用):

    commands:
      00-create-dir:
        command: "mkdir -p /opt/py26-selected-site-packages"
      01-link-numpy:
        command: "ln -s /usr/lib64/python2.6/site-packages/numpy /opt/py26-selected-site-packages/numpy"
      02-link-mpl:
        command: "ln -s /usr/lib64/python2.6/site-packages/matplotlib /opt/py26-selected-site-packages/matplotlib"
    

    两个不确定性:AWS 文档没有说明 packages 是在 commands 执行之前处理的。你得试试。如果它不起作用,请使用container_commands。其次,安装 python-matplotlib 后可以使用/usr/lib64/python2.6/site-packages/matplotlib 只是一个有根据的猜测。它应该安装到这个地方,但它可能最终安装在其他地方。需要进行测试。 Numpy 应该以从this 文章推断的方式结束。

    [从 SEB 更新] AWS 文档说“cfn-init 帮助程序脚本按以下顺序处理这些配置部分:包、组、用户、源、文件、命令,然后是服务。” http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-init.html

    所以,您的方法是安全的 [/更新]

    正如 cmets 对此答案所指出的那样,关键步骤是告诉您的 Python 应用程序在哪里寻找包。 在尝试导入之前直接修改sys.path 是控制这一点的可靠方法。以下代码将我们的特殊目录添加到 Python 查找包的目录选择中,然后尝试导入 matplotlib:

    sys.path.append("/opt/py26-selected-site-packages")
    from matplotlib import pyplot
    

    sys.path 中的顺序定义了优先级,因此如果在其他目录之一中有任何其他 matplotlib 或 numpy 包可用,那么最好

    sys.path.insert(0, "/opt/py26-selected-site-packages")
    

    但是,如果我们的整个方法经过深思熟虑,则没有必要这样做。

    【讨论】:

    • 这在 AWS 上有效吗?大多数情况下(如前所述)我对让简单的 SSH+PIP 方法正常工作很感兴趣(因为它是经过批准的方法;并且可以应用于所有包并总体上加快部署时间)。
    • “它可以在 AWS 上运行吗?”我认为是这样,这取决于实际运行的是哪个 Linux 发行版。 “这是认可的方法”:不相关的标准,在您与人们联系的另一个线程中也偏离了这一点——找到一个简单的、有效的解决方案更为重要。 “可以应用于所有软件包”:aptitude 也可能几乎可以获取所有软件包。如果您需要发行版的 repo 不包含的小型特殊包,那么通过 pip 检索简单的包是很好的! “快速部署时间”:,编译(例如构建 numpy)需要大量时间。
    • 我不遵循你的推理。你在 AWS 上试过吗?这就是他问题的背景——考虑到它的所有特性,让它在 AWS 上可靠地工作。
    • EC2 上的 Linux VM 的行为类似于任何其他 Linux 系统。是的,我已经在 EC2 上尝试过了。我只是不知道您正在通过 Elastic Beanstalk 运行哪种 Linux VM(这完全取决于 Linux 发行版,您需要的软件包是否在存储库中)。这就是为什么你需要测试我的提议。如果它有效:很好——简单可靠的方法。如果没有,则必须寻找另一种解决方案。因此,SSH 进入您的虚拟机,获得超级用户权限并使用发行版的包管理器将 matplotlib 安装到系统 python。此测试不应超过 5 分钟。
    • 应该可以工作,但可能是在调用 Python 应用程序之前再次更改了您的环境。所以,你可以试试这个,但我可能无法可靠地工作。可以肯定的是 sys.path 修改 in 您的应用程序,就在导入之前。从字面上看,没有什么可以干扰这一点。编辑:是的,您提出的解决方案和我的解决方案是相同的,除了符号链接故事。为了简单和性能,我真的建议创建符号链接。另外,您提议的/opt/science-stack-packages 对我来说看起来不错:)。 Edit2:记住,sys.path 中的项目顺序很重要。
    【解决方案2】:

    添加到 Jan-Philip 答案:

    AWS Elastic Beanstalk 正在使用 Amazon Linux 发行版(.Net 环境除外)。 Amazon Linux 使用 yum 包管理器。 MatPlotLib 在 Amazon 的软件存储库中可用。

    [ec2-user@ip-1-1-1-174 ~]$ yum list | grep matplot
    python-matplotlib.x86_64            0.99.1.2-1.6.amzn1              amzn-main
    

    如果您的应用程序需要此版本,我会尝试简单地修改您的 .ebextensions/software.config 文件并将包添加到它的 yum 部分:

    packages:
      yum:
        python-matplotlib: [] 
        python-devel: []
        atlas-sse3-devel: []
        lapack-devel: []
        libpng-devel: []
        freetype-devel: []
        zlib-devel: []
    

    关于 AWS Elastic BeansTalk 和 SSH 的最后说明。

    虽然 Amazon 为您提供了通过 SSH 连接到 Elastic Beanstalk 实例的可能性,但您应该仅将这种可能性用于调试目的,以了解您的应用程序失败或未按建议安装的原因。

    除此之外,您的部署必须是 100% 自动的。当 Elastic Beanstalk(准确地说是 Auto Scaling)将根据您的应用程序工作负载扩展您的基础架构(添加更多实例)或扩展它(终止实例)时,您的所有手动配置都将丢失。

    最佳做法是不要在您的生产环境中安装 SSH 密钥,这会进一步减少攻击面。

    【讨论】:

    • 很好,感谢您填补我与 EB 相关的知识空白,这些答案真的很好:-)。
    • 好收获;这将是我的后续行动——考虑到环境可以自动终止或实例化(出于各种原因)这一事实,SSH(或任何手动配置)是否真的可以在 EB 上运行。
    • 还有一个问题:为什么我不能让 PIP 在 SSH 中工作?
    • 还有一个:它看起来像things may not be this simple after all。以上内容是否足以构成我的 EB 申请?或者如果我想让yum 方法起作用,我还需要做这篇文章中描述的其他事情(指向site-packages 等)吗?
    • 据我所知,这些答案都不起作用。包管理器 (yum) 没有放置 Matplotlib(或者就此而言 NumpySciPy;也许是所有包?)in a place that is accessible to EB(即 EB virtualenv)。例如,它们不会出现在pip list 中。相反,它们都在/usr/lib64/python2.6/site-packages 中,而不是(也不应该)在sys.path 上。
    【解决方案3】:

    这个问题我可能有点晚了,但由于 AWS 和许多云服务提供商正在转向 Docker 并考虑到您尚未指定平台。我对您的问题有一个快速的解决方案:

    1. 使用通用 docker 平台。
    2. 我创建了一些预装了 Python、Numpy、Scipy 和 Matplotlib 的图像,因此您可以通过一行代码直接拉取并开始使用它们。

    Python 2.7(这个也有你为 numpy 和 matplotlib 指定的版本)

    sudo docker pull chuseuiti/pynuscimat2.7
    

    Python 3.4

    sudo docker pull chuseuiti/pynusci
    

    但是,您可以创建自己的图像或修改现有图像。

    如果您想自动化您的实例,您可以将 Dockerfile 与您的映像定义一起传递给 AWS。

    提示,如果您不了解 docker:

    需要登录才能拉取:

    sudo docker login
    

    拉取镜像后,您可以使用以下代码生成并在从镜像创建的容器中工作:

     sudo docker run -i -t chuseuiti/pynuscimat2.7 bash
    

    PS。至少对于免费层 AWS 总是抱怨 scipy 和 matplotlib 时间不够用,安装它们需要太多时间,这就是我使用这个选项的原因。

    【讨论】:

      猜你喜欢
      • 2015-09-26
      • 2013-03-21
      • 2018-07-01
      • 2021-12-01
      • 2018-05-25
      • 2021-01-07
      • 2015-04-03
      • 1970-01-01
      • 2018-07-10
      相关资源
      最近更新 更多