[英]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 监听器规则中,它显示:
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 规则按照我想要的方式精确配置:
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.