前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >解决Docker for Windows无法共享磁盘的问题

解决Docker for Windows无法共享磁盘的问题

原创
作者头像
yaxin
发布2019-03-01 14:49:43
5.5K5
发布2019-03-01 14:49:43
举报
文章被收录于专栏:DevOps BoyDevOps Boy

Docker for Windows 简化了windows下使用docker的流程,而且其有一项非常好的功能就是共享本地磁盘给docker(docker mount),但在实际使用中发现无法共享磁盘给docker,报错为:

A firewall is blocking file Sharing between Windows and the containers...

0x01 错因分析

错误提示很明确,因为防火墙的问题导致无法正常共享磁盘。这里要提一下,Docker for Windows本质也是通过一个运行在hyper-v上Linux虚拟机来实现的,而其共享磁盘的方案也是通过samba来,也就是说,Windows作为samba服务器,然后运行docker的虚拟机通过smbclient访问Windows的samba服务。samba服务使用的是445端口,也就是说,docker虚拟机无法访问主机的445端口。可以通过下面的命令来验证:

代码语言:txt
复制
docker run --rm -it --net=host alpine /bin/sh
nc -vz 10.0.75.1 445
run.png
run.png

上图中10.0.75.1为docker网络设置的网关,可以看到,如果端口无法访问,会在等待一段时间超时后报错。

那为什么防火墙会拦截samba服务了。首先我们要先分析一下防火墙的规则了。打开控制面板,依次选择“系统和安全”->“Windows Defender 防火墙”,然后打开左侧“高级设置”中的“入站规则”

firewall.png
firewall.png

可以看到入站规则中有很多“阻止的规则”,但是也有一条明确放通10.0.75.1445端口的访问,可为什么还是不行呢?

通过Google,发现Windows的防火墙规则并不是按照规则先后顺序执行的,而是“阻止规则”优先级大于“放通规则”,参见:https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc755191(v=ws.10)。

0x02 解决方法

那如何处理呢?当然可以通过关闭防火墙来直接验证。但是这只是一种临时的验证方式,因为关闭防火墙很不安全而且公司本身也不允许。

分析一下阻止规格,并不是所有源IP都被禁止了访问445端口,这就给我们提供了一个解决方式,找一个没有被禁止访问445端口IP端作为Docker for Windows的subnet address

首先打开cmd,使用下面命令将所有入站的规则导出到文件中:

代码语言:txt
复制
netsh advfirewall firewall show rule name=all dir=in type=dynamic status=enabled > d:/firewall_rules.txt

然后将所有操作阻止协议TCP的规则中的远程IP全部复制出来。然后上python处理,这里使用了IPy库进行网关的判断和处理。

代码语言:txt
复制
from IPy import IP
# netsh advfirewall firewall show rule name=all dir=in type=dynamic status=enabled > d:/firewall_rules.txt
firewall_rules = """
169.254.2.0/24
10.3.128.0/17
9.19.161.0/26,9.19.161.64/26,10.3.224.0/19
"""
net_sets = []
for line in firewall_rules.strip().split('\n'):
    line = line.strip()
    line_seg = line.split(',')
    for net_string in line_seg:
        print(net_string)
        net_sets.append(IP(str(net_string)))
        
for net in net_sets:
    for l2 in range(0, 255):
        for l3 in range(0, 255):
            ip_net = "10.%s.%s.0" % (l2, l3)
            if ip_net in net:
                continue
            print("Net %s is available" % ip_net)

然后从打印出的网段中找一个更新到Docker网络中,然后就可以愉快的共享磁盘了。

Image.png
Image.png

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0x01 错因分析
  • 0x02 解决方法
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档