在Minikube中配置LoadBalancer以直接访问SQL Server
Minikube部署SQL Server连接问题排查
问题背景
我在本地使用Minikube部署SQL Server,已配置ClusterIP和LoadBalancer Service,但无法从外部建立连接。尝试了多种地址组合均失败,错误提示Name or service not known,推测是网络层面的问题。
配置文件
mssql-depl.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: mssql-depl spec: replicas: 1 selector: matchLabels: app: mssql template: metadata: labels: app: mssql spec: containers: - name: mssql image: mcr.microsoft.com/mssql/server:2017-latest ports: - containerPort: 1433 env: - name: MSSQL_PID value: "Express" - name: ACCEPT_EULA value: "Y" - name: SA_PASSWORD valueFrom: secretKeyRef: name: mssql key: SA_PASSWORD volumeMounts: - mountPath: /var/opt/mssql/data name: mssqldb volumes: - name: mssqldb persistentVolumeClaim: claimName: mssql-claim --- apiVersion: v1 kind: Service metadata: name: mssql-clusterip-srv spec: type: ClusterIP selector: app: mssql ports: - name: mssql protocol: TCP port: 1433 targetPort: 1433 --- apiVersion: v1 kind: Service metadata: name: mssql-loadbalancer spec: type: LoadBalancer selector: app: mssql ports: - name: mssql protocol: TCP port: 1433 targetPort: 1433
local-pvc.yaml
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mssql-claim spec: resources: requests: storage: 200Mi volumeMode: Filesystem accessModes: - ReadWriteMany
执行结果
执行kubectl apply -f msql-depl.yaml后,运行kubectl get services得到以下输出:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE commands-clusterip-srv ClusterIP 10.96.28.141 <none> 80/TCP 20h kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2d21h mssql-clusterip-srv ClusterIP 10.105.217.207 <none> 1433/TCP 29s mssql-loadbalancer LoadBalancer 10.107.63.199 <pending> 1433:31681/TCP 28s platforms-clusterip-srv ClusterIP 10.98.35.159 <none> 80/TCP 44h platformservice-srv NodePort 10.104.221.184 <none> 80:30201/TCP 2d21h
运行minikube ip返回192.168.59.100,尝试过以下地址均连接失败:
192.168.59.100:1433localhost:1433localhost:31681192.168.59.100:3168110.107.63.199:143310.107.63.199:31681
错误详情
Microsoft.Data.SqlClient.SqlException (0x80131904): 建立与 SQL Server 的连接时出现与网络相关的或特定于实例的错误。找不到服务器或无法访问服务器。请验证实例名称是否正确,并且 SQL Server 配置为允许远程连接。 (provider: TCP Provider, error: 35 - 捕获到内部异常) ---> System.Net.Sockets.SocketException (00000005, 0xFFFDFFFF): Name or service not known at System.Net.Dns.GetHostEntryOrAddressesCore(String hostName, Boolean justAddresses, AddressFamily addressFamily, Int64 startingTimestamp) at System.Net.Dns.GetHostAddresses(String hostNameOrAddress, AddressFamily family) at Microsoft.Data.SqlClient.SNI.SNICommon.GetDnsIpAddresses(String serverName) at Microsoft.Data.SqlClient.SNI.SNITCPHandle.Connect(String serverName, Int32 port, TimeSpan timeout, Boolean isInfiniteTimeout, SqlConnectionIPAddressPreference ipPreference, String cachedFQDN, SQLDNSInfo& pendingDNSInfo) at Microsoft.Data.SqlClient.SNI.SNITCPHandle..ctor(String serverName, Int32 port, Int64 timerExpire, Boolean parallel, SqlConnectionIPAddressPreference ipPreference, String cachedFQDN, SQLDNSInfo& pendingDNSInfo, Boolean tlsFirst, String hostNameInCertificate, String serverCertificateFilename) at Microsoft.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) at Microsoft.Data.SqlClient.TdsParser.Connect(ServerInfo serverInfo, SqlInternalConnectionTds connHandler, Boolean ignoreSniOpenTimeout, Int64 timerExpire, SqlConnectionString connectionOptions, Boolean withFailover) at Microsoft.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean ignoreSniOpenTimeout, TimeoutTimer timeout, Boolean withFailover) at Microsoft.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString connectionOptions, SqlCredential credential, TimeoutTimer timeout) at Microsoft.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(TimeoutTimer timeout, SqlConnectionString connectionOptions, SqlCredential credential, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance) at Microsoft.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, SqlCredential credential, Object providerInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString userOptions, SessionData reconnectSessionData, Boolean applyTransientFaultHandling, String accessToken, DbConnectionPool pool) at Microsoft.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions) at Microsoft.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions) at Microsoft.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection) at Microsoft.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection) at Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection) at Microsoft.Data.ProviderBase.DbConnectionPool.WaitForPendingOpen() --- End of stack trace from previous location --- at Microsoft.Data.SqlClient.SqlRetryLogicProvider.ExecuteAsync(Object sender, Func`1 function, CancellationToken cancellationToken) at Microsoft.Data.SqlClient.SqlRetryLogicProvider.ExecuteAsync(Object sender, Func`1 function, CancellationToken cancellationToken) at Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection.ReliableSqlConnection.<>c__DisplayClass30_0.<<OpenAsync>b__0>d.MoveNext() in /_/src/Microsoft.SqlTools.ManagedBatchParser/ReliableConnection/ReliableSqlConnection.cs:line 319 --- End of stack trace from previous location --- at Microsoft.SqlTools.ServiceLayer.Connection.ConnectionService.TryOpenConnection(ConnectionInfo connectionInfo, ConnectParams connectionParams) in /_/src/Microsoft.SqlTools.ServiceLayer/Connection/ConnectionService.cs:line 712 ClientConnectionId:00000000-0000-0000-0000-000000000000
排查步骤与解决方案
1. 正确暴露Minikube LoadBalancer服务
Minikube没有原生LoadBalancer支持,需通过minikube tunnel分配外部IP:
- 打开新终端执行
minikube tunnel并保持运行 - 重新执行
kubectl get services,此时mssql-loadbalancer会获得有效EXTERNAL-IP,使用该IP+1433端口连接
2. 验证Pod运行状态
执行kubectl get pods确认mssql-depl-xxx状态为Running:
- 若Pod未启动,执行
kubectl logs mssql-depl-xxx查看日志,排查PVC绑定失败、SA密码不符合复杂度要求等问题
3. 检查容器内SQL Server状态
进入容器验证服务运行情况:
kubectl exec -it mssql-depl-xxx -- /bin/bash # 查看版本 /opt/mssql/bin/sqlservr --version # 检查进程状态 ps aux | grep sqlservr
4. 测试集群内部连接
临时启动测试Pod验证集群内服务可用性:
kubectl run -it --rm --image=mcr.microsoft.com/mssql-tools:latest sqlcmd
进入容器后执行连接命令:
sqlcmd -S mssql-clusterip-srv,1433 -U SA -P "<你的SA密码>"
若能连接,说明集群内服务正常,问题出在外部网络暴露环节
5. 检查端口与防火墙
- 用
telnet 192.168.59.100 31681或nc -zv 192.168.59.100 31681测试NodePort端口是否可达 - 确认本地防火墙未阻止31681或1433端口
内容的提问来源于stack exchange,提问作者Ian Tunbridge
相关产品推荐
相关产品推荐

