0

Notes: Slow network performance in Docker container does not address either of my issues. Very slow network performance of Docker containers with host's network might be related, but the one response there is definitely not the problem.

I am running the windows server 2016 integrated version of docker, with the microsoft/mssql-server-windows-developer image. (windows containers, linux is not an option for the ultimate purpose). My goal is to use this image for a temporary SQL server for repeated acceptance test runs.

As of now, everything works as I need it to, except for performance. As a measurement of performance I have a set of scripts (invoked by powershell) that will setup a database with tables, schema, role, etc and some small amount of initial data.

When I share a drive with the host system, I can connect to the container and run this powershell script inside the container. It takes 30 seconds to complete. No errors, and when I inspect the database with SSMS, it is all correct.

When I run the script from the host machine (via the exposed port 1433), the script takes about 6000 percent longer. (i.e. about 30 minutes.) However, it also runs correctly and produces correct results.

The above measurements were made using the default "nat" network, with the container run with -p 1433:1433. My main question is, how can I get remotely reasonable performance when running my script from the host system? (Ultimately running anything under test from within the container is not an option. Also ultimately this same performance issue must be resolved in order for our container deployment plans to be realistic.)

Thanks!

What I have tried so far.

First, there is no internal CPU or memory performance issues from within the container. So I have already experimented with the --cpus related options and -m options and given the container far more resources than it really needed. The internal performance does not change. It's very fast that way regardless of any of these settings.

I have also investigate creating a "transparent" network. Using the powershell cmdlet New-ContainerNetwork, I created a transparent network, and started the container with the "--net Trans" switch. I got a valid DHCP address from the external network and had connectivity to the internet and other domain machines on the intranet. Using netstat -a, (and powershell Get-WMIObject win32_service) I was able to determine that the MSSQLSERVER instance was running and listening on port 1433. I installed telnet inside the container, and could make a connect to that port using the command "telnet [ipaddressfromipconfig] 1433".

From a host command prompt, I could ping the containers ip address and get replies, but the telnet command (above) would not connect from the host. So naturally when I tried SSMS it would not connect either. The -P, or -p 1433:1433 port mapping option is not supported with a transparent network, but I have been imagining that if I were accessing from the host machine that should not be necessary for a transparent network.

Suspecting that there was a firewall somehow blocking the connect, I verified that the firewall service in the container is not even running. I turned off the firewall completely on the host, however, nothing changed. I still cannot connect. I tried both the "--expose 1433" parameter on the docker run, as well as rebuilt the image with the EXPOSE 1433 line in the docker file. No change in conditions.

I have no idea if a transparent network will even solve the issue, but I would like advice on this.

It would be okay for the performance to be somewhat slower, within reason, but a 6000 percent degradation is a problem for my intended purpose.

SteveSims
  • 535
  • 6
  • 19

1 Answers1

0

It turns out that I did not know to supply enough information on this issue.

The powershell code we are using to create and populate the test database with is sending a series of 328 script.sql files to the sql server. It is using Windows authentication. This works with the container, because we are using a GSMA credential_spec which is documented here:

https://learn.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/manage-serviceaccounts

That method of authentication may or may not be relevant. Using Wireshark to monitor the container adapter, I noticed that a connection took just under 4 seconds to authenticate, but I have no other method to provide as a comparison. Therefore, I cannot say if that method of authentication is somehow significantly slower than some other method. What is definitely of relevant significance is that when our main powershell code sends a particular script.sql file, it does not use Invoke-Sqlcmd. Rather it invokes sqlcmd via Invoke-Expression similar to:

$args = "-v DBName = $dbName JobOwnerName = $jobOwnerName -E -i $fileName -S $server -V 1 -f 65001 -I";
if (!$skipDBFlag)
{
    $args += " -d $dbName";
}
Invoke-Expression "& sqlcmd --% $args";

In this case, sqlcmd will reconnect to the database in the container, run a script.sql file, and then disconnect. It will not cache the connection the way that Invoke-Sqlcmd does.

So, because of the lack of connection pooling the authentication was happening 328 times, once for each script.sql file. 4 seconds * 328 / 60 = ~21 minutes. Thats where the source of the above issue was. Not in any container network issue.

I apologize for not being able to supply all of the relevant information initially. I hope that this answer will help someone if they run into a similar issue with using containers in this way, and the length of time that authentication with SQL Server takes in this configuration.

SteveSims
  • 535
  • 6
  • 19