Windows 容器中的 UNC 访问:先看名称,再看身份
主机上的资源管理器既不能证明容器的 DNS 路径,也不能证明它的 SMB 身份。先检查容器内的名称解析和 445 端口,再谈权限。
需要在隧道另一侧访问共享的 Windows 容器,会在两条互相独立的路径上失败,而主机上的资源管理器一条都证明不了。容器有自己的网络端点,也有自己的进程身份。在桌面上能解析的名称、文件服务器在那里接受的会话,描述的是桌面,不是工作负载。
主机上的资源管理器不是证据
在主机上打开共享,用的是主机的 DNS 客户端、主机的路由表和主机上登录的账户。容器进程不会自动继承其中任何一项,即使容器和 VPN 客户端运行在同一台机器上。第一个边界是网络路径:容器能不能解析这个名称,能不能向 SMB 端口打开 TCP 会话。第二个边界是身份:文件服务器是否接受容器出示的身份,并且带着工作负载所需的权限。
把两者当成一个问题,就会陷入熟悉的循环:不断放宽防火墙规则,去修一个实际上是共享返回拒绝访问的问题。
跟着容器自己的请求走
Windows 容器的网络由主机网络服务管理,它创建的端点拥有自己的网络命名空间。你选择的模式决定了端点是被转换、被桥接,还是接入与主机共享的网络。这个决定同时改变两件事:容器能解析什么,以及文件服务器看到哪个源地址。
在改动任何东西之前,先确认容器自己观察到什么。在外面能解析的名称,在里面可能失败,因为容器的 DNS 配置不是主机的;被转换的端点也可能出示一个文件服务器规则没有预料到的源。
docker exec -it app powershell -Command "Resolve-DnsName files.corp.example" docker exec -it app powershell -Command "Test-NetConnection files.corp.example -Port 445" docker exec -it app powershell -Command "Get-NetIPConfiguration"
如果解析失败,就在网络配置里修 DNS,而不是替换地址。用 IP 代替名称可能改变身份验证和服务器身份的行为,把一个变成两个问题。下一个该检查的是 VPN 客户端自己的策略,因为它可能对主机进程和源自容器的流量区别对待。
身份是另一个决定
交互式用户映射的盘符不是应用接口。它只存在于一个登录会话里,容器进程并不属于那个会话。请使用 UNC 路径,并给工作负载一个部署模型支持的身份。在域支持的地方,组托管服务账户(gMSA)通过凭据规范提供托管身份。
微软的容器 gMSA 指南描述了这种凭据规范安排及其前提条件,其中包括域成员资格和能够取回凭据的主机。账户、取回、容器内的进程身份和共享权限必须全部对得上。VPN 登录不是那个身份,把密码烤进镜像来复现主机用户的会话,会制造长期暴露。
让失败的那一步可见
解析失败、连接被拒和访问被拒需要不同的证据。它们分别是 DNS 问题、路由或过滤问题、身份验证或权限问题。要读容器收到的响应,而不是应用给出的笼统错误。
用工作负载自己的身份测试,也测试一次被拒绝的情况。
为重新连接做准备
VPN 路径会断。隧道回来时,端点可能带着另一个转换后的地址回来,已有的 SMB 会话可能已经死掉而应用毫无察觉。要在应用里处理:重建路径和身份,重试操作,并把结果未知的文件操作对账,而不是假设什么都没发生。
把网络模式、DNS 来源和身份安排写进部署笔记。下一次故障要谈的,正是这三件事。