使用 PHP 从 Elastic Beanstalk 连接到 EFS

Connecting to EFS from Elastic Beanstalk with PHP

和往常一样,操作越简单,AWS文档就越让我困惑。我想使用 PHP 写入和读取存储在 EFS 上的文件。我有使用 AWS 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 文件或有限的 "one time" 控制台配置中执行所有操作的答案。这一点是我需要 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 服务器上为持久保存用户文件上传等所做的工作。

部署代码时,您必须使用 AWS EBExtensions 机制从 EB/EC2 实例建立连接。这样做的示例配置片段是:

# 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 上的应用程序是持久的。

希望对您有所帮助