在Kubernetes中通过Kong Gateway暴露MySQL失败,如何排查解决?
通过Helm Chart安装Kong后,在values.yaml的Stream段配置了两个TCP端口:
stream: - containerPort: 39019 #MongoDB servicePort: 39019 protocol: TCP parameters: - ssl - containerPort: 43576 #MySQL servicePort: 43576 protocol: TCP parameters: - ssl
为两个数据库创建了TCPIngress配置:
MySQL的TCPIngress配置
apiVersion: configuration.konghq.com/v1beta1 kind: TCPIngress metadata: name: tcp-mysql annotations: kubernetes.io/tls-acme: "true" cert-manager.io/cluster-issuer: letsencrypt kubernetes.io/ingress.class: kong konghq.com/plugins: global-file-log spec: tls: - hosts: - s.mytest.domain secretName: s.mytest.domain-certificate rules: - host: s.mytest.domain port: 43576 backend: serviceName: mysql servicePort: 3306
MongoDB的TCPIngress配置
apiVersion: configuration.konghq.com/v1beta1 kind: TCPIngress metadata: name: tcp-mongodb annotations: kubernetes.io/tls-acme: "true" cert-manager.io/cluster-issuer: letsencrypt kubernetes.io/ingress.class: kong konghq.com/plugins: global-file-log spec: tls: - hosts: - s.mytest.domain secretName: s.mytest.domain-certificate rules: - host: s.mytest.domain port: 39019 backend: serviceName: mongodb servicePort: 27017
当前MongoDB可正常通过域名连接,但MySQL无法连接,直接端口转发到MySQL Pod则正常。需要排查并解决该问题。
1. 确认Kong Service的端口暴露
检查Kong的Service是否正确对外暴露了43576端口:
kubectl get svc kong -o yaml
查看spec.ports段,确认存在port: 43576且targetPort: 43576的配置,端口类型应为NodePort或LoadBalancer(根据集群部署方式)。如果缺失,说明Helm配置未生效,重新部署Kong:
helm upgrade kong kong/kong -f values.yaml
2. 验证TCPIngress资源状态
检查Kong是否成功加载了MySQL的TCPIngress配置:
kubectl describe tcpingress tcp-mysql
查看输出中的事件信息,确认是否有Successfully synced to Kong类的提示。如果存在错误(如证书缺失、后端服务不可达),根据提示修复对应问题。
3. 测试Kong到MySQL Service的连通性
进入Kong Pod内部,测试能否访问MySQL Service:
kubectl exec -it <kong-pod-name> -- bash # 使用telnet或nc测试连接 telnet mysql 3306
如果无法连接,检查MySQL Service的标签是否匹配Pod,以及Service的端口配置(spec.ports.port需为3306,targetPort需对应Pod的实际端口)。
4. 检查SSL证书有效性
由于配置了ssl参数,Kong会对该端口流量做SSL终止,需确认证书正常:
kubectl get secret s.mytest.domain-certificate -o yaml
检查data.tls.crt和data.tls.key是否有有效值,且证书未过期。如果证书未生成,查看cert-manager日志排查原因:
kubectl logs -n cert-manager <cert-manager-pod-name>
5. 核对MySQL的SSL配置
MySQL默认可能拒绝SSL连接,需确认其是否开启SSL支持:
- 进入MySQL Pod查看配置文件,或执行
SHOW VARIABLES LIKE '%ssl%';确认SSL状态。 - 如果MySQL未开启SSL,而Kong强制做SSL终止,会导致连接失败。此时可二选一:
- 修改MySQL配置,开启SSL支持;
- 移除Kong Stream配置中MySQL端口的
ssl参数,重新部署Kong。
6. 查看Kong日志定位错误
查看Kong Pod的日志,获取连接失败的具体细节:
kubectl logs <kong-pod-name>
日志中可能包含连接超时、证书错误、协议不匹配等信息,根据日志针对性修复。
内容的提问来源于stack exchange,提问作者Andy Schmitt

