簡體   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?

我有多個服務需要暴露在互聯網上,但我想為它們使用一個 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 ),但我還沒有找到關於如何實現這一點的明確解釋。

這是設置:

我有 service- a.example.com -and- service-b.example.com。 他們每個人在 Amazon Certificate Manager 中都有自己的證書。

在 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

每個服務都有自己的入口 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

HTTP 到 HTTPS 重定向按預期工作。

但是 - 我的兩個應用程序之間沒有區別,負載均衡器能夠知道發往 service-a.example.com 和 service-b.example.com 的流量應該路由到兩個不同的目標組。

在控制台的 HTTP:443 監聽器規則中,它顯示:

  1. IF Path is /* THEN Forward to ServiceATargetGroup
  2. IF Path is /* THEN Return fixed 503
  3. IF Path is /* THEN Forward to ServiceBTargetGroup
  4. IF Path is /* THEN Return fixed 503
  5. IF 請求否則未路由 THEN 返回固定 404

所以這里的重要問題是:應該如何定義入口以強制將發往 service-a.example.com 的流量發送到 ServiceATargetGroup - 並將發往 service-b.example.com 的流量發送到 ServiceBargetGroup?

其次,我需要“否則不路由”來返回 503 而不是 404。我希望這只會在規則中出現一次(被合並) - 但它是為每個入口創建的。 我的 yaml 應該如何構建以實現這一目標?

我最終想通了——所以對於其他偶然發現這篇文章的人來說,我是這樣解決的:

訣竅不是依賴於 Ingress 對象之間的合並。 是的,它可以處理一定程度的合並,但是作為 TargetGroups 的 Services 和作為 ALB 的 Ingress 之間並沒有真正的一對一關系。 因此,您必須非常謹慎並了解每個 Ingress object 中的內容。

一旦我將所有入口合並到一個 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

默認操作:

通過直接在spec下指定 serviceName 和 servicePort 來設置:

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

路由:

因為我使用的是子域並且路徑對我不起作用,所以我只是省略了路徑,而是依賴主機名作為條件。

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"]}}]

最終結果:

ALB 規則按照我想要的方式精確配置:

  • 默認操作是 503 固定響應
  • 所有 http 流量都被重定向到 https
  • 流量根據主機 header 定向到 TargetGroups

AWS EKS 現在具有IngressGroups的概念,因此多個入口可以共享一個入口 controller。 請參閱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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM