我正在尝试将持久卷挂载到容器中,但容器没有启动,因为错误:"没有这样的文件或目录"。
下面是相关配置:
# EFS
resource "aws_security_group" "allow_nfs_inbound" {
name = "${local.resource_prefix}-allow-nfs-inbound"
vpc_id = module.vpc.vpc_id
ingress {
from_port = 2049
to_port = 2049
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "all"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
lifecycle {
create_before_destroy = true
}
}
resource "aws_efs_file_system" "persistent" {
creation_token = "${local.resource_prefix}-efs"
encrypted = true
}
resource "aws_efs_mount_target" "mount_targets" {
count = length(module.vpc.private_subnets)
file_system_id = aws_efs_file_system.persistent.id
subnet_id = module.vpc.private_subnets[count.index]
security_groups = [aws_security_group.allow_nfs_inbound.id]
}
resource "aws_efs_access_point" "assets_access_point" {
file_system_id = aws_efs_file_system.persistent.id
root_directory {
path = "/assets"
creation_info {
owner_gid = 0
owner_uid = 0
permissions = "755"
}
}
}
resource "aws_efs_access_point" "shared_access_point" {
file_system_id = aws_efs_file_system.persistent.id
root_directory {
path = "/shared"
creation_info {
owner_gid = 0
owner_uid = 0
permissions = "755"
}
}
}
# ECS
resource "aws_ecs_task_definition" "backend_task_definition" {
...
container_definitions = jsonencode(
[
{
...
mountPoints = [
{
sourceVolume = "assets"
containerPath = "/app/assets"
readOnly = false
},
{
sourceVolume = "shared"
containerPath = "/app/shared"
readOnly = false
}
]
volumesFrom = []
...
}
]
volume {
name = "assets"
efs_volume_configuration {
file_system_id = aws_efs_file_system.persistent.id
root_directory = "/assets"
}
}
volume {
name = "shared"
efs_volume_configuration {
file_system_id = aws_efs_file_system.persistent.id
root_directory = "/shared"
}
}
...
}
resource "aws_security_group" "allow_efs" {
name = "${local.resource_prefix}-allow-efs"
vpc_id = module.vpc.vpc_id
ingress {
from_port = 2049
to_port = 2049
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
}
resource "aws_ecs_service" "backend_ecs_service" {
...
network_configuration {
subnets = setunion(
module.vpc.public_subnets
)
security_groups = [aws_security_group.allow_efs.id]
assign_public_ip = true
}
...
}
完整的错误信息是:
Resourceinitializationerror: failed to invoke EFS utils commands to set EFS volumes: stderr: b'mount。nfs4: mount:/assets失败,服务器给出原因:没有这样的文件或目录':不成功的EFS utils命令执行;代码:32
网络配置应该是正确的,因为如果我删除安全组,我会得到一个不同的网络相关错误。
编辑:
添加dockerRUN
:
RUN apt-get update &&
apt-get -y install git binutils &&
git clone https://github.com/aws/efs-utils &&
cd efs-utils &&
./build-deb.sh &&
apt-get -y install ./build/amazon-efs-utils*deb
RUN wget https://bootstrap.pypa.io/pip/3.5/get-pip.py -O /tmp/get-pip.py &&
python3 /tmp/get-pip.py &&
pip3 install botocore
我真的不知道为什么你会得到那个特定的错误。您可能想要确保在您的aws_ecs_service
资源定义中有platform_version = "1.4.0"
。我认为1.4.0
现在是默认的,但是你没有显示你的整个资源定义,如果你把它设置为1.3.0
这样的东西,可能会导致这个问题。
还确保在aws_ecs_service
资源定义中有launch_type = "FARGATE"
(再次我不得不猜测,因为您没有包含完整的代码)。对我来说,这个错误听起来更像是运行自定义EC2 AMI的EC2部署会发生的问题,而不是Fargate部署。所以仔细检查你是否真的部署到Fargate。
另外,您没有配置ECS来使用您创建的EFS接入点。你应该改变你的volume
块看起来像这样;
volume {
name = "assets"
efs_volume_configuration {
file_system_id = aws_efs_file_system.persistent.id
root_directory = "/assets"
transit_encryption = "ENABLED"
authorization_config {
access_point_id = aws_efs_access_point.assets_access_point.id
iam = "ENABLED"
}
}
}
volume {
name = "shared"
efs_volume_configuration {
file_system_id = aws_efs_file_system.persistent.id
root_directory = "/shared"
transit_encryption = "ENABLED"
authorization_config {
access_point_id = aws_efs_access_point.shared_access_point.id
iam = "ENABLED"
}
}
}
还有,你为什么在这里做setunion()
?
subnets = setunion(
module.vpc.public_subnets
)
如果您的module.vpc.public_subnets
是一个集合列表,那么您需要在访问该模块输出变量的任何地方执行setunion()
,例如在aws_efs_mount_target
资源中。但是如果你的module.vpc.public_subnets
不是一个集合列表,那么这个函数调用是没有意义的。