WSL + Docker 网络访问详解
概述
本文档详细说明Windows宿主机、WSL、Docker容器之间的网络访问流程,以及常见的坑点和解决方案。
安利一个claude code镜像站,注册即送200刀,每日签到25刀,每日还有抽奖。
网络架构图
┌─────────────────────────────────────────────────────────────────┐
│ Windows 宿主机 │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ 浏览器/应用 │ │ WSL2 子系统 │ │
│ │ │ │ │ │
│ │ localhost:9208 │ │ 172.27.157.134 │ │
│ │ localhost:9209 │ │ │ │
│ └─────────────────┘ └─────────────────┘ │
│ │ │ │
│ │ │ │
│ └────────┬─────────────────┘ │
│ │ │
│ ┌────────▼─────────────────┐ │
│ │ WSL 虚拟网络 │ │
│ │ │ │
│ │ ┌─────────────────────┐ │ │
│ │ │ Docker 容器 │ │ │
│ │ │ │ │ │
│ │ │ 容器IP: 172.17.x.x │ │ │
│ │ │ 端口: 9208 │ │ │
│ │ └─────────────────────┘ │ │
│ └─────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
网络访问流程详解
1. 浏览器访问WSL中Docker容器的完整路径
浏览器 → Windows宿主机 → WSL → Docker容器
详细步骤:
-
浏览器发起请求
用户输入: http://localhost:9209
-
Windows宿主机接收
Windows网络栈监听9209端口 检查是否有进程占用该端口
-
WSL端口映射转发
WSL接收来自Windows的请求 通过Docker端口映射转发到容器
-
Docker容器处理
容器内应用监听9208端口 处理请求并返回响应
-
响应返回
容器 → WSL → Windows → 浏览器
2. 端口映射机制
Docker端口映射语法
docker run -p 宿主机端口:容器端口
实际例子
# 将WSL的9209端口映射到容器的9208端口
docker run -p 9209:9208 hr-system-backend:latest
映射关系:
- Windows宿主机:9209 ← → WSL:9209 ← → Docker容器:9208
常见坑点及解决方案
坑点1:端口冲突
问题描述
docker: Error response from daemon: ports are not available:
exposing port TCP 0.0.0.0:9208 -> 127.0.0.1:0: listen tcp 0.0.0.0:9208:
bind: Only one usage of each socket address (protocol/network address/port)
is normally permitted.
原因分析
- Windows宿主机端口被占用
- 本地开发服务与Docker容器端口冲突
- 之前的容器没有完全清理
解决方案
1. 检查端口占用
# Windows PowerShell
netstat -ano | findstr :9208
netstat -ano | findstr :9209# 查看占用进程
tasklist /FI "PID eq 进程ID"
2. 停止占用进程
# 强制停止进程
taskkill /PID 进程ID /F
3. 使用不同端口
# 修改Docker端口映射
docker run -p 9209:9208 hr-system-backend:latest
4. 清理旧容器
# 停止并删除旧容器
docker stop hr-backend
docker rm hr-backend# 或者强制删除
docker rm -f hr-backend
坑点2:WSL网络配置问题
问题描述
- WSL无法访问宿主机服务
- 容器无法访问外部网络
- 端口映射不生效
解决方案
1. 检查WSL网络状态
# 查看WSL IP地址
wsl hostname -I# 检查WSL网络配置
wsl ip addr show
2. 重启WSL网络
# 在Windows PowerShell中
wsl --shutdown
wsl
3. 检查Docker网络
# 查看Docker网络
docker network ls
docker network inspect bridge
坑点3:防火墙和代理问题
问题描述
- 浏览器无法访问localhost:9209
- 请求超时
- 连接被拒绝
解决方案
1. 检查Windows防火墙
# 临时关闭防火墙测试
netsh advfirewall set allprofiles state off# 添加防火墙规则
netsh advfirewall firewall add rule name="WSL Docker" dir=in action=allow protocol=TCP localport=9209
2. 检查代理设置
# 检查系统代理
netsh winhttp show proxy# 重置代理
netsh winhttp reset proxy
3. 检查WSL代理配置
# 在WSL中检查代理
echo $HTTP_PROXY
echo $HTTPS_PROXY
坑点4:Docker容器启动失败
问题描述
- 容器创建成功但无法启动
- 健康检查失败
- 服务无法访问
解决方案
1. 检查容器日志
# 查看容器日志
docker logs hr-backend# 实时查看日志
docker logs -f hr-backend
2. 检查容器状态
# 查看容器状态
docker ps -a# 查看容器详细信息
docker inspect hr-backend
3. 进入容器调试
# 进入容器
docker exec -it hr-backend sh# 检查容器内服务
netstat -tlnp
ps aux
最佳实践
1. 端口规划策略
开发环境端口分配:
├── 本地开发后端: 9208
├── WSL Docker后端: 9209
├── 本地开发前端: 3000
├── WSL Docker前端: 3001
└── 生产环境: 9208
2. 部署脚本优化
#!/bin/bash# 检查端口是否被占用
check_port() {local port=$1if netstat -ano | findstr ":$port" > /dev/null; thenecho "[警告] 端口 $port 已被占用"return 1fireturn 0
}# 清理旧容器
cleanup_old_containers() {echo "清理旧容器..."docker stop hr-backend 2>/dev/null || truedocker rm hr-backend 2>/dev/null || true
}# 检查端口并部署
if check_port 9209; thencleanup_old_containersdocker run -d --name hr-backend -p 9209:9208 hr-system-backend:latest
elseecho "请先停止占用9209端口的服务"exit 1
fi
3. 网络诊断工具
# 创建网络诊断脚本
cat > network-diagnosis.sh << 'EOF'
#!/bin/bashecho "=== WSL网络诊断 ==="
echo "WSL IP地址: $(hostname -I)"
echo "Docker网络:"
docker network ls
echo "容器状态:"
docker ps -a
echo "端口占用:"
netstat -tlnp | grep -E ":(9208|9209)"
echo "网络连通性测试:"
curl -I http://localhost:9209/health 2>/dev/null || echo "无法访问服务"
EOFchmod +x network-diagnosis.sh
故障排查流程
1. 快速诊断步骤
# 1. 检查端口占用
netstat -ano | findstr ":9209"# 2. 检查容器状态
docker ps -a | grep hr-backend# 3. 检查容器日志
docker logs hr-backend# 4. 测试网络连通性
curl -I http://localhost:9209/health# 5. 检查WSL网络
wsl hostname -I
2. 常见错误及解决方案
错误信息 | 原因 | 解决方案 |
---|---|---|
bind: address already in use | 端口被占用 | 停止占用进程或使用不同端口 |
docker: Error response from daemon | Docker服务问题 | 重启Docker服务 |
curl: (7) Failed to connect | 网络连接问题 | 检查防火墙和代理设置 |
Container is not running | 容器启动失败 | 检查容器日志和配置 |
3. 性能优化建议
# 1. 使用Docker网络优化
docker network create hr-network
docker run --network hr-network -p 9209:9208 hr-system-backend:latest# 2. 配置资源限制
docker run -d \--name hr-backend \--memory=1g \--cpus=1 \-p 9209:9208 \hr-system-backend:latest# 3. 使用健康检查
docker run -d \--name hr-backend \--health-cmd="curl -f http://localhost:9208/health || exit 1" \--health-interval=30s \-p 9209:9208 \hr-system-backend:latest
总结
WSL + Docker的网络访问虽然复杂,但理解了网络架构和常见坑点后,可以有效地进行故障排查和性能优化。关键是要理解端口映射机制和网络访问路径,这样才能快速定位和解决问题。
文档版本: v1.0
适用环境: Windows 10/11 + WSL2 + Docker Desktop