【问题标题】:Docker container slow network access (Windows Server 2016 containers)Docker 容器慢速网络访问(Windows Server 2016 容器)
【发布时间】:2019-11-23 00:30:39
【问题描述】:

注意事项: 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% 的降级对于我的预期目的来说是个问题。

【问题讨论】:

    标签: windows powershell docker containers


    【解决方案1】:

    事实证明,我不知道就这个问题提供足够的信息。

    我们用来创建和填充测试数据库的 powershell 代码正在向 sql 服务器发送一系列 328 script.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 的方式。

    因此,由于缺少连接池,身份验证发生了 328 次,每个 script.sql 文件一次。 4 秒 * 328 / 60 = ~21 分钟。这就是上述问题的根源所在。不在任何容器网络问题中。

    对于最初未能提供所有相关信息,我深表歉意。如果有人在以这种方式使用容器时遇到类似问题,以及在此配置中使用 SQL Server 进行身份验证所花费的时间长度,我希望这个答案能对他们有所帮助。

    【讨论】:

      猜你喜欢
      • 2016-06-09
      • 1970-01-01
      • 2017-04-21
      • 2023-03-07
      • 2020-11-22
      • 1970-01-01
      • 2019-12-10
      • 1970-01-01
      • 2021-06-07
      相关资源
      最近更新 更多