如何根据两种情况在 AWS ALB 中路由流量

How to route traffic in AWS ALB based on two conditions

我正在将服务从 Kubernetes 迁移到 AWS ECS。对于路由,我使用 AWS Application Load Balancer (ALB)。

ALB 在端口 80 上有一个侦听器,我的服务聚合在目标组中。

为了在服务之间路由流量,我使用了 ALB 侦听器规则。 对于路由,我需要满足两个条件:host-headerpath-pattern.

所以我想要如下内容:

我尝试向规则添加多个条件(在 Terrafom 中),但是只能有 host-headerpath-pattern:

Only one of host_header, http_header, http_request_method, path_pattern, query_string or source_ip can be set in a condition block

也无法在 AWS 控制台中将 host_headerpath_pattern 一起添加。

如何根据两个条件在 AWS ALB 中路由流量 - host-header + path-pattern?

一个可能的选择是每个主机使用一个 ALB,但是当主机/子域的数量增加时,这会太昂贵。

在 Kubernetes 中是如何完成的

在 Kubernetes 的 nginx 入口路由器中可以同时使用主机头和路径模式路由。例如有这两个入口资源:

资源 1

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: web-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
    - host: domain-one.com
      http:
        paths:
          - path: /web
            backend:
              serviceName: web-service
              servicePort: 8080
          - path: /media/files
            backend:
              serviceName: web-service
              servicePort: 8080

    - host: another-domain.com
      http:
        paths:
          - path: /web
            backend:
              serviceName: web-service
              servicePort: 8080
          - path: /media/files
            backend:
              serviceName: web-service
              servicePort: 8080


资源 2

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: api-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
    - host: www.domain-one.com
      http:
        paths:
          - path: /api
            backend:
              serviceName: api-service
              servicePort: 8181


对于 Kubernetes,除了 path 参数之外,还可以定义一个可选的 host 参数。 所以最后 hostpath 都必须在负载均衡器将流量定向到相应的后端之前匹配传入请求的内容:

那么,如何在 AWS ALB 上实现同样的效果呢?

谢谢。

A​​LB 侦听器规则可以包含多个条件,但一个条件只能包含一个描述的块。

单个规则的条件使用 AND 处理,因此必须满足所有条件才能路由到目标组。

因此需要为多个主机创建多个规则,如下所述:

编辑我将验证此解决方案并将更新post。

编辑 2此解决方案有效。

我也在从 k8s 迁移到 ECS。 正如您提到的,您需要有多个条件。 这就是我在 terraform 中的做法。

resource "aws_lb_listener_rule" "backend_api_routing" {
  depends_on = [aws_alb_target_group.main8080]

  listener_arn = var.https_aws_alb_listener_arn
  priority     = var.backend_api_routing_priority

  action {
    type             = "forward"
    target_group_arn = aws_alb_target_group.main8080.arn
  }

  condition {
    host_header {
      values = ["domain-one.com"]
    }
  }

  condition {
    path_pattern {
      values = ["/web/*", "/media/files/*"]
    }
  }
}

此外,我建议您检查一下 terragrunt,它允许您重新使用 terraform 模块。