【问题标题】:Connecting to EFS from Elastic Beanstalk with PHP使用 PHP 从 Elastic Beanstalk 连接到 EFS
【发布时间】:2019-02-12 06:31:35
【问题描述】:

像往常一样,操作越简单,AWS 文档就越让我感到困惑。我想使用 PHP 来写入和读取存储在 EFS 上的文件。我有使用 AWS PHP 库的经验,我只需要正确的代码来促进交流。这是我的设置:

  • 我的默认 VPC 上的 1 EFS 文件系统。
  • 1 Elasticbeanstalk 环境,将“storage-efs-mountfilesystem.config”添加到最新应用程序代码的 .ebextensions 目录中,并在没有错误的情况下初始化(这让我认为它正在连接)。 EB 的安全组被添加到 EFS 安全组。 AWS PHP SDK 也存在于应用程序中
  • 应用程序中有 1 个 PHP 文件

现在在文件中我通常以这种方式连接到其他服务:

use Aws\S3\S3Client;
$options = [
    'region'            => 'us-east-1',
    'version'           => '2006-03-01',
    'signature_version' => 'v4',
    'credentials' => [
        'key' => 'key#',
        'secret' => 'secret#'
    ] 
];
$GLOBALS['s3Client'] = new S3Client($options);
$writeFile = $GLOBALS['s3Client']->putObject(array(...

我认为这对于 EFS 应该是一样的。作为第一个猜测,我尝试了:

$efsOptions = [
    'region'            => 'us-east-1',
    'version'           => 'latest',
    'credentials' => [
        'key' => 'key#',
        'secret' => 'secret#'
    ] 
];
use Aws\Efs\EfsClient;
$efsClient = new EfsClient($efsOptions);
$result = $efsClient->describeFileSystems(array(
    'FileSystemId' => 'fs-#'
));

但是得到一个错误:

Fatal error: Uncaught exception 'Aws\Efs\Exception\EfsException' with message 'Error executing "DescribeFileSystems" on "https://elasticfilesystem.us-east-1.amazonaws.com/2015-02-01/file-systems?FileSystemId=f#"; AWS HTTP error: Client error: `GET https://elasticfilesystem.us-east-1.amazonaws.com/2015-02-01/file-systems?FileSystemId=f#` resulted in a `403 Forbidden`

那么正确的方法是什么? (须藤代码):

use Aws\efs\EfsClient;
$options = [
    'What keys need to be here' => 'paramter',
    'credentials' => [
        'key' => 'key#',
        'secret' => 'sevret#'
    ] 
];
$efsClient = new EfsClient($options);
$dir = "/test/";
$makeDir = $efsClient -> mkdir($dir);
$scanDir = $efsClient -> scandir($dir);
print_r($scanDir);
**/test/

我从不使用控制台或连接到服务器来安装软件包,因此请将其限制为允许我在 PHP 文件中执行所有操作或有限的“一次性”控制台配置的答案。重点是我需要 PHP 脚本来创建和读取 EFS 上的文件并与其他 EB 环境共享这些文件。到目前为止我已经查看或使用过的 AWS 文档:

https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/services-efs.html https://github.com/awsdocs/elastic-beanstalk-samples/blob/master/configuration-files/aws-provided/instance-configuration/storage-efs-mountfilesystem.config https://docs.aws.amazon.com/aws-sdk-php/v2/api/class-Aws.Efs.EfsClient.html

【问题讨论】:

  • 为什么不将 EFS 作为共享安装在运行代码的 EC2 实例上。那么 EFS 只是您的 PHP 应用程序可以写入的常规路径。这就是我们在 Elastic Beanstalk Web 服务器上为持久用户文件上传等所做的工作。
  • 是的,这也可以。你有任何关于如何完成连接的示例代码吗?使用 PHP 的原生文件命令会很棒。
  • 我在下面回答了一个小例子。
  • @mrunion 谢谢先生 .. 我今天会试一试并跟进。

标签: php amazon-web-services amazon-elastic-beanstalk mkdir amazon-efs


【解决方案1】:

为什么不将 EFS 作为共享安装在运行代码的 EC2 实例上。那么 EFS 只是您的 PHP 应用程序可以写入的常规路径。这就是我们在 Elastic Beanstalk Web 服务器上为持久用户文件上传等所做的工作。

您必须在部署代码时使用 AWS EBExtensions 机制设置与 EB/EC2 实例的连接。用于执行此操作的示例配置 sn-p 是:

# config.yml file:

files:
  "/opt/elasticbeanstalk/hooks/appdeploy/post/my_config_job.sh":
    mode: "000755"
    owner: root
    group: root
    content: |
      #!/usr/bin/env bash
      # Load the EFS path from the EB environment settings
      # (The variables are set in the "Configuration" section in the AWS
      # Console under the "Environment properties" area. That area takes
      # Name and Value pairs, so in our example below, the value
      # "WHERE_TO_MOUNT_EFS" is the Name of the variable, and it contains
      # a path on the EC2, for example "/efs". That would mount the EFS
      # volume at the path /efs on the filesystem.
      WHERE_TO_MOUNT_EFS=$(/opt/elasticbeanstalk/bin/get-config environment -k WHERE_TO_MOUNT_EFS)

      # This is the actual AWS EFS volume name that has been set up
      EFS_VOLUME_NAME=$(/opt/elasticbeanstalk/bin/get-config environment -k EFS_VOLUME_NAME)

      # Now create the path for the mount on the filesystem (again, in 
      # our example "/efs" as specified in the WHERE_TO_MOUNT_EFS variable)
      mkdir ${WHERE_TO_MOUNT_EFS}

      # Now actually mount the EFS to the "/efs" folder created above
      mount -t nfs4 -o nfsvers=4.1 ${EFS_VOLUME_NAME}-$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone).mydomain.com:/ ${WHERE_TO_MOUNT_EFS}

当然,这只是一个示例。

“curl”命令用于查询 AWS 在特殊 IP 169.254.169.154 提供的信息。您的域和路径会有所不同。

另外,这是一个在 Linux 上运行的 Bash 脚本。如果您在 EB 上使用 Windows,则必须调整此过程。

最后,在上面的挂载之后,在我们的脚本中,我们实际上继续创建从我们网站的子文件夹到附加的 EFS 文件夹的符号链接。我们还使用 Bash 命令管理权限,这些命令为“webapp”用户分配所需的权限。当然,这些步骤是可选的。

现在 PHP 只会将该文件夹视为文件系统上的路径,但实际上它位于您的 EFS 共享上。当 EB 环境重新构建时,此脚本会自动重新运行并重新附加 EFS,因此数据似乎会持久保存到 EC2 上的应用程序中。

希望对你有帮助

【讨论】:

  • 嘿@mrunion - 再次,非常感谢你..刚从旅行回来并能够测试它。澄清一下,“mydomain.com”应该是 EB 应用程序的 URL 正确吗?我能够按照您的所有指示进行操作,并且没有出错。当我运行 PHP 的 mkdir 时,它作为用户“ec2-user”得到“警告:mkdir():权限被拒绝”。这听起来像您在可选部分中描述的权限问题吗?谢谢!
  • 是的,使用您的域。至于 PHP 错误,是的,您的假设似乎是正确的——至少部分正确。在我们的例子中,Web 应用程序作为用户“webapp”而不是“ec2-user”运行。您可以在“mkdir...WHERE_TO_MOUNT_EFS..”部分之后将另一段代码添加到上面的示例脚本中,以更改安装点权限,以便“webapp”用户可以在那里编写。在我的办公室,我们只使用一个 EFS,在上面的每个应用程序的脚本中,我们在“装载”之后还有一个额外的步骤,该步骤在 EFS 上为该特定应用程序创建一个子文件夹,然后授予“webapp”用户/组适当的访问权限。跨度>
  • 是的,webapp 运行良好。非常感谢您抽出宝贵时间提供帮助。这是一个巨大的帮助。
  • 如果我想将我的 efs 挂载到 /var/www/html/uploads 文件夹怎么办...我尝试将我的挂载点创建为 /var/www/html/uploads,但在环境之后创建 efs 正在安装到 /var/app/current.old/uploads...不明白为什么。
猜你喜欢
  • 2018-12-08
  • 2020-11-14
  • 2016-02-15
  • 2014-02-10
  • 2015-12-10
  • 2021-02-14
  • 2015-11-07
  • 2015-04-13
  • 2016-08-24
相关资源
最近更新 更多