Docker容器会降低网络访问速度(Windows Server 2016容器)

时间:2019-07-13 15:31:27

标签: windows powershell docker containers

注意: Slow network performance in Docker container没有解决我的两个问题。 Very slow network performance of Docker containers with host's network可能与此有关,但是那里的一个答案肯定不是问题。

我正在运行带有microsoft / mssql-server-windows-developer映像的Windows Server 2016集成版本的docker。 (Windows容器,Linux并非最终目的)。我的目标是将该图像用于临时SQL服务器以进行重复的验收测试运行。

到目前为止,除了性能之外,一切都按我需要的方式工作。为了衡量性能,我有一组脚本(由powershell调用),这些脚本将设置具有表,架构,角色等以及少量初始数据的数据库。

当我与主机系统共享驱动器时,我可以连接到容器并在容器内运行此powershell脚本。需要30秒才能完成。没有错误,当我使用SSMS检查数据库时,一切都正确。

当我从主机(通过公开的端口1433)运行脚本时,该脚本花费的时间大约增加了6000%。 (即大约30分钟。)但是,它也可以正常运行并产生正确的结果。

以上测量是使用默认的“ nat”网络进行的,容器以-p 1433:1433运行。我的主要问题是,从主机系统运行脚本时,如何获得远程合理的性能? (最终选择不要从容器内部运行任何受测对象。最终,同样的性能问题也必须解决,以使我们的容器部署计划切实可行。)

谢谢!

到目前为止我尝试过的。

首先,容器内部没有内部CPU或内存性能问题。因此,我已经尝试了--cpus相关选项和-m选项,并为容器提供了远远超出其实际需要的资源。内部性能不变。无论采用哪种设置,这种方式都非常快。

我也研究过创建“透明”网络。使用powershell cmdlet New-ContainerNetwork,创建了一个透明网络,并使用“ --net Trans”开关启动了容器。我从外部网络获得了有效的DHCP地址,并且可以连接到Internet和Intranet上的其他域计算机。使用netstat -a(和powershell Get-WMIObject win32_service),我能够确定MSSQLSERVER实例正在运行并正在侦听端口1433。我在容器内安装了telnet,并可以使用命令“ telnet”连接到该端口。 [ipaddressfromipconfig] 1433“。

在主机命令提示符下,我可以ping容器的ip地址并获得答复,但telnet命令(上述)无法从主机连接。因此,当我尝试使用SSMS时,它自然也不会连接。透明网络不支持-P或-p 1433:1433端口映射选项,但是我一直在想,如果我是从主机访问的,则透明网络不必要。

怀疑有一个防火墙以某种方式阻止了连接,我验证了容器中的防火墙服务甚至没有运行。我完全关闭了主机上的防火墙,但是没有任何改变。我仍然无法连接。我在docker run上尝试了“ --expose 1433”参数,并在docker文件中使用EXPOSE 1433行重建了映像。条件没有变化。

我不知道透明的网络是否可以解决问题,但是我想提出建议。

在合理的范围内,性能会稍慢是可以的,但是对于我的预期目的而言,性能下降6000%是一个问题。

1 个答案:

答案 0 :(得分:0)

事实证明,我不知道是否提供有关此问题的足够信息。

我们用于创建和填充测试数据库的powershell代码将一系列328 script.sql文件发送到sql服务器。它正在使用Windows身份验证。这适用于容器,因为我们使用的是GSMA credential_spec,该文档在此处记录:

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

该身份验证方法可能相关,也可能不相关。使用Wireshark监视容器适配器,我注意到一个连接花费了不到4秒的时间来进行身份验证,但是我没有其他方法可以提供比较。因此,我不能说这种身份验证方法是否比其他方法慢得多。绝对相关的意义是,当我们的主要Powershell代码发送特定的script.sql文件时,它不使用Invoke-Sqlcmd。而是通过类似于以下内容的Invoke-Expression调用sqlcmd:

$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";

在这种情况下,sqlcmd将重新连接到容器中的数据库,运行script.sql文件,然后断开连接。它不会缓存连接 Invoke-Sqlcmd的方式。

因此,由于缺少连接池,因此对于每个script.sql文件,身份验证进行了328次。 4秒* 328/60 =〜21分钟。那就是上述问题的根源所在。没有任何容器网络问题。

很抱歉无法最初提供所有相关信息。我希望这个答案如果对使用这种方式使用容器时遇到类似问题的人有所帮助,以及这种配置下使用SQL Server进行身份验证所花费的时间长。