如何构建具有中央证书和身份验证管理的入口控制器
我想以集中管理的安全方式将 EKS 中的一些 Web 应用程序公开到互联网。
在 AWS 中,使用 ALB 很好,因为它允许您终止 TLS 并使用 Cognito 添加身份验证。 (参见此处)
要配置 ALB 并将其连接到应用程序,请使用 aws-load-balancer-controller。 它工作正常,但它需要每个应用程序/入口配置一个新的 ALB:
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/tags: Environment=test,Project=cognito
external-dns.alpha.kubernetes.io/hostname: sample.${COK_MY_DOMAIN}
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/auth-type: cognito
alb.ingress.kubernetes.io/auth-scope: openid
alb.ingress.kubernetes.io/auth-session-timeout: '3600'
alb.ingress.kubernetes.io/auth-session-cookie: AWSELBAuthSessionCookie
alb.ingress.kubernetes.io/auth-on-unauthenticated-request: authenticate
alb.ingress.kubernetes.io/auth-idp-cognito: '{"UserPoolArn": "$(aws cognito-idp describe-user-pool --user-pool-id $COK_COGNITO_USER_POOL_ID --region $COK_AWS_REGION --query 'UserPool.Arn' --output text)","UserPoolClientId":"${COK_COGNITO_USER_POOL_CLIENT_ID}","UserPoolDomain":"${COK_COGNITO_DOMAIN}.auth.${COK_AWS_REGION}.amazoncognito.com"}'
alb.ingress.kubernetes.io/certificate-arn: $COK_ACM_CERT_ARN
alb.ingress.kubernetes.io/target-type: 'ip'
我希望有一个中央定义良好的 ALB,并且所有应用程序都不需要再关心这一点。
我的想法是拥有一个常规的 nginx-ingress-controller 并通过中央 ALB 公开它。
现在的问题是:如何将 ALB 连接到 nginx 控制器?
一种方法是手动配置 ALB 并手动构建目标组,这感觉不是一个稳定的解决方案。
另一种方法是使用 aws-load-balancer-controller 连接 nginx。然而在这种情况下,nginx 似乎无法发布正确的负载均衡器地址,并且 external-dns 将输入错误的 DNS 记录。 (不幸的是,通常的入口中似乎没有 --publish-ingress 选项像 nginx 或 traefik 这样的控制器。)
问题:
- 有没有办法让 nginx-ingress-controller 提供正确的地址?
- 是否有更简单的方法来组合两个入口控制器?
I want to expose a few webapps in EKS to the internet in a centrally managed secure way.
In AWS, using an ALB is nice, as it for example allows you to terminate TLS and add authentication using Cognito. (see here)
To provision an ALB and connect it to the application there is the aws-load-balancer-controller.
It works fine, but it requires for each and every app/ingress to configure a new ALB:
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/tags: Environment=test,Project=cognito
external-dns.alpha.kubernetes.io/hostname: sample.${COK_MY_DOMAIN}
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/auth-type: cognito
alb.ingress.kubernetes.io/auth-scope: openid
alb.ingress.kubernetes.io/auth-session-timeout: '3600'
alb.ingress.kubernetes.io/auth-session-cookie: AWSELBAuthSessionCookie
alb.ingress.kubernetes.io/auth-on-unauthenticated-request: authenticate
alb.ingress.kubernetes.io/auth-idp-cognito: '{"UserPoolArn": "$(aws cognito-idp describe-user-pool --user-pool-id $COK_COGNITO_USER_POOL_ID --region $COK_AWS_REGION --query 'UserPool.Arn' --output text)","UserPoolClientId":"${COK_COGNITO_USER_POOL_CLIENT_ID}","UserPoolDomain":"${COK_COGNITO_DOMAIN}.auth.${COK_AWS_REGION}.amazoncognito.com"}'
alb.ingress.kubernetes.io/certificate-arn: $COK_ACM_CERT_ARN
alb.ingress.kubernetes.io/target-type: 'ip'
I would love to have one central well defined ALB and all the application do not need to care about this anymore.
My idea was having a regular nginx-ingress-controller and expose it via a central ALB.
Now the question is: How do I connect the ALB to the nginx-controller?
One way would be manually configuring the ALB and build the target group by hand, which does not feel like a stable solution.
Another way would be using aws-load-balancer-controller to connect the nginx. In that case however nginx seems not to be able to publish the correct loadbalancer address and external-dns will enter the wrong DNS records. (Unfortunately there seems to be no --publish-ingress option in usual ingress controllers like nginx or traefik.)
Question:
- Is there a way to make the nginx-ingress-controller provide the correct address?
- Is there maybe an easier way that combining two ingress controllers?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我想我找到了一个很好的解决方案。
我使用 terraform 设置环境。
设置完 alb 入口控制器后,我可以创建一个合适的入口对象,等待 ALB 启动,使用 terraform 提取 ALB 的地址并使用
publish-status-address
告诉 nginx将该地址准确地发布到其所有入口:这有点奇怪,因为它引入了类似循环依赖的东西,但入口只是等待 nginx 最终启动并且一切正常。
此解决方案与 --publish-ingress 选项不完全相同它将无法适应ALB地址的任何变化。 - 幸运的是,我不希望该地址发生变化,所以我对这个解决方案很满意。
I think I found a good solution.
I set up my environment using terraform.
After I set up the alb ingress controller, I can create a suitable ingress object, wait until the ALB is up, use terraform to extract the address of the ALB and use
publish-status-address
to tell nginx to publish exactly that address to all its ingresses:It is a bit weird, as it introduces something like a circular dependency, but the ingress simply waits until nginx is finally up and all is well.
This solution in not exactly the same as the --publish-ingress option as it will not be able to adapt to any changes of the ALB address. - Luckily I don't expect that address to change, so I'm fine with that solution.
您可以使用两个入口控制器来实现此目的。 ALB 入口控制器将公开暴露的端点并将流量路由到作为其后端的 nginx 入口控制器。然后配置 nginx 入口控制器来管理应用程序流量的入口。
You can achieve this with two ingress controllers. The ALB ingress controller will hand the publicly exposed endpoint and route traffic to the nginx ingress controller as its backend. Then you configure your nginx ingress controller for managing ingress of application traffic.