简体   繁体   English

在 AWS EKS 中,如何定义入口以将一个 ALB 用于多个子域 URL,每个 URL 都有自己的证书?

[英]In AWS EKS, how can I define ingress to use one ALB for multiple subdomain URLs, each with their own certificate?

I have multiple services that need to be exposed to the internet, but I'd like to use a single ALB for them.我有多个服务需要暴露在互联网上,但我想为它们使用一个 ALB。

I am using the latestAWS Load Balancer Controller , and I've been reading the documentation here ( https://kubernetes-sigs.github.io/aws-load-balancer-controller/guide/ingress/annotations/#traffic-routing ), but I haven't found a clear explanation on how to achieve this. I am using the latestAWS Load Balancer Controller , and I've been reading the documentation here ( https://kubernetes-sigs.github.io/aws-load-balancer-controller/guide/ingress/annotations/#traffic-routing ),但我还没有找到关于如何实现这一点的明确解释。

Here's the setup:这是设置:

I have service-a.example.com -and- service-b.example.com.我有 service- a.example.com -and- service-b.example.com。 They each have their own certificates within Amazon Certificate Manager.他们每个人在 Amazon Certificate Manager 中都有自己的证书。

Within Kubernetes, each has its own service object defined as follows (each unique):在 Kubernetes 中,每个都有自己的服务 object,定义如下(每个唯一):

apiVersion: v1
kind: Service
metadata:
  name: svc-a-service
  annotations:
    alb.ingress.kubernetes.io/healthcheck-protocol: HTTP
    alb.ingress.kubernetes.io/healthcheck-port: traffic-port
    alb.ingress.kubernetes.io/healthy-threshold-count: '5'
    alb.ingress.kubernetes.io/unhealthy-threshold-count: '2'
    alb.ingress.kubernetes.io/healthcheck-path: /index.html
    alb.ingress.kubernetes.io/healthcheck-interval-seconds: '30'
    alb.ingress.kubernetes.io/healthcheck-timeout-seconds: '5'
    alb.ingress.kubernetes.io/success-codes: '200'
    alb.ingress.kubernetes.io/tags: Environment=Test,App=ServiceA
spec:
  selector:
    app: service-a
  ports:
  - port: 80
    targetPort: 80
  type: NodePort

And each service has it's own Ingress object defined as follows (again, unique to each and with the correct certificates specified for each service):每个服务都有自己的入口 object,定义如下(同样,每个服务都是唯一的,并且为每个服务指定了正确的证书):

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: svc-a-ingress
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/group.name: services
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/security-groups: sg-01234567898765432
    alb.ingress.kubernetes.io/ip-address-type: ipv4
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
    alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
    alb.ingress.kubernetes.io/actions.response-503: >
      {"type":"fixed-response","fixedResponseConfig":{"contentType":"text/plain","statusCode":"503","messageBody":"Unknown Host"}}
    alb.ingress.kubernetes.io/target-type: instance
    alb.ingress.kubernetes.io/load-balancer-attributes: routing.http2.enabled=true,idle_timeout.timeout_seconds=600
    alb.ingress.kubernetes.io/tags: Environment=Test
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-east-2:555555555555:certificate/33333333-2222-4444-AAAA-EEEEEEEEEEEE
    alb.ingress.kubernetes.io/ssl-policy: ELBSecurityPolicy-2016-08
spec:
  rules:
    - http:
        paths:
          - path: /*
            backend:
              serviceName: ssl-redirect
              servicePort: use-annotation
          - path: /*
            backend:
              serviceName: svc-a-service
              servicePort: 80
          - path: /*
            backend:
              serviceName: response-503
              servicePort: use-annotation

The HTTP to HTTPS redirection works as expected. HTTP 到 HTTPS 重定向按预期工作。

However -- there is no differentiation between my two apps for the load balancer to be able to know that traffic destined for service-a.example.com and service-b.example.com should be routed to two different target groups.但是 - 我的两个应用程序之间没有区别,负载均衡器能够知道发往 service-a.example.com 和 service-b.example.com 的流量应该路由到两个不同的目标组。

In the HTTP:443 listener rules in the console, it shows:在控制台的 HTTP:443 监听器规则中,它显示:

  1. IF Path is /* THEN Forward to ServiceATargetGroup IF Path is /* THEN Forward to ServiceATargetGroup
  2. IF Path is /* THEN Return fixed 503 IF Path is /* THEN Return fixed 503
  3. IF Path is /* THEN Forward to ServiceBTargetGroup IF Path is /* THEN Forward to ServiceBTargetGroup
  4. IF Path is /* THEN Return fixed 503 IF Path is /* THEN Return fixed 503
  5. IF Request otherwise not routed THEN Return fixed 404 IF 请求否则未路由 THEN 返回固定 404

So the important question here is: How should the ingress be defined to force traffic destined for service-a.example.com to ServiceATargetGroup - and traffic destined for service-b.example.com to ServiceBTargetGroup?所以这里的重要问题是:应该如何定义入口以强制将发往 service-a.example.com 的流量发送到 ServiceATargetGroup - 并将发往 service-b.example.com 的流量发送到 ServiceBargetGroup?

And secondarily, I need the "otherwise not routed" to return a 503 instead of 404. I was expecting this to appear only once in the rules (be merged) - yet it is created for each ingress.其次,我需要“否则不路由”来返回 503 而不是 404。我希望这只会在规则中出现一次(被合并) - 但它是为每个入口创建的。 How should my yaml be structured to achieve this?我的 yaml 应该如何构建以实现这一目标?

I eventually figured this out -- so for anyone else stumbling onto this post, here's how I resolved it:我最终想通了——所以对于其他偶然发现这篇文章的人来说,我是这样解决的:

The trick was not relying on merging between the Ingress objects.诀窍不是依赖于 Ingress 对象之间的合并。 Yes, it can handle a certain degree of merging, but there's not really a one-to-one relationship between Services as TargetGroups and Ingress as ALB.是的,它可以处理一定程度的合并,但是作为 TargetGroups 的 Services 和作为 ALB 的 Ingress 之间并没有真正的一对一关系。 So you have to be very cautious and aware of what's in each Ingress object.因此,您必须非常谨慎并了解每个 Ingress object 中的内容。

Once I combined all of my ingress into a single object definition, I was able to get it working exactly as I wanted with the following YAML:一旦我将所有入口合并到一个 object 定义中,我就可以使用以下 YAML 让它完全按照我的意愿工作:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: svc-ingress
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/group.name: services
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/security-groups: sg-01234567898765432
    alb.ingress.kubernetes.io/ip-address-type: ipv4
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
    alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
    alb.ingress.kubernetes.io/actions.response-503: >
      {"type":"fixed-response","fixedResponseConfig":{"contentType":"text/plain","statusCode":"503","messageBody":"Unknown Host"}}
    alb.ingress.kubernetes.io/actions.svc-a-host: >
      {"type":"forward","forwardConfig":{"targetGroups":[{"serviceName":"svc-a-service","servicePort":80,"weight":100}]}}
    alb.ingress.kubernetes.io/conditions.svc-a-host: >
      [{"field":"host-header","hostHeaderConfig":{"values":["svc-a.example.com"]}}]
    alb.ingress.kubernetes.io/actions.svc-b-host: >
      {"type":"forward","forwardConfig":{"targetGroups":[{"serviceName":"svc-b-service","servicePort":80,"weight":100}]}}
    alb.ingress.kubernetes.io/conditions.svc-b-host: >
      [{"field":"host-header","hostHeaderConfig":{"values":["svc-b.example.com"]}}]
    alb.ingress.kubernetes.io/target-type: instance
    alb.ingress.kubernetes.io/load-balancer-attributes: routing.http2.enabled=true,idle_timeout.timeout_seconds=600
    alb.ingress.kubernetes.io/tags: Environment=Test
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-east-2:555555555555:certificate/33333333-2222-4444-AAAA-EEEEEEEEEEEE,arn:aws:acm:us-east-2:555555555555:certificate/44444444-3333-5555-BBBB-FFFFFFFFFFFF
    alb.ingress.kubernetes.io/ssl-policy: ELBSecurityPolicy-2016-08
spec:
  backend:
    serviceName: response-503
    servicePort: use-annotation
  rules:
    - http:
        paths:
          - backend:
              serviceName: ssl-redirect
              servicePort: use-annotation
          - backend:
              serviceName: svc-a-host
              servicePort: use-annotation
          - backend:
              serviceName: svc-b-host
              servicePort: use-annotation

Default Action:默认操作:

Set by specifying the serviceName and servicePort directly under spec :通过直接在spec下指定 serviceName 和 servicePort 来设置:

spec:
  backend:
    serviceName: response-503
    servicePort: use-annotation

Routing:路由:

Because I'm using subdomains and paths won't work for me, I simply omitted the path and instead relied on hostname as a condition.因为我使用的是子域并且路径对我不起作用,所以我只是省略了路径,而是依赖主机名作为条件。

metadata:
  alb.ingress.kubernetes.io/actions.svc-a-host: >
      {"type":"forward","forwardConfig":{"targetGroups":[{"serviceName":"svc-a-service","servicePort":80,"weight":100}]}}
  alb.ingress.kubernetes.io/conditions.svc-a-host: >
      [{"field":"host-header","hostHeaderConfig":{"values":["svc-a.example.com"]}}]

End Result:最终结果:

The ALB rules were configured precisely how I wanted them: ALB 规则按照我想要的方式精确配置:

  • default action is a 503 fixed response默认操作是 503 固定响应
  • all http traffic is redirected to https所有 http 流量都被重定向到 https
  • traffic is directed to TargetGroups based on the host header流量根据主机 header 定向到 TargetGroups

AWS EKS now has a notion of IngressGroups so multiple ingresses can share one ingress controller. AWS EKS 现在具有IngressGroups的概念,因此多个入口可以共享一个入口 controller。 See Application load balancing on Amazon EKS请参阅Amazon EKS 上的应用程序负载平衡

To share an application load balancer across multiple ingress resources using IngressGroups

To join an Ingress to an Ingress group, add the following annotation to a Kubernetes Ingress resource specification.

alb.ingress.kubernetes.io/group.name: <my-group>
The group name must be:

63 characters or less in length.

Consist of lower case alphanumeric characters, -, and ., and must start and end with an alphanumeric character.

The controller will automatically merge ingress rules for all Ingresses in the same Ingress group and support them with a single ALB. Most annotations defined on an Ingress only apply to the paths defined by that Ingress. By default, Ingress resources don't belong to any Ingress group.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何加入 ALB 入口组而不是覆盖 EKS 中的现有入口组? - How can I join a ALB ingress group instead of overriding an existing one in EKS? 适用于 EKS 的 AWS ALB(入口控制器)前面的 AWS API 网关 - AWS API Gateway infront of AWS ALB (Ingress Controller) for EKS 即使在 AWS EKS 中删除 Ingress Manifest 后,如何保留 LoadBalancer[ALB]? - How to keep LoadBalancer[ALB] even after we delete Ingress Manifest in AWS EKS? 只有“/”适用于 AWS EKS 中的 NGINX 入口控制器和 ALB - Only the '/' works with NGINX ingress controller and ALB in AWS EKS 503 Service Temporarily Unavailable use EKS ALB Ingress - 503 Service Temporarily Unavailable use EKS ALB Ingress 使用 EKS alb 入口运行状况检查管理的 ALB 前面的 AWS 全球加速器失败 - AWS Global Accelerator in front of ALB managed with EKS alb ingress health checks fail EKS Fargate - 用于没有出站 Internet 访问的私有集群的入口 controller? 不支持 aws-alb-ingress - EKS Fargate - ingress controller for a private cluster with no outbound internet access? aws-alb-ingress not supported 如何使用 AWS ALB 作为入口 Controller 将多个服务 map 到单个入口? - How to map multiple services to a single ingress using AWS ALB as Ingress Controller? 我可以使用AWS自己的ELB证书进行HTTPS / SSL连接吗? - Can I use AWS own ELB certificate for HTTPS/SSL connection? 我们可以在 Nginx-Ingress-Contoller 使用多个 AWS ACM 证书或在 Ingress object 级别使用多个 ACM 证书吗? - Can We use Multiple AWS ACM Certificates at Nginx-Ingress-Contoller OR Multiple ACM certificate at Ingress object level?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM