简体   繁体   English

使用 HAProxy 入口控制器时,TLS 握手间歇性失败

[英]TLS handshake fails intermittently when using HAProxy Ingress Controller

I'm using HAProxy Ingress Controller ( https://github.com/helm/charts/tree/master/incubator/haproxy-ingress ) for TLS-termination for my app.我正在使用 HAProxy Ingress Controller ( https://github.com/helm/charts/tree/master/incubator/haproxy-ingress ) 为我的应用程序终止 TLS。 I have a simple Node.JS server listening on 8080 for HTTP, and 1935 as a simple echo server (not HTTP).我有一个简单的 Node.JS 服务器在 8080 上侦听 HTTP,而 1935 作为一个简单的回显服务器(不是 HTTP)。
And I use HAProxy Ingress controller to wrap the ports in TLS.我使用 HAProxy Ingress 控制器将端口封装在 TLS 中。 (8080 -> 443 (HTTPS), 1935 -> 1936 (TCP + TLS)) (8080 -> 443 (HTTPS), 1935 -> 1936 (TCP + TLS))
I installed HAProxy Ingress Controller with我安装了 HAProxy 入口控制器

helm upgrade --install haproxy-ingress incubator/haproxy-ingress \
   --namespace test \
  -f ./haproxy-ingress-values.yaml \
  --version v0.0.27

, where the content of haproxy-ingress-values.yaml is ,其中haproxy-ingress-values.yaml


controller:
  ingressClass: haproxy
  replicaCount: 1
  service:
    type: LoadBalancer
  tcp:
    1936: "test/simple-server:1935:::test/ingress-cert"
  nodeSelector:
    "kubernetes.io/os": linux
defaultBackend:
  nodeSelector:
    "kubernetes.io/os": linux

And here's my ingress:这是我的入口:


apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress
  annotations:
    kubernetes.io/ingress.class: "haproxy"
spec:
  tls:
  - hosts:
    secretName: ingress-cert
  rules:
    - http:
        paths:
        - path: /
          backend:
            serviceName: "simple-server"
            servicePort: 8080

The cert is self-signed.证书是自签名的。 If I test the TLS handshake with如果我测试 TLS 握手

echo | openssl s_client -connect "<IP>":1936

Sometimes (about 1/3 of the times) it fails with有时(大约 1/3 的次数)它会失败

CONNECTED(00000005)
139828847829440:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:../ssl/record/ssl3_record.c:332:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 5 bytes and written 316 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---

The same problem doesn't happen for 443 port. 443 端口不会发生同样的问题。
See here for the details of the settings to reproduce the problem.有关重现问题的设置的详细信息,请参见此处

[edit] [编辑]
As pointed out by @JoaoMorais, it's because the default statistic port is 1936. Although I didn't turn on statistics, it seems like it still interferes with the behavior.正如@JoaoMorais 所指出的,这是因为默认的统计端口是 1936。虽然我没有打开统计,但它似乎仍然干扰了行为。
There're two solutions that work for me.有两种解决方案对我有用。

  • Change my service's 1936 port to another将我的服务的 1936 端口更改为另一个
  • Change the stats port by adding values like below when installing the haproxy-ingress chart.在安装 haproxy-ingress 图表时,通过添加如下值来更改统计端口。
controller:
  stats:
    port: 5000

HAProxy by default allows to reuse the same port number across the same or other frontend/listen sections and also across other haproxy process.默认情况下,HAProxy 允许在相同或其他前端/侦听部分以及其他 haproxy 进程中重用相同的端口号。 This can be changed adding noreuseport in the global section.这可以更改在global部分添加noreuseport

The default HAProxy Ingress configuration uses port number 1936 to expose stats.默认的 HAProxy Ingress 配置使用端口号1936来公开统计信息。 If such port number is reused by eg a tcp proxy, the incoming requests will be distributed between both frontends - sometimes your service will be called, sometimes the stats page.如果这样的端口号被例如 tcp 代理重用,传入的请求将在两个前端之间分配 - 有时会调用您的服务,有时会调用统计信息页面。 Changing the tcp proxy or the stats page (doc here ) to another port should solve the issue.将 tcp 代理或统计页面( 此处为文档)更改为另一个端口应该可以解决问题。

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

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