简体   繁体   English

"如何在 GKE 上为 Kubernetes Ingress 强制 SSL"

[英]How to force SSL for Kubernetes Ingress on GKE

Is there a way to force an SSL upgrade for incoming connections on the ingress load-balancer?有没有办法强制对入口负载平衡器上的传入连接进行 SSL 升级? Or if that is not possible with, can I disable port :80?或者,如果这不可能,我可以禁用端口:80 吗? I haven't found a good documentation pages that outlines such an option in the YAML file.我还没有找到一个很好的文档页面来概述 YAML 文件中的此类选项。 Thanks a lot in advance!提前非常感谢!

"

https://github.com/kubernetes/ingress-gce#frontend-https https://github.com/kubernetes/ingress-gce#frontend-https

You can block HTTP through the annotation kubernetes.io/ingress.allow-http: "false" or redirect HTTP to HTTPS by specifying a custom backend.您可以通过注释kubernetes.io/ingress.allow-http: "false"阻止 HTTP 或通过指定自定义后端将 HTTP 重定向到 HTTPS。 Unfortunately GCE doesn't handle redirection or rewriting at the L7 layer directly for you, yet.不幸的是,GCE 还没有直接在 L7 层为您处理重定向或重写。 (see https://github.com/kubernetes/ingress-gce#ingress-cannot-redirect-http-to-https ) (见https://github.com/kubernetes/ingress-gce#ingress-cannot-redirect-http-to-https

Update: GCP now handles redirection rules for load balancers , including HTTP to HTTPS.更新: GCP 现在处理负载均衡器的重定向规则,包括 HTTP 到 HTTPS。 There doesn't appear to be a method to create these through Kubernetes YAML yet.似乎还没有通过 Kubernetes YAML 创建这些的方法。

The annotation has changed:注释已更改:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test
  annotations:
    kubernetes.io/ingress.allow-http: "false"
spec:
...

Here is the annotation change PR: https://github.com/kubernetes/contrib/pull/1462/files这是注释更改 PR: https : //github.com/kubernetes/contrib/pull/1462/files

If you are not bound to the GCLB Ingress Controller you could have a look at the Nginx Ingress Controller .如果您没有绑定到 GCLB 入口控制器,您可以查看Nginx 入口控制器 This controller is different to the builtin one in multiple ways.这个控制器在很多方面不同于内置控制器。 First and foremost you need to deploy and manage one by yourself.首先,您需要自己部署和管理一个。 But if you are willing to do so, you get the benefit of not depending on the GCE LB (20$/month) and getting support for IPv6/websockets.但是,如果您愿意这样做,您将获得不依赖 GCE LB(20 美元/月)并获得对 IPv6/websockets 的支持的好处。

The documentation states:文件指出:

By default the controller redirects (301) to HTTPS if TLS is enabled for that ingress .默认情况下,如果为该入口启用了 TLS,控制器会将 (301) 重定向到 HTTPS。 If you want to disable that behaviour globally, you can use ssl-redirect: "false" in the NGINX config map.如果要全局禁用该行为,可以在 NGINX 配置映射中使用ssl-redirect: "false"

The recently released 0.9.0-beta.3 comes with an additional annotation for explicitly enforcing this redirect:最近发布的0.9.0-beta.3附带了一个额外的注释,用于明确强制执行此重定向:

Force redirect to SSL using the annotation ingress.kubernetes.io/force-ssl-redirect使用注释ingress.kubernetes.io/force-ssl-redirect强制重定向到 SSL

Google has responded to our requests and is testing HTTP->HTTPS SSL redirection on their load balancers. Google 已响应我们的请求,并正在其负载平衡器上测试 HTTP->HTTPS SSL 重定向。 Their latest answer said it should be in Alpha sometime before the end of January 2020.他们的最新回答是,它应该在 2020 年 1 月底之前的某个时间处于 Alpha 状态。

Their comment:他们的评论:

Thank you for your patience on this issue.感谢您对这个问题的耐心等待。 The feature is currently in testing and we expect to enter Alpha phase before the end of January.该功能目前正在测试中,我们预计将在 1 月底之前进入 Alpha 阶段。 Our PM team will have an announcement with more details as we get closer to the Alpha launch.随着我们接近 Alpha 发布,我们的 PM 团队将发布包含更多详细信息的公告。

My fingers are crossed that we'll have a straightforward solution to this very common feature in the near future.我的手指交叉,我们将在不久的将来为这个非常常见的功能提供一个简单的解决方案。


UPDATE (April 2020) :更新(2020 年 4 月)

HTTP(S) rewrites is now a Generally Available feature. HTTP(S) 重写现在是一项普遍可用的功能。 It's still a bit rough around the edges and does not work out-of-the-box with the GCE Ingress Controller unfortunately.不幸的是,它的边缘仍然有点粗糙,并且不能与GCE Ingress Controller一起开箱即用。 But time will tell and hopefully a native solution will appear.但时间会证明一切,希望本机解决方案会出现。

This was already correctly answered by a comment on the accepted answer.对已接受答案的评论已经正确回答了这一点。 But since the comment is buried I missed it several times.但由于评论被埋没了,我错过了好几次。

As of GKE version 1.18.10-gke.600 you can add a k8s frontend config to redirect from http to https.从 GKE 版本 1.18.10-gke.600 开始,您可以添加 k8s 前端配置以从 http 重定向到 https。

https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-features#https_redirect https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-features#https_redirect

apiVersion: networking.gke.io/v1beta1
kind: FrontendConfig
metadata:
  name: ssl-redirect
spec:
  redirectToHttps:
    enabled: true

# add below to ingress
# metadata:
#   annotations:
#     networking.gke.io/v1beta1.FrontendConfig: ssl-redirect

A quick update.快速更新。 Here 这里

Now a FrontEndConfig can be make to configure the ingress.现在可以使用 FrontEndConfig 来配置入口。 Hopes it helps.希望它有帮助。

Example:例子:

apiVersion: networking.gke.io/v1beta1
kind: FrontendConfig
metadata:
  name: my-frontend-config
spec:
  redirectToHttps:
    enabled: true
    responseCodeName: 301

You'll need to make sure that your load balancer supports HTTP and HTTPS您需要确保您的负载均衡器支持 HTTP 和 HTTPS

Worked on this for a long time.在这方面工作了很长时间。 In case anyone isn't clear on the post above.如果有人在上面的帖子中不清楚。 You would rebuild your ingress with annotation -- kubernetes.io/ingress.allow-http: "false” -- Then delete your ingress and redeploy. The annotation will have the ingress only create a LB for 443, instead of both 443 and 80.您将使用注释重建您的入口 -- kubernetes.io/ingress.allow-http: "false" -- 然后删除您的入口并重新部署。该注释将使入口仅为 443 创建一个 LB,而不是 443 和 80 .

Then you do a compute HTTP LB, not one for GKE.然后你做一个计算 HTTP LB,而不是一个 GKE。

Gui directions: Create a load balancer and choose HTTP(S) Load Balancing -- Start configuration. Gui 说明:创建负载均衡器并选择 HTTP(S) 负载均衡 -- 开始配置。

choose - From Internet to my VMs and continue选择 - 从 Internet 到我的 VM 并继续

Choose a name for the LB为 LB 选择一个名称

leave the backend configuration blank.将后端配置留空。

Under Host and path rules, select Advanced host and path rules with the action set to Redirect the client to different host/path.在主机和路径规则下,选择高级主机和路径规则,并将操作设置为将客户端重定向到不同的主机/路径。 Leave the Host redirect field blank.将主机重定向字段留空。 Select Prefix Redirect and leave the Path value blank.选择前缀重定向并将路径值留空。 Chose the redirect response code as 308. Tick the Enable box for HTTPS redirect.选择重定向响应代码为 308。勾选启用 HTTPS 重定向框。

For the Frontend configuration, leave http and port 80, for ip address select the static IP address being used for your GKE ingress.对于前端配置,保留 http 和端口 80,对于 ip 地址,选择用于 GKE 入口的静态 IP 地址。

Create this LB.创建此 LB。

You will now have all http traffic go to this and 308 redirect to your https ingress for GKE.您现在将让所有 http 流量都流向这里,并且 308 重定向到 GKE 的 https 入口。 Super simple config setup and works well.超级简单的配置设置并且运行良好。

Note: If you just try to delete the port 80 LB that GKE makes (not doing the annotation change and rebuilding the ingress) and then adding the new redirect compute LB it does work, but you will start to see error messages on your Ingress saying error 400 invalid value for field 'resource.ipAddress " " is in use and would result in a conflict, invalid.注意:如果您只是尝试删除 GKE 生成的端口 80 LB(不进行注释更改并重建入口),然后添加新的重定向计算 LB 它确实有效,但您将开始在 Ingress 上看到错误消息说错误 400 字段“resource.ipAddress”的无效值正在使用中,会导致冲突,无效。 It is trying to spin up the port 80 LB and can't because you already have an LB on port 80 using the same IP.它正在尝试启动端口 80 LB 并且不能,因为您已经在端口 80 上使用相同的 IP 有一个 LB。 It does work but the error is annoying and GKE keeps trying to build it (I think).它确实有效,但错误很烦人,GKE 一直在尝试构建它(我认为)。

You can disable HTTP on your cluster (note that you'll need to recreate your cluster for this change to be applied on the load balancer) and then set HTTP-to-HTTPS redirect by creating an additional load balancer on the same IP address.您可以在集群上禁用 HTTP (请注意,您需要重新创建集群才能将此更改应用于负载均衡器),然后通过在同一 IP 地址上创建额外的负载均衡器来设置 HTTP 到 HTTPS 重定向

I spend couple of hours on the same question, and ended up doing what I've just described.我在同一个问题上花了几个小时,最后做了我刚刚描述的事情。 It works perfectly.它完美地工作。

Redirecting to HTTPS in Kubernetes is somewhat complicated.在 Kubernetes 中重定向到 HTTPS 有点复杂。 In my experience, you'll probably want to use an ingress controller such as Ambassador or ingress-nginx to control routing to your services, as opposed to having your load balancer route directly to your services.根据我的经验,您可能希望使用诸如Ambassadoringress-nginx 之类的入口控制器来控制到您的服务的路由,而不是让您的负载均衡器直接路由到您的服务。

Assuming you're using an ingress controller, then:假设您使用的是入口控制器,则:

  • If you're terminating TLS at the external load balancer and the LB is running in L7 mode (ie, HTTP/HTTPS), then your ingress controller needs to use X-Forwarded-Proto , and issue a redirect accordingly.如果您在外部负载均衡器上终止 TLS 并且 LB 以 L7 模式(即 HTTP/HTTPS)运行,那么您的入口控制器需要使用X-Forwarded-Proto ,并相应地发出重定向。
  • If you're terminating TLS at the external load balancer and the LB is running in TCP/L4 mode, then your ingress controller needs to use the PROXY protocol to do the redirect.如果您在外部负载均衡器上终止 TLS 并且 LB 以 TCP/L4 模式运行,那么您的入口控制器需要使用代理协议来执行重定向。
  • You can also terminate TLS directly in your ingress controller, in which case it has all the necessary information to do the redirect.您还可以直接在入口控制器中终止 TLS,在这种情况下,它具有执行重定向所需的所有信息。

Here's a tutorial on how to do this in Ambassador.这是有关如何在大使中执行此操作的教程

Thanks to the comment of @Andrej Palicka and according to the page he provided: https:\/\/cloud.google.com\/kubernetes-engine\/docs\/how-to\/ingress-features#https_redirect<\/a> now I have an updated and working solution.感谢@Andrej Palicka 的评论并根据他提供的页面: https<\/a> :\/\/cloud.google.com\/kubernetes-engine\/docs\/how-to\/ingress-features#https_redirect 现在我有了一个更新且有效的解决方案。

First we need to define a FrontendConfig<\/strong> resource and then we need to tell the Ingress<\/strong> resource to use this FrontendConfig<\/strong> .首先我们需要定义一个FrontendConfig<\/strong>资源,然后我们需要告诉Ingress<\/strong>资源使用这个FrontendConfig<\/strong> 。

Example:例子:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-app-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: myapp-prd
    networking.gke.io/managed-certificates: managed-cert
    kubernetes.io/ingress.class: "gce"
    networking.gke.io/v1beta1.FrontendConfig: myapp-frontend-config
spec:
  defaultBackend:
    service:
      name: myapp-app-service
      port:
        number: 80
---
apiVersion: networking.gke.io/v1beta1
kind: FrontendConfig
metadata:
  name: myapp-frontend-config
spec:
  redirectToHttps:
    enabled: true
    responseCodeName: MOVED_PERMANENTLY_DEFAULT

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM