使用 PHP 从 Elastic Beanstalk 连接到 EFS
Connecting to EFS from Elastic Beanstalk with PHP
和往常一样,操作越简单,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 文件或有限的 "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 上的应用程序是持久的。
希望对您有所帮助
和往常一样,操作越简单,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 文件或有限的 "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 上的应用程序是持久的。
希望对您有所帮助