我有一个在ECS Fargate
上运行的API,它接受GET
的方法请求。我在其前面放置了一个API Gateway
端点,并在一个私有子网中与一个VPC_LINK
进行了NLB
集成。使用调用URL发送GET
请求时,出现404 page not found
错误。我很困惑为什么要得到这个。我在8000/tcp
上的任务定义中设置了每个组件-NLB侦听器,目标组以及主机和容器端口。因此,我不确定为什么会发生此错误。我的Fargate
任务也正在成功运行,并通过了所有运行状况检查。当我在本地进行curl -X GET localhost/nmapscan:8000
测试容器时,它工作正常。以下是我在Terraform
中的配置以及控制台的屏幕截图。
Terraform:
resource "aws_lb" "myapis" {
name = "my-apis"
internal = true
load_balancer_type = "network"
subnets = ["${module.vpc.private_subnets}"]
enable_deletion_protection = false
tags = {
Environment = "dev"
}
}
resource "aws_security_group" "ecs_tasks" {
name = "ecs-tasks"
description = "allow inbound access from the NLB only"
vpc_id = "${module.vpc.vpc_id}"
ingress {
protocol = "tcp"
from_port = 8000
to_port = 8000
cidr_blocks = ["10.10.11.0/24", "10.10.12.0/24", "10.10.13.0/24"]
}
egress {
protocol = "-1"
from_port = 0
to_port = 0
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_lb_target_group" "test" {
name = "test-api"
port = 8000
protocol = "TCP"
target_type = "ip"
vpc_id = "${module.vpc.vpc_id}"
stickiness{
enabled = false
type = "lb_cookie"
}
health_check{
interval = 30
port = 8000
protocol = "tcp"
healthy_threshold = 2
unhealthy_threshold = 2
}
}
resource "aws_lb_listener" "test" {
load_balancer_arn = "${aws_lb.myapis.id}"
port = "8000"
protocol = "TCP"
default_action {
target_group_arn = "${aws_lb_target_group.test.id}"
type = "forward"
}
}
resource "aws_api_gateway_vpc_link" "myapi" {
name = "my_api_link"
description = "VPC link for API NLB"
target_arns = ["${aws_lb.myapis.arn}"]
}
resource "aws_api_gateway_rest_api" "GOAPI" {
name = "GO"
description = "REST API for GO APIs"
}
resource "aws_api_gateway_resource" "test" {
rest_api_id = "${aws_api_gateway_rest_api.GOAPI.id}"
parent_id = "${aws_api_gateway_rest_api.GOAPI.root_resource_id}"
path_part = "nmapscan"
}
resource "aws_api_gateway_method" "testmethod" {
rest_api_id = "${aws_api_gateway_rest_api.GOAPI.id}"
resource_id = "${aws_api_gateway_resource.test.id}"
http_method = "GET"
authorization = "NONE"
}
resource "aws_api_gateway_integration" "integrationtest" {
connection_type = "VPC_LINK"
connection_id = "${aws_api_gateway_vpc_link.myapi.id}"
type = "HTTP"
integration_http_method = "GET"
rest_api_id = "${aws_api_gateway_rest_api.GOAPI.id}"
resource_id = "${aws_api_gateway_resource.test.id}"
http_method = "${aws_api_gateway_method.testmethod.http_method}"
uri = "${format("https://%s:8000/", aws_lb.myapis.dns_name)}"
}
resource "aws_api_gateway_method_response" "test-200" {
rest_api_id = "${aws_api_gateway_rest_api.GOAPI.id}"
resource_id = "${aws_api_gateway_resource.test.id}"
http_method = "${aws_api_gateway_method.testmethod.http_method}"
status_code = "200"
response_models = {
"application/json" = "Empty"
}
}
resource "aws_api_gateway_integration_response" "testintegrationresponse" {
rest_api_id = "${aws_api_gateway_rest_api.GOAPI.id}"
resource_id = "${aws_api_gateway_resource.test.id}"
http_method = "${aws_api_gateway_method.testmethod.http_method}"
status_code = "${aws_api_gateway_method_response.test-200.status_code}"
response_templates = {
"application/json" = ""
}
}
resource "aws_api_gateway_deployment" "testdeploy" {
depends_on = ["aws_api_gateway_integration.integrationtest"]
rest_api_id = "${aws_api_gateway_rest_api.GOAPI.id}"
stage_name = "v1"
}
resource "aws_ecs_cluster" "goapi" {
name = "goapis"
}
data "aws_iam_role" "ecs_task_execution_role" {
name = "ecsTaskExecutionRole"
}
resource "aws_ecs_task_definition" "test" {
family = "test"
requires_compatibilities = ["FARGATE"]
network_mode = "awsvpc"
cpu = 256
memory = 512
execution_role_arn = "${data.aws_iam_role.ecs_task_execution_role.arn}"
container_definitions = "${file("test-service.json")}"
}
resource "aws_ecs_service" "test" {
name = "test-service"
cluster = "${aws_ecs_cluster.goapi.id}"
task_definition = "${aws_ecs_task_definition.test.arn}"
launch_type = "FARGATE"
desired_count = 1
network_configuration {
subnets = ["${module.vpc.private_subnets}"]
security_groups = ["${aws_security_group.ecs_tasks.id}"]
}
load_balancer {
target_group_arn = "${aws_lb_target_group.test.id}"
container_name = "test-service"
container_port = 8000
}
depends_on = [
"aws_lb_listener.test",
]
}
Task Definiton:
[
{
"name": "test-service",
"image": "12345678910.dkr.ecr.us-east-1.amazonaws.com/myimages:latest",
"cpu": 256,
"memory": 512,
"essential": true,
"portMappings": [
{
"containerPort": 8000,
"hostPort": 8000
}
]
}
]
Screenshots:
答案 0 :(得分:0)
编辑 似乎答案来自here,可能不建议弃用该帖子。
除非成功通过SIGV4在方法请求上使用IAM auth签名您的请求,或者在身份验证失败的情况下映射了自定义网关响应,否则API网关将不会返回404,并且NLB也不会返回,因此此响应必须到来在此堆栈中超出NLB。您应该可以通过查看API Gateway CloudWatch logs来确认这一点(在舞台上启用完整的请求/响应数据)。
注意:您应该将CloudWatch日志中的请求ID与API GW响应标头“ x-amzn-requestid”进行匹配,例如:
x-amzn-requestid:7cc765bb-4086-45f4-9450-1a2a3c4e67d5
在日志中,您应该看到它上面写着“正在将请求发送到...”之类的内容,或者说它从该请求返回的响应行。这表明API网关已收到请求,将其发送到后端集成,并收到404作为回报。
我要说的下一步是对集成实施调试日志记录,以记录传入的请求以及这些请求的属性,以便您可以确定故障所在。好像请求是针对您的应用未配置为响应的URI。