简体   繁体   English

Kubernetes + Socket.io:Pod 客户端 -> LoadBalancer 服务 SSL 问题

[英]Kubernetes + Socket.io: Pod client -> LoadBalancer service SSL issues

I have a socket.io-based node.js deployment on my Kubernetes cluster with a LoadBalancer-type service through Digital Ocean.我在我的 Kubernetes 集群上有一个基于 socket.io 的 node.js 部署,通过 Digital Ocean 使用 LoadBalancer 类型的服务。 The service uses SSL termination using a certificate uploaded to DO.该服务使用上传到 DO 的证书使用 SSL 终止。

I've written a pod which acts as a health check to ensure that clients are still able to connect.我编写了一个 pod,它充当运行状况检查以确保客户端仍然能够连接。 This pod is node.js using the socket.io-client package, and it connects via the public domain name for the service.这个 pod 是使用socket.io-client包的 node.js,它通过服务的公共域名连接。 When I run the container locally, it connects just fine, but when I run the container as a pod in the same cluster as the service, the health check can't connect.当我在本地运行容器时,它连接得很好,但是当我在与服务相同的集群中将容器作为 pod 运行时,运行状况检查无法连接。 When I shell into the pod, or any pod really, and try wget my-socket.domain.com , I get an SSL handshake error "wrong version number".当我进入 pod 或任何真正的 pod 并尝试wget my-socket.domain.com ,我收到 SSL 握手错误“版本号错误”。

Any idea why a client connection from outside the cluster works, a client connection out of the cluster to a normal server works, but a client connection from a pod in the cluster to the public domain name of the service doesn't work?知道为什么来自集群外部的客户端连接有效,集群外到普通服务器的客户端连接有效,但是从集群中的 pod 到服务的公共域名的客户端连接不起作用吗?

You have to set up Ingress Controller to route traffic from a Load-Balancer to a Service.您必须设置入口控制器以将流量从负载均衡器路由到服务。

The flow of traffic looks like this:流量看起来像这样:

INTERNET -> LoadBalancer -> [ Ingress Controller -> Service]

If you want to use SSL:如果要使用 SSL:

You can provision your own SSL certificate and create a Secret to hold it.您可以提供自己的 SSL 证书并创建一个Secret来保存它。 You can then refer to the Secret in an Ingress specification to create an HTTP(S) load balancer that uses the certificate.然后,您可以参考 Ingress 规范中的 Secret 来创建使用该证书的 HTTP(S) 负载平衡器。

You can deploy an ingress controller like nginx using following instruction: ingress-controller .您可以使用以下指令部署像 nginx 这样的入口控制器: ingress-controller

Turns out, the issue is with how kube-proxy handles LoadBalancer-type services and requests to it from inside the cluster.事实证明,问题在于 kube-proxy 如何处理 LoadBalancer 类型的服务以及从集群内部向它发出的请求。 Turns out, when the service is created, it adds iptables entries that causes requests inside the cluster skip the load balancer completely, which becomes an issue when the load balancer also handles SSL termination.事实证明,当服务被创建时,它添加了 iptables 条目,导致集群内部的请求完全跳过负载均衡器,当负载均衡器也处理 SSL 终止时,这成为一个问题。 There is a workaround, which is to add a loadbalancer-hostname annotation which forces all connections to use the load balancer.有一种解决方法,即添加一个loadbalancer-hostname注释,强制所有连接使用负载均衡器。 AWS tends not to have this problem because they automatically apply the workaround to their service configurations, but Digital Ocean does not. AWS 往往没有这个问题,因为他们会自动将变通方法应用于他们的服务配置,但 Digital Ocean 没有。

Here are some more details:以下是更多详细信息:

https://github.com/digitalocean/digitalocean-cloud-controller-manager/blob/master/docs/controllers/services/annotations.md https://github.com/digitalocean/digitalocean-cloud-controller-manager/blob/master/docs/controllers/services/annotations.md

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

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