Connecting to Kubernetes SQL Server pod. Testing locally. Internal connection fatal error

79 views Asked by At

I have this yaml file for my SQL Server deployment. I can access the database server and query the master database from my host machine. I can connect using localhost,30000 in SSMS.

Then I created an ASP.NET Core Web API using .NET 8 and I've created a temporary method just to test it from my host machine. Why can I open the connection and get the SQL Server version but not execute a simple query? I'm receiving an error

Internal connection fatal error

Here is the Web API WeatherforecastController method:

    [HttpGet("TestDatabaseConnection")]
    public IActionResult TestDatabaseConnection(string serverName = "localhost,14344", string databaseName = "master", string userId = "sa", string password = "P@ssw0rd123")
    {
        string connectionString = $"Server={serverName};Database={databaseName};User Id={userId};Password={password};";
        string queryString = "SELECT TOP 1 * FROM sys.databases;";

        _logger.LogInformation("Connection String: {0}", connectionString);
        _logger.LogInformation("Query String: {0}", queryString);

        try
        {
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                _logger.LogInformation("Create new SqlCommand");
                using (var command = new SqlCommand(queryString, connection)) 
                {
                    try
                    {
                        CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;
                        CultureInfo.CurrentUICulture = CultureInfo.InvariantCulture;
                        _logger.LogInformation("Open connection");
                        connection.Open();

                        // Add a simple query execution here
                        using (SqlCommand versionCommand = new SqlCommand("SELECT @@VERSION", connection)) 
                        {
                            string version = (string)versionCommand.ExecuteScalar();
                            _logger.LogInformation("SQL Server Version: {0}", version);
                        }

                        _logger.LogInformation("Execute reader");

                        using (SqlDataReader reader = command.ExecuteReader()) 
                        {
                            _logger.LogInformation("Read");

                            while (reader.Read())
                            {
                                Console.WriteLine(String.Format("{0}", reader[0]));
                            }

                            _logger.LogInformation("Close connection");

                            reader.Close();
                        }

                        return Ok("Database Connection Successful");
                    }
                    catch (Exception ex)
                    {
                        return Problem("Database Connection Failed: " + ex.Message);
                    }
                }
            }
        }
        catch (Exception ex)
        {
            return Problem("Database Connection Failed[SqlConnection]: " + ex.Message);
        }
}

Here is my yaml file.

apiVersion: apps/v1
kind: StatefulSet
metadata:
 name: accsol-sqlserver # name of the StatefulSet workload, the SQL Server instance name is derived from this. We suggest to keep this name same as the .spec.template.metadata.labels, .spec.selector.matchLabels and .spec.serviceName to avoid confusion.
spec:
 serviceName: "accsol-sqlserver" # serviceName is the name of the service that governs this StatefulSet. This service must exist before the StatefulSet, and is responsible for the network identity of the set.
 replicas: 1 # only one pod, with one SQL Server instance deployed.
 selector:
  matchLabels:
   app: accsol-sqlserver  # this has to be the same as .spec.template.metadata.labels
 template:
  metadata:
   labels:
    app: accsol-sqlserver # this has to be the same as .spec.selector.matchLabels, as documented [here](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/):
  spec:
   securityContext:
     fsGroup: 10001
   containers:
   - name: accsol-sqlserver # container name within the pod.
     image: solomiosisante/accsol-sqlserver:0.1.0
     ports:
     - containerPort: 1433
       name: tcpsql
     env:
     - name: ENABLE_HADR
       value: "1"
     - name: AGENT_ENABLED
       value: "1"
     - name: MSSQL_PID
       value: "Express"
     - name: ACCEPT_EULA
       value: "Y"
     - name: MSSQL_SA_PASSWORD
       valueFrom:
         secretKeyRef:
           name: accsol-sqlserver
           key: MSSQL_SA_PASSWORD
     volumeMounts:
     - name: accsol-sqlserver-claim
       mountPath: "/Data"
 volumeClaimTemplates:
   - metadata:
      name: accsol-sqlserver-claim
     spec:
      accessModes:
      - ReadWriteOnce
      resources:
       requests:
        storage: 1Gi
apiVersion: v1
kind: Service
metadata:
  name: accsol-sqlserver-clusterip-srv
spec:
  type: ClusterIP
  selector:
    app: accsol-sqlserver
  ports:
  - name: accsol-sqlserver
    protocol: TCP
    port: 14344
    targetPort: 1433
apiVersion: v1
kind: Service
metadata:
  name: accsol-sqlserver-service
spec:
  selector:
    app: accsol-sqlserver
  ports:
  - protocol: TCP
    port: 1433
    targetPort: 1433
    nodePort: 30000  # this will expose the service on your host at port 30000
  type: NodePort
apiVersion: v1
kind: Service
metadata:
  name: accsol-sqlserver-loadbalancer
spec:
  type: LoadBalancer
  selector:
    app: accsol-sqlserver
  ports:
  - protocol: TCP
    port: 14344
    targetPort: 1433

enter image description here

1

There are 1 answers

0
Sol On

I got my answer from the very bottom of this github page InvariantGlobalization

Turns out I just need to disable InvariantGlobalization in the project file.