使用HAProxy Ingress Controller时TLS握手间歇性失败问题排查
解决HAProxy Ingress TCP+TLS端口握手概率性失败问题
我最近在给Node.js应用配置HAProxy Ingress Controller做TLS终止时,碰到了一个挺棘手的概率性问题,折腾了好一阵才找到原因,这里把整个过程和解决方法分享出来:
场景还原
我的环境是这样的:
- Node.js服务有两个端口:8080监听HTTP请求,1935是一个非HTTP的echo服务
- 用HAProxy Ingress实现:把8080映射到443(HTTPS终止),1935映射到1936(TCP+TLS终止)
安装HAProxy Ingress的Helm命令
helm upgrade --install haproxy-ingress incubator/haproxy-ingress \ --namespace test \ -f ./haproxy-ingress-values.yaml \ --version v0.0.27
对应的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
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
证书用的是自签名的,部署完后测试发现了问题。
问题现象
测试443端口的HTTPS服务完全正常,但用echo | openssl s_client -connect "<IP>":1936测试1936的TCP+TLS服务时,大概每3次就会有1次握手失败,错误信息如下:
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) ---
根因分析
排查了好半天,终于发现问题所在:HAProxy的默认统计端口就是1936,哪怕我们没有在配置里开启统计功能,这个端口依然会被HAProxy内部占用。当我们把Ingress的TCP服务映射到1936端口时,就和HAProxy自身的统计端口产生了冲突——请求会随机落到统计端口或者我们的业务端口上,这就是为什么会出现概率性握手失败的情况。
解决方案
有两种可行的解决办法,选哪种都可以:
方案1:修改业务TCP服务的映射端口
直接把haproxy-ingress-values.yaml里的TCP映射端口从1936改成其他未被占用的端口,比如1937:
service: type: LoadBalancer tcp: 1937: "test/simple-server:1935:::test/ingress-cert"
修改后重新执行Helm升级命令即可:
helm upgrade --install haproxy-ingress incubator/haproxy-ingress \ --namespace test \ -f ./haproxy-ingress-values.yaml \ --version v0.0.27
方案2:修改HAProxy的统计端口
在安装时通过配置把HAProxy的统计端口改成其他值,比如5000。需要在haproxy-ingress-values.yaml里添加控制器的统计端口配置:
controller: ingressClass: haproxy replicaCount: 1 stats: port: 5000 service: type: LoadBalancer tcp: 1936: "test/simple-server:1935:::test/ingress-cert" nodeSelector: "kubernetes.io/os": linux defaultBackend: nodeSelector: "kubernetes.io/os": linux
同样,修改后重新执行Helm升级命令生效。
内容的提问来源于stack exchange,提问作者Hans
相关产品推荐
相关产品推荐

