Kubernetes中.NET微服务Pod连接本地外部SQL数据库失败求助
针对你遇到的"A connection was successfully established with the server, but then an error occurred during the pre-login handshake"错误,以下是逐步排查和解决的方法:
1. 修复连接字符串拼写错误
你的连接字符串中TrustServerCertficate=True存在拼写错误,正确参数名是TrustServerCertificate=True(少了一个字母i)。这个错误会导致证书信任配置不生效,进而引发预登录握手的SSL相关问题。修正后的连接字符串:
{ "ConnectionStrings": { "con": "data source=DB_name; database=admin_table; user id=admin; pwd=admin; Pooling=true;Max Pool Size=500;timeout=40000; TrustServerCertificate=True; Encrypt=False" }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*" }
2. 排除数据库地址的代理拦截
你的Pod配置了HTTP_PROXY和HTTPS_PROXY,但SQL Server连接基于TCP协议,.NET的SqlClient会默认继承系统代理设置,导致SQL连接请求被代理拦截。需要添加NO_PROXY环境变量,将数据库的主机名和IP排除在代理之外:
修改Deployment的containers.env部分:
containers: - name: masterapi image: repo/mpsaps-masters:v1.14 env: - name: HTTP_PROXY value: http://proxy-details - name: HTTPS_PROXY value: http://proxy-detail - name: NO_PROXY value: "DB_name,hostip" # 替换为你的数据库主机名和实际IP
3. 验证hostAliases配置是否生效
进入Pod内部,测试数据库主机名的解析是否正确:
kubectl exec -it <你的master-api-pod名称> -- ping DB_name
如果ping的结果不是你配置的hostip,检查Deployment中hostAliases的缩进是否正确(必须和containers同级,属于spec.template.spec下的配置),或者确认连接字符串中的DB_name和hostAliases里的hostname完全一致。
4. 检查SQL Server和防火墙配置
- 确认SQL Server已启用TCP/IP协议:打开SQL Server配置管理器,在"SQL Server网络配置"中启用TCP/IP,并确保监听端口为1433(如果端口非默认,连接字符串需明确指定,比如
data source=DB_name,1434;)。 - 检查本地防火墙规则:允许K8s集群所有节点的IP访问SQL Server的监听端口(默认1433)。
- 确认SQL登录账号
admin允许远程登录,且拥有admin_table数据库的访问权限。
5. 查看Pod日志获取更详细异常
执行以下命令查看Pod的详细日志,定位内部异常的具体原因:
kubectl logs <你的master-api-pod名称>
日志中可能会包含更具体的错误信息(比如SSL握手失败的细节、代理返回的错误等),帮助进一步排查。
内容的提问来源于stack exchange,提问作者Anu Pathania

