如何为AWS Elastic Beanstalk应用程序安装matplotlib?

时间:2015-01-22 22:33:58

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

我正忙着在AWS Elastic Beanstalk上部署matplotlib。 I gather我的问题来自某些依赖项以及EB部署使用PIP安装的软件包的方式,并试图遵循instructions here on SO来解决问题。

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

所以在答案结尾处提到的简单解决方案对我很有吸引力:只需eb ssh,用

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

pip install个包。但我也无法让这个工作。首先,我经常遇到left-beind构建目录(如上所述)

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.

但即使删除了这些,我也一直得到

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 pipsudo: 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: []

和以{/ p>结尾的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个小时之后,我已经变得很笨拙了(正如{virtusalenv中pip list报道的那样)。

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

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

3 个答案:

答案 0 :(得分:5)

我在Windows和Linux系统上使用了很多方法来构建和部署numpy / scipy / matplotlib。我使用过系统提供的软件包管理器(aptitude,rpm),第三方软件包管理器(pypm),Python软件包管理器(easy_install,pip),源代码发布,使用不同的构建环境/工具(GCC,还有英特尔MKL,OpenMP) )。在这样做的同时,我遇到了许多非常烦人的情况,但也学到了很多关于每种方法的利弊。

我没有Elastic Beanstalk(EB)的经验,但我有EC2的经验。我看到你可以通过SSH连接到一个实例并进行搜索。所以,我在下面进一步建议是基于

  • 上述经历和
  • 关于Beanstalk和
  • 的或多或少明显的边界条件
  • 您的应用场景,在SO和
  • 上的另一个问题中描述
  • 事实上你只是想让事情快速运转

我的建议:从没有自己构建这些东西开始。不要使用pip。如果可能的话,尝试使用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
  • 蟒-matplotlib-0.99.1.2

此版本的matplotlib非常陈旧,根据changelog它是从2009年9月开始的:&#34; 2009-09-21标记为0.99.1版本&#34;。

我没想到它如此旧,但仍然可能足以满足您的需求。所以我们继续我们的计划(但我知道这是否是一个阻止者)。

现在,我们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部分:

  

您可以使用命令键在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文档说&#34; cfn-init帮助程序脚本按以下顺序处理这些配置部分:包,组,用户,源,文件,命令,然后是服务。&#34; http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-init.html

所以,你的方法是安全的 [/ UPDATE]

正如本答案的评论中所指出的,关键步骤是告诉您的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")

然而,如果我们对整个方法进行深思熟虑,那就不应该这样做了。

答案 1 :(得分:3)

添加到Jan-Philip答案:

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

[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的最后一点说明。

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

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

最佳做法是不在生产环境中安装SSH密钥,它进一步减少了攻击的范围。

答案 2 :(得分:1)

我对这个问题可能有点迟了,但是随着AWS和许多云服务提供商进入Docker并考虑到你没有指定平台。我快速解决了你的问题:

  1. 使用通用docker平台。
  2. 我使用预装的Python,Numpy,Scipy和Matplotlib创建了一些图像,因此您可以直接拉动并开始使用一行代码。
  3. Python 2.7(这个也有你为numpy和matplotlib指定的版本)

    sudo docker pull chuseuiti/pynuscimat2.7
    

    Python 3.4

    sudo docker pull chuseuiti/pynusci
    

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

    如果您想自动化实例,可以使用图像定义将Dockerfile传递给AWS。

    提示,如果您不了解泊坞广告:

    需要先登录才能拉:

    sudo docker login
    

    拉动图像后,您可以使用下一个代码生成并处理使用图像创建的容器:

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

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