当前位置: 首页 > news >正文

VMware Horizon 与 Docker 冲突排错记录

因为开发需要使用带界面的仿真软件,而以往的使用习惯基本都是 SSH 登录虚拟机即可满足需求。

但这次遇到两个现实问题:

  • 现有虚拟机系统为Ubuntu 18.04
  • 仿真软件要求Ubuntu 22.04 + GUI

最终选择的方案是:

  • 基于 Docker 构建一套Ubuntu 22.04 + 仿真软件的镜像
  • 运行在原有虚拟机中
  • 结合VMware Horizon,通过浏览器访问桌面,实现软件可视化操作

也正是在这个组合下,踩到了Docker 与 Horizon 的一个隐藏但非常典型的坑

也尝试过使用 MobaXterm 弹窗,根本弹不了远程虚拟机上的容器程序,AI 说可以是骗人的。


一、Horizon 是什么

VMware Horizon 本质上是一套VDI(虚拟桌面基础架构)解决方案。

简单理解就是:

  • 后端运行着大量云服务器 / 虚拟机
  • 虚拟机具备完整桌面环境(Linux / Windows)
  • 用户可通过浏览器(Web)或客户端访问远程桌面

在此前的实际使用中:

  • 日常运维、开发:SSH 完全够用
  • Horizon 桌面更多是“存在但几乎不用”的状态

但当GUI 仿真工具加入后,情况就完全不同了。


二、问题现象:安装 Docker 后,Horizon Web 桌面不可用

在虚拟机中安装 Docker 并启动后,出现了一个非常反直觉的现象:

  • SSH 登录、命令行操作一切正常
  • Horizon Web 桌面无法打开

浏览器直接报错:

An error has occurred: {"errno":"ETIMEDOUT","code":"ETIMEDOUT","syscall":"connect","address":"172.17.0.1","port":22443}

关键点非常集中:

172.17.0.1:22443

172.17.0.1,正是 Docker 默认创建的docker0网桥地址。


三、问题根因:Docker 默认网桥优先级与 Horizon 网络路径冲突

1️⃣ 先厘清:Horizon Web 桌面是如何建立连接的?

Horizon Web(Blast / HTML Access)并不只有一种连接模式,常见有两种:

模式一:浏览器直连虚拟机(Direct Connection)

  • 浏览器直接访问:虚拟机IP:22443
  • Blast 服务监听地址为:
0.0.0.0:22443
  • 网络路径:
浏览器 → 虚拟机 → Blast Server
模式二:通过中转服务器访问(Blast Secure Gateway / Unified Access Gateway)
  • 浏览器先连接 Horizon 中转服务器
  • 由中转服务器回连虚拟机的 Blast 服务端口
  • 网络路径:
浏览器 → Horizon 中转服务器 → 虚拟机 → Blast Server

本次问题环境使用的是第二种(中转模式),该模式可在 Horizon 管理台中配置。

2️⃣ 为什么会“连到” 172.17.0.1?

需要特别强调的是:

这并不是 Blast 监听地址配置错误,而是 Linux 系统选路问题。

Blast 服务本身监听的是:

0.0.0.0:22443

这意味着:

  • Blast 并不绑定某个具体 IP
  • 实际使用哪个 IP,对它来说取决于操作系统的网络选路结果

真正出问题的地方在于:

Linux 在选择“对外通信地址”时,选错了网卡。

3️⃣ Docker 实际造成了什么影响(真正的根因)

Docker 启动后会自动完成以下操作:

  • 创建docker0网桥
  • 默认分配地址:
172.17.0.1/16
  • 同时调整系统路由表与 iptables 规则

在部分环境中,会出现以下情况:

  • docker0网卡在路由或接口优先级上
    高于真实业务网卡
  • 系统在选择“回包路径”或“源地址”时
    优先选用了 docker0 的地址(172.17.0.1)

于是,实际发生的网络行为变成了:

Horizon 中转服务器 → 虚拟机 ↳ 系统选路:docker0 (172.17.0.1) ↳ Blast :22443

结果就是:

  • Horizon 中转服务器尝试连接172.17.0.1:22443
  • 该地址仅在虚拟机本地 Docker 网桥存在
  • 对外部网络完全不可达

最终表现为:

ETIMEDOUT

4️⃣ 补充:虚拟机访问地址的来源

需要注意的是:

虚拟机的访问地址是由 Horizon Agent 上报给 Connection Server / Gateway 的

当系统在某些场景下:

  • 选用了 docker0 对应的地址作为“对外地址”

那么 Agent 上报的地址本身就是不可达的,这也是问题产生的根源之一。

5️⃣ 结论

这并不是:

“Docker 抢占了 Blast 的端口”

而是:

Docker 创建的 docker0 网桥,在系统选路/接口优先级上高于真实网卡,
导致 Horizon 中转回连流量被引导到一个外部不可达的地址。

这也解释了为什么:

  • SSH 完全正常
  • 虚拟机本身运行无异常
  • 只有Horizon Web 桌面无法访问

因为只有 Horizon(尤其是中转模式)

👉强依赖“系统最终选择哪个 IP 作为对外通信地址”。


四、解决方案(可行但偏工程化)

最终采用的解决方式并不优雅,但非常稳定:

删除 docker0 → 登录 Horizon 桌面 → 重启 Docker

iplinksetdocker0 downiplinkdelete docker0# 用户成功登录 Horizon 桌面后systemctl restartdocker# docker0 会被重新创建

后续断开并重新连接 Horizon 桌面也可以正常访问(可能与会话 / 地址缓存有关)。

并不是所有虚拟机都会触发该问题
且实际需要桌面(GUI 仿真)的用户数量有限
同时虚拟机 IP 均为 DHCP 分配,无法批量在 Horizon Agent 中固定地址

因此最终选择了这种最小改动、可控范围内的工程方案

关于修改 Docker 网桥地址的误区

曾尝试通过修改 Docker 网关配置:

"bip":"10.99.99.1/24"

来规避172.17.0.1,但实践发现:

  • 问题并未彻底解决
  • 根因并非“占用了 172.17.0.1 本身”
  • 而是docker0 作为接口参与系统选路时的优先级问题

另外还踩过一个小坑:

  • Horizon 服务未停止时
  • Docker 启动阶段可能仍会受到影响

最终采用的顺序是:

  1. 停止 Horizon Web / Agent 服务
  2. 启动 Docker
  3. 再启动 Horizon

五、另一类常见报错的排查思路

如果不是 172.17.0.1 相关报错,而是:

“无法进入桌面,请联系管理员”

则可以按以下顺序排查。

检查 Horizon Agent 服务

systemctl status viewagent

必要时重启:

systemctl restart viewagent

检查 Blast 服务端口

netstat-tlnp|grep22443

期望看到:

tcp 0 0 0.0.0.0:22443 LISTEN xxx/VMwareBlastS

检查 iptables 影响

Docker 会自动修改 iptables,可能影响 Blast 通信。

可临时验证:

iptables -F iptables -L

仅用于排错验证,生产环境请谨慎

如果最终浏览器访问 Horizon 出现:

ETIMEDOUT 172.17.0.1:22443

基本可以确认仍是 docker0 选路问题,按前述方式处理即可。


六、Docker + GUI:DISPLAY

桌面能正常访问,并不代表容器里的 GUI 程序就能显示。

宿主机(虚拟机)准备

echo$DISPLAY

例如:

:102

并执行:

xhost +

仅限内网 / 临时调试使用

Docker 启动示例

dockerrun --net=host --rm -it\-eDISPLAY=$DISPLAY镜像bash

测试

aptinstall-y x11-apps xclock

能够弹窗即说明 GUI 显示链路打通。


七、批量环境治理

既然 Docker 在后续场景中是必需组件,那就统一在虚拟机上提前安装,并批量为现有用户授予 Docker 使用权限,避免后续重复配置和权限问题。

ansible 虚拟机组 -m shell -a'apt install -y docker.io'ansible 虚拟机组 -m shell -a\'for user in $(ls /home | grep -vE "^(public|gerrit|lost\+found)$"); do usermod -aG docker "$user" && echo "用户 $user 已加入 docker 组" done'

总结

本文问题本质并非端口或服务异常,而是 Docker 默认网桥参与系统选路,导致 Horizon 回连路径选错接口。
在依赖回连机制的 VDI 场景中,Docker 网络与桌面访问路径必须明确隔离或有序控制。

http://www.gsyq.cn/news/149093.html

相关文章:

  • Iridescent:Day34
  • 2025最新!9个AI论文平台测评:继续教育写论文痛点全解析
  • 8个降AI率工具推荐!继续教育学生必看
  • 路由策略和策略路由区别是什么
  • 深入剖析WordPress插件漏洞:未授权攻击的成功之道
  • GIF压缩策略优化:从激进到智能的演进之路
  • Chap25-SeparateUI-NetThread
  • 如果计算引擎是MapReduce,那么Hive能跑Spark SQL作业吗?
  • 告别复杂笔记软件!Memos+cpolar,让你的笔记随时随地可用
  • 佳能LBP2900 linux驱动 captdriver - 童晓伟
  • 为何选择 Go 语言进行开发?
  • Asio15-QuitGracefully
  • 基于Android的XX校园学习娱乐交流APP--论文小程序
  • 领导根本不关心你干了多少活,只在意这3点
  • 【课程设计/毕业设计】基于SpringBoot的植物知识分享系统的设计与实现基于SpringBoot的植物知识管理与分享平台的设计与实现【附源码、数据库、万字文档】
  • 手把手吃透设计模式内功:七大原则代码解析与重构指南
  • Elasticsearch倒排索引详解:如何实现高效搜索
  • excel如何筛选重复项?码住这4种方法!
  • Asio12-HandlePacketStickingProblemSimply
  • 第四章 SQL Server备份和还原
  • 【课程设计/毕业设计】基于springboot美发门店管理系统设计与实现基于springboot的美发商城系统【附源码、数据库、万字文档】
  • 计算机Java毕设实战-基于springboot的美发商城系统服务预约技师选择、到店时间预约【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • 计算机Java毕设实战-基于SpringBoot的植物知识管理与分享平台的设计与实现家庭园艺种植分享平台设计与实现【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • 番茄小说下载器 2025.12.21 | 现代化、高效的番茄小说下载器,支持批量下载和多种格式导出
  • STM32平衡车工具-匿名助手+虚拟串口如何使用。
  • 计算机Java毕设实战-基于springboot+vue技术的二手车交易管理系统的设计与实现基于SpringBoot+Vue的二手车交易平台设计【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • 2-[(2-叠氮乙酰基)氨基]-2-脱氧-D-吡喃甘露糖—糖生物学与代谢标记的关键化学探针 1971934-97-0
  • Java毕设选题推荐:基于springboot+vue技术的二手车交易管理系统的设计与实现汽车管理汽车品牌管理,公告类型管理,论坛管理【附源码、mysql、文档、调试+代码讲解+全bao等】
  • 新品限免|国产大模型工程化实战:GLM-4.7与MiniMax M2.1 免费选型对比
  • Java毕设项目:基于springboot+vue技术的二手车交易管理系统的设计与实现(源码+文档,讲解、调试运行,定制等)