У меня кластер ECS
, работающий поверх EC2
в частных подсетях. У меня есть запись CNAME
в моем регистраторе, которая перенаправляет мой домен API на имя DNS
моего открытого доступа NLB
. У меня есть nginx
контейнер для боковой машины, действующий в качестве обратного прокси для пользовательского Go
API. Порты хоста / контейнера прослушивают 443, а затем контейнер nginx направляет мой API через 8080 через мостовую сеть. Слушатель балансировки нагрузки прослушивает 443 / TCP, так как я хочу, чтобы завершение TLS
было выполнено с контейнером nginx. Таким образом, у меня есть tcp
проход на NLB. Я также прикрепил целевую группу, принимающую трафик через 443 / tcp. Кроме того, я подключил группу безопасности к кластеру, позволяющему весь трафик свыше 443 из балансировщика сетевой нагрузки. Несмотря на все это, когда я делаю запросы к API, я получаю тайм-аут подключения к балансировщику нагрузки. У меня такое чувство, что у меня здесь мои утки подряд, поэтому я не знаю, почему это происходит. Все проверки здоровья моей целевой группы также проходят. Ниже приведены моя конфигурация, nginx conf, определение задачи и вывод ошибок.
Configuration:
resource "aws_lb" "myapi_api_lb" {
name = "my-api-lb"
internal = false
load_balancer_type = "network"
subnets = ["${module.vpc.public_subnets}"]
enable_deletion_protection = false
tags = {
Environment = "dev/demo"
}
}
resource "aws_security_group" "ecs_tasks" {
name = "ecs-tasks"
description = "allow inbound access from the LB only"
vpc_id = "${module.vpc.vpc_id}"
ingress {
protocol = "TCP"
from_port = 443
to_port = 443
cidr_blocks = ["10.10.1.0/24", "10.10.2.0/24", "10.10.3.0/24"]
}
egress {
protocol = "-1"
from_port = 0
to_port = 0
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_lb_target_group" "myapi_api_tg" {
name = "myapi-api-tg"
port = 443
protocol = "TCP"
target_type = "instance"
vpc_id = "${module.vpc.vpc_id}"
stickiness{
enabled = false
type = "lb_cookie"
}
health_check{
interval = 10
port = 443
protocol = "TCP"
healthy_threshold = 2
unhealthy_threshold = 2
}
}
resource "aws_lb_listener" "myapi_listener" {
load_balancer_arn = "${aws_lb.myapi_api_lb.id}"
port = "443"
protocol = "TCP"
default_action {
target_group_arn = "${aws_lb_target_group.myapi_tg.id}"
type = "forward"
}
}
resource "aws_iam_role" "ecs-instance-role" {
name = "ecs-instance-role"
path = "/"
assume_role_policy = "${data.aws_iam_policy_document.ecs-instance-policy.json}"
}
data "aws_iam_policy_document" "ecs-instance-policy" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["ec2.amazonaws.com"]
}
}
}
resource "aws_iam_role_policy_attachment" "ecs-instance-role-attachment" {
role = "${aws_iam_role.ecs-instance-role.name}"
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role"
}
resource "aws_iam_instance_profile" "ecs-instance-profile" {
name = "ecs-instance-profile"
path = "/"
role = "${aws_iam_role.ecs-instance-role.id}"
provisioner "local-exec" {
command = "sleep 10"
}
}
resource "aws_launch_configuration" "ecs-launch-configuration" {
image_id = "ami-123456"
instance_type = "t2.medium"
iam_instance_profile = "${aws_iam_instance_profile.ecs-instance-profile.id}"
root_block_device {
volume_type = "standard"
volume_size = 25
delete_on_termination = false
}
lifecycle {
create_before_destroy = true
}
security_groups = ["${aws_security_group.ecs_tasks.id}", "${module.ssh_security_group.this_security_group_id}"]
associate_public_ip_address = "false"
key_name = "myapiadmin"
user_data = <<EOF
#!/bin/bash
sudo yum update -y ecs-init
echo ECS_CLUSTER=${aws_ecs_cluster.myapi.name} >> /etc/ecs/ecs.config
EOF
}
resource "aws_autoscaling_group" "ecs-autoscaling-group" {
name = "ecs-autoscaling-group"
max_size = 4
min_size = 2
desired_capacity = 2
vpc_zone_identifier = ["${module.vpc.private_subnets}"]
launch_configuration = "${aws_launch_configuration.ecs-launch-configuration.name}"
health_check_type = "ELB"
}
resource "aws_ecs_cluster" "myapi" {
name = "mygoapis"
}
data "aws_iam_role" "ecs_task_execution_role" {
name = "ecsTaskExecutionRole"
}
resource "aws_ecs_task_definition" "myapi" {
family = "myapi"
requires_compatibilities = ["EC2"]
network_mode = "bridge"
cpu = 512
memory = 1024
execution_role_arn = "${data.aws_iam_role.ecs_task_execution_role.arn}"
container_definitions = "${file("myapi-service.json")}"
}
resource "aws_ecs_service" "myapiservice" {
name = "myapi_service"
cluster = "${aws_ecs_cluster.myapi.id}"
task_definition = "${aws_ecs_task_definition.myapi.arn}"
launch_type = "EC2"
desired_count = 2
load_balancer {
target_group_arn = "${aws_lb_target_group.myapi_tg.id}"
container_name = "nginx"
container_port = 443
}
depends_on = [
"aws_lb_listener.myapi_listener",
]
}
nginx.conf:
events { }
http {
server {
listen 80;
listen [::]:80;
server_name www.myapi.com myapi.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name www.myapi.com myapi.com;
ssl_certificate /etc/certbot/live/myapi.com/fullchain.pem;
ssl_certificate_key /etc/certbot/live/myapi.com/privkey.pem;
ssl_dhparam /etc/ssl/ffdhe2048.pem;
ssl_protocols TLSv1.3 TLSv1.2 TLSv1.1;
ssl_prefer_server_ciphers on;
ssl_ciphers EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA512:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:ECDH+AESGCM:ECDH+AES256:DH+AESGCM:DH+AES256:RSA+AESGCM:!aNULL:!eNULL:!LOW:!RC4:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS;
ssl_session_cache shared:TLS:2m;
ssl_buffer_size 4k;
ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1 1.0.0.1 [2606:4700:4700::1111] [2606:4700:4700::1001]; # Cloudflare
add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload' always;
location /api/ {
proxy_pass http://myapi:8080/;
# Reject requests with unsupported HTTP method
if ($request_method !~ ^(GET|POST)$) {
return 405;
}
}
}
}
Task Definition:
[
{
"name": "nginx",
"image": "12345678910.dkr.ecr.us-east-1.amazonaws.com/myapi-reverse-proxy:1.0",
"memory": 256,
"cpu": 256,
"essential": true,
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "reverse_proxy_nginx",
"awslogs-region": "us-east-1",
"awslogs-stream-prefix": "nginx"
}
},
"portMappings": [
{
"hostPort": 443,
"containerPort": 443
}
],
"links": [
"myapi"
]
},
{
"name": "myapi",
"image": "12345678910.dkr.ecr.us-east-1.amazonaws.com/myapi:1.0",
"cpu": 256,
"memory": 256,
"essential": true,
"portMappings": [
{
"containerPort": 8080
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "myapi",
"awslogs-region": "us-east-1",
"awslogs-stream-prefix": "api"
}
}
}
]
Error:
curl -v -X POST https://myapi.com/api/register
* Trying 1.2.3.4...
* TCP_NODELAY set
* Connection failed
* connect to 1.2.3.4 port 443 failed: Operation timed out
* Closing connection 0
curl: (7) Failed to connect to myapi.com port 443: Operation timed out