OpenTwins Windows 本地部署实战指南
本文档记录了在 Windows 环境下成功部署 OpenTwins 数字孪生平台的完整过程,包括所有必要的工具安装、配置和故障排查。
一、部署概述
1.1 OpenTwins 简介
OpenTwins 是一个开源的数字孪生平台,基于 Eclipse Ditto 构建,提供了完整的数字孪生管理、数据采集、存储和可视化功能。
1.2 部署架构
1Windows 本地环境2├── Docker Desktop(容器运行时)3├── Minikube(本地 Kubernetes 集群)4├── Helm 3(包管理器)5└── OpenTwins 平台组件6 ├── Eclipse Ditto(数字孪生核心引擎)7 ├── Mosquitto(MQTT 消息代理)8 ├── InfluxDB(时序数据库)9 ├── Grafana(数据可视化)10 └── MongoDB(数据存储)1.3 系统要求
硬件要求
- CPU: 4 核心或以上(推荐 8 核心)
- 内存: 8GB RAM(最低),推荐 16GB
- 磁盘: 至少 40GB 可用空间
- 操作系统: Windows 10/11 Pro、Enterprise 或 Education
软件要求
- 操作系统: Windows 10 (1903+) 或 Windows 11
- PowerShell: 5.1 或以上
- 虚拟化: 启用 Hyper-V 或 WSL 2
本次部署使用 Docker Desktop + WSL 2 作为容器运行时,Minikube 作为 Kubernetes 集群。
二、环境准备
2.1 安装 Docker Desktop
下载安装
- 访问 Docker Desktop 官网
- 下载 Windows 版本安装程序
- 运行安装程序并按照向导完成安装
- 重启计算机
配置 Docker Desktop
启动 Docker Desktop 后,进行以下配置:
-
选择后端:
- 设置 → General → Use WSL 2 based engine(推荐)
-
资源配置:
- 设置 → Resources → Advanced
- CPUs: 至少 4 核心
- Memory: 至少 8GB
- Disk image size: 至少 60GB
验证 Docker 安装
打开 PowerShell:
1# 检查 Docker 版本2docker --version3# 输出示例: Docker version 28.5.1, build e180ab845# 运行测试容器6docker run hello-world78# 查看运行中的容器9docker ps2.2 安装 kubectl
kubectl 已经随 Docker Desktop 安装,验证版本:
1kubectl version --client2# 输出示例: Client Version: v1.34.12.3 安装 Chocolatey(可选但推荐)
Chocolatey 是 Windows 的包管理器,可以简化后续工具的安装。
以管理员身份运行 PowerShell:
1Set-ExecutionPolicy Bypass -Scope Process -Force2[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 30723iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))验证安装:
1choco --version2# 输出示例: 2.5.12.4 安装 Helm
使用 Chocolatey 安装:
1choco install kubernetes-helm -y验证安装:
1helm version2# 输出示例: version.BuildInfo{Version:"v3.18.6"...}2.5 安装 Minikube
使用 Chocolatey 安装:
1choco install minikube -y验证安装:
1minikube version2# 输出示例: minikube version: v1.37.0三、部署 Kubernetes 集群
3.1 启动 Minikube
打开 PowerShell(建议以管理员身份运行):
1# 启动 Minikube 集群(使用 Docker 驱动)2minikube start `3 --cpus 4 `4 --memory 8192 `5 --disk-size 40gb `6 --driver=docker首次启动 Minikube 需要下载 Kubernetes 镜像,可能需要 5-10 分钟,请耐心等待。
预期输出:
1* Microsoft Windows 11 Pro 10.0.26100 上的 minikube v1.37.02* 根据用户配置使用 docker 驱动程序3* 正在拉取基础镜像 v0.0.48 ...4* 正在下载 Kubernetes v1.34.0 的预加载文件...5* 启用插件: storage-provisioner, default-storageclass6* 完成!kubectl 现在已配置,默认使用"minikube"集群和"default"命名空间3.2 验证集群状态
1# 配置 kubectl 使用 minikube 上下文2kubectl config use-context minikube34# 验证集群连接5kubectl cluster-info6# 输出: Kubernetes control plane is running at https://127.0.0.1:xxxxx78# 查看节点状态9kubectl get nodes10# 输出:11# NAME STATUS ROLES AGE VERSION12# minikube Ready control-plane 2m v1.34.03.3 验证集群功能
1# 查看所有命名空间2kubectl get namespaces34# 查看系统 Pod5kubectl get pods -n kube-system67# 查看服务8kubectl get services四、部署 OpenTwins
4.1 添加 Helm 仓库
1# 添加 ERTIS Helm 仓库2helm repo add ertis https://ertis-research.github.io/Helm-charts/34# 更新仓库5helm repo update67# 查看 OpenTwins Chart 信息8helm search repo opentwins预期输出:
1NAME CHART VERSION APP VERSION DESCRIPTION2ertis/OpenTwins 0.5.23 0.5.0 Esta es una plataforma de codigo abierto...4.2 安装 OpenTwins
1# 安装 OpenTwins(推荐配置)2helm upgrade --install opentwins ertis/OpenTwins `3 --wait `4 --timeout 20m `5 --dependency-update--wait: 等待所有 Pod 就绪--timeout 20m: 设置超时时间为 20 分钟(首次安装需要拉取镜像)--dependency-update: 自动更新依赖的 Chart
4.3 监控部署进度
在另一个 PowerShell 窗口中运行:
1# 实时查看所有 Pod 状态2kubectl get pods -w或者定期检查:
1# 查看所有 Pod 状态2kubectl get pods34# 查看特定 Pod 的详细信息5kubectl describe pod <pod-name>67# 查看 Pod 日志8kubectl logs <pod-name>4.4 部署过程说明
OpenTwins 包含 12 个组件,部署过程大约需要 15-25 分钟:
-
初始阶段(0-5分钟)
- 下载 Helm Chart
- 创建 Kubernetes 资源
- 开始拉取容器镜像
-
镜像拉取阶段(5-15分钟)
- 下载各组件的 Docker 镜像
- 镜像大小总计约 2-3GB
- 状态显示为
ContainerCreating或Init
-
启动阶段(15-20分钟)
- 容器依次启动
- MongoDB、InfluxDB 等基础服务先启动
- Ditto 组件依次启动
- Grafana 最后启动
-
就绪阶段(20-25分钟)
- 所有 Pod 状态变为
Running READY列显示1/1或2/2
- 所有 Pod 状态变为
ContainerCreating: 正在拉取镜像或创建容器Init:0/1: 正在运行初始化容器PodInitializing: Pod 正在初始化Running: 容器正在运行CrashLoopBackOff: 容器启动失败,正在重试(Telegraf 在等待 InfluxDB 时会出现,这是正常的)
4.5 验证部署
等待所有 Pod 就绪:
1# 检查所有 Pod 状态2kubectl get pods预期输出(所有 Pod 都应该是 Running 状态):
1NAME READY STATUS RESTARTS AGE2opentwins-ditto-connectivity-xxx 1/1 Running 0 23m3opentwins-ditto-extended-api-xxx 1/1 Running 0 23m4opentwins-ditto-gateway-xxx 1/1 Running 0 23m5opentwins-ditto-nginx-xxx 1/1 Running 0 23m6opentwins-ditto-policies-xxx 1/1 Running 0 23m7opentwins-ditto-things-xxx 1/1 Running 0 23m8opentwins-ditto-thingssearch-xxx 1/1 Running 0 23m9opentwins-grafana-xxx 2/2 Running 0 23m10opentwins-influxdb2-0 1/1 Running 0 23m11opentwins-mongodb-xxx 1/1 Running 0 23m12opentwins-mosquitto-xxx 1/1 Running 0 23m13opentwins-telegraf-xxx 1/1 Running 9 23m查看服务:
1kubectl get services预期输出:
1NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)2opentwins-ditto-extended-api NodePort 10.105.182.81 <none> 8080:30526/TCP3opentwins-ditto-nginx NodePort 10.102.210.73 <none> 8080:30525/TCP4opentwins-grafana NodePort 10.109.196.142 <none> 80:30718/TCP5opentwins-influxdb2 NodePort 10.108.92.37 <none> 80:30716/TCP6opentwins-mongodb NodePort 10.109.115.172 <none> 27017:30717/TCP7opentwins-mosquitto NodePort 10.103.102.84 <none> 1883:30511/TCP,9001:32453/TCP五、访问 OpenTwins
5.1 网络访问说明
由于 Windows 上 Minikube 的网络限制,无法直接通过 Minikube IP 访问服务。我们需要使用端口转发的方式。
不要尝试通过 minikube ip 获取的 IP 地址访问服务,这在 Windows 上通常不起作用。
5.2 手动端口转发
方式 1: 单个服务端口转发
1# Grafana(数据可视化)2kubectl port-forward svc/opentwins-grafana 3002:8034# Ditto API(数字孪生核心)5kubectl port-forward svc/opentwins-ditto-nginx 8080:808067# OpenTwins Extended API8kubectl port-forward svc/opentwins-ditto-extended-api 8081:8080910# InfluxDB(时序数据库)11kubectl port-forward svc/opentwins-influxdb2 8086:801213# Mosquitto MQTT(消息代理)14kubectl port-forward svc/opentwins-mosquitto 1883:1883端口转发命令会占用当前终端窗口,需要保持窗口打开。建议为每个服务开启一个新的 PowerShell 窗口。
方式 2: 使用自动化脚本
创建 start-opentwins-portforward.ps1 文件:
1# OpenTwins 端口转发启动脚本23Write-Host "======================================" -ForegroundColor Green4Write-Host "启动 OpenTwins 端口转发" -ForegroundColor Green5Write-Host "======================================" -ForegroundColor Green6Write-Host ""78# 启动端口转发(后台运行)9Write-Host "正在启动端口转发..." -ForegroundColor Yellow10Write-Host ""1112# Grafana13Start-Job -Name "grafana-forward" -ScriptBlock { 14 kubectl port-forward svc/opentwins-grafana 3000:80 15} | Out-Null1617# Ditto API18Start-Job -Name "ditto-forward" -ScriptBlock { 19 kubectl port-forward svc/opentwins-ditto-nginx 8080:8080 20} | Out-Null2122# OpenTwins Extended API23Start-Job -Name "extended-api-forward" -ScriptBlock { 24 kubectl port-forward svc/opentwins-ditto-extended-api 8081:8080 25} | Out-Null2627# InfluxDB28Start-Job -Name "influxdb-forward" -ScriptBlock { 29 kubectl port-forward svc/opentwins-influxdb2 8086:80 30} | Out-Null3132# Mosquitto MQTT33Start-Job -Name "mosquitto-forward" -ScriptBlock { 34 kubectl port-forward svc/opentwins-mosquitto 1883:1883 35} | Out-Null3637# 等待端口转发启动38Start-Sleep -Seconds 33940Write-Host "======================================" -ForegroundColor Green41Write-Host "端口转发已启动!" -ForegroundColor Green42Write-Host "======================================" -ForegroundColor Green43Write-Host ""44Write-Host "访问地址:" -ForegroundColor Yellow45Write-Host ""46Write-Host " Grafana (数据可视化):" -ForegroundColor Cyan47Write-Host " http://localhost:3000" -ForegroundColor White48Write-Host " 用户名: admin" -ForegroundColor Gray49Write-Host " 密码: admin" -ForegroundColor Gray50Write-Host ""51Write-Host " Ditto API (数字孪生核心):" -ForegroundColor Cyan52Write-Host " http://localhost:8080" -ForegroundColor White53Write-Host ""54Write-Host " OpenTwins Extended API:" -ForegroundColor Cyan55Write-Host " http://localhost:8081" -ForegroundColor White56Write-Host ""57Write-Host " InfluxDB (时序数据库):" -ForegroundColor Cyan58Write-Host " http://localhost:8086" -ForegroundColor White59Write-Host ""60Write-Host " Mosquitto MQTT:" -ForegroundColor Cyan61Write-Host " localhost:1883" -ForegroundColor White62Write-Host ""63Write-Host "======================================" -ForegroundColor Green64Write-Host ""65Write-Host "管理命令:" -ForegroundColor Yellow66Write-Host " 查看后台任务: Get-Job" -ForegroundColor Gray67Write-Host " 停止所有转发: Get-Job | Stop-Job; Get-Job | Remove-Job" -ForegroundColor Gray68Write-Host ""69Write-Host "提示: 保持此窗口打开以维持端口转发" -ForegroundColor Yellow70Write-Host " 按 Ctrl+C 可以停止所有转发" -ForegroundColor Yellow71Write-Host ""7273# 显示后台任务状态74Write-Host "后台任务状态:" -ForegroundColor Yellow75Get-Job | Format-Table -AutoSize7677Write-Host ""78Write-Host "正在监控端口转发状态... (按 Ctrl+C 停止)" -ForegroundColor Gray79Write-Host ""8081# 保持脚本运行82try {83 while ($true) {84 Start-Sleep -Seconds 1085 86 # 检查任务状态87 $failedJobs = Get-Job | Where-Object { $_.State -eq "Failed" }88 if ($failedJobs) {89 Write-Host "警告: 有端口转发任务失败" -ForegroundColor Red90 $failedJobs | Format-Table -AutoSize91 }92 }93} finally {94 Write-Host ""95 Write-Host "正在停止所有端口转发..." -ForegroundColor Yellow96 Get-Job | Stop-Job97 Get-Job | Remove-Job98 Write-Host "已停止所有端口转发" -ForegroundColor Green99}运行脚本:
1powershell -ExecutionPolicy Bypass -File .\start-opentwins-portforward.ps15.3 访问服务
启动端口转发后,在浏览器中访问以下地址:
📊 Grafana(数据可视化)- 推荐首先访问
1http://localhost:3002- 默认用户名:
admin - 默认密码:
admin - 首次登录会要求修改密码
验证访问: 打开浏览器访问上述地址,应该看到 Grafana 登录页面。
🌐 Ditto API(数字孪生核心)
1http://localhost:8080Eclipse Ditto 提供了完整的数字孪生管理 API。
API 文档: http://localhost:8080/apidoc/
验证访问: 访问根路径应该看到 Ditto 的欢迎页面。
🌐 OpenTwins Extended API
1http://localhost:8081/docs/OpenTwins 的扩展 API 接口文档。
根路径 http://localhost:8081/ 会显示 "Cannot GET /",这是正常现象。
Extended API 没有配置根路径响应,需要访问 /docs/ 路径查看 API 文档。
验证访问: 访问 http://localhost:8081/docs/ 应该看到 Swagger API 文档页面。
💾 InfluxDB(时序数据库)
1http://localhost:8086首次访问需要完成初始化配置:
- 设置初始用户名和密码
- 设置组织名称
- 设置初始 Bucket 名称
验证访问: 打开浏览器应该看到 InfluxDB 的欢迎/登录页面。
📡 Mosquitto MQTT(消息代理)
1localhost:1883MQTT 端口不能通过浏览器访问!
1883 端口使用的是 MQTT 协议,不是 HTTP/HTTPS 协议。如果在浏览器中访问会看到:
- Chrome/Edge: "该网页无法正常运作" 或 "ERR_EMPTY_RESPONSE"
- Firefox: "连接被重置"
这是正常现象,不是错误!
如何访问 MQTT 服务:
-
使用 MQTT Explorer(推荐)
- 下载: http://mqtt-explorer.com/
- 安装后配置连接:
- Protocol:
mqtt:// - Host:
localhost - Port:
1883
- Protocol:
-
使用命令行工具
bash1# 订阅主题2mosquitto_sub -h localhost -p 1883 -t "test/#"34# 发布消息5mosquitto_pub -h localhost -p 1883 -t "test/topic" -m "Hello OpenTwins" -
使用 Python
python1import paho.mqtt.client as mqtt23client = mqtt.Client()4client.connect("localhost", 1883, 60)5client.publish("test/topic", "Hello OpenTwins!")6client.disconnect()
验证连接: 使用 PowerShell 测试端口是否开放:
1Test-NetConnection -ComputerName localhost -Port 18832# TcpTestSucceeded 应该显示 True六、配置和使用
6.1 Grafana 初始配置
- 访问
http://localhost:3000 - 使用默认凭据登录(admin/admin)
- 系统会提示修改密码,建议修改
- 进入主界面后,可以看到预配置的仪表板
6.2 创建数字孪生
使用 Ditto API 创建数字孪生实例:
1# 使用 curl 创建一个简单的数字孪生2curl -X PUT http://localhost:8080/api/2/things/org.example:my-thing \3 -H "Content-Type: application/json" \4 -d '{5 "attributes": {6 "location": "Room 42"7 },8 "features": {9 "temperature": {10 "properties": {11 "value": 23.512 }13 }14 }15 }'6.3 MQTT 消息发布
使用 MQTT 客户端发布消息:
1# 使用 mosquitto_pub 发布消息2mosquitto_pub -h localhost -p 1883 -t "org.example/my-thing" -m '{"temperature": 24.5}'七、常用管理命令
7.1 查看状态
1# 查看所有 Pod 状态2kubectl get pods34# 查看服务5kubectl get services67# 查看 Helm 发布8helm list910# 查看 Helm 发布详情11helm status opentwins1213# 查看特定 Pod 日志14kubectl logs <pod-name>1516# 实时查看日志17kubectl logs -f <pod-name>7.2 重启服务
1# 重启特定 Pod(删除后会自动重建)2kubectl delete pod <pod-name>34# 重启所有 OpenTwins Pod5kubectl delete pods -l app.kubernetes.io/instance=opentwins7.3 停止和启动
1# 停止 Minikube(保留数据)2minikube stop34# 启动 Minikube5minikube start67# 删除 Minikube(删除所有数据)8minikube delete7.4 卸载 OpenTwins
1# 卸载 OpenTwins2helm uninstall opentwins34# 确认卸载5kubectl get pods6# 应该看不到 opentwins 相关的 Pod八、故障排查
8.1 端口访问问题
问题 1: localhost:8081 显示 "Cannot GET /"
现象: 访问 http://localhost:8081 时浏览器显示 "Cannot GET /"
原因: 这是正常现象,不是错误!Extended API 的根路径没有配置任何内容。
解决方案: 访问 API 文档页面:
1http://localhost:8081/docs/问题 2: localhost:1883 无法在浏览器中打开
现象: 访问 http://localhost:1883 时浏览器显示:
- "该网页无法正常运作"
- "ERR_EMPTY_RESPONSE"
- "连接被重置"
原因: 这是正常现象,不是错误!
1883 端口使用的是 MQTT 协议,不是 HTTP 协议。浏览器只能访问 HTTP/HTTPS 服务。
解决方案:
-
验证 MQTT 端口是否正常:
powershell1Test-NetConnection -ComputerName localhost -Port 18832# TcpTestSucceeded 应该显示 True -
使用 MQTT 客户端连接:
- 下载 MQTT Explorer
- 或使用命令行:
mosquitto_pub -h localhost -p 1883 -t "test" -m "hello"
问题 3: Grafana 端口 3002 已被占用
现象: 启动端口转发时报错:
1Error listen tcp4 127.0.0.1:3002: bind: Only one usage of each socket address原因: 端口 3002 已经被其他程序占用,或者已经有一个端口转发在运行。
解决方案:
-
检查端口占用:
powershell1netstat -ano | findstr :3002 -
使用不同的本地端口:
powershell1kubectl port-forward svc/opentwins-grafana 3003:802# 然后访问 http://localhost:3003 -
结束占用端口的进程:
powershell1# 找到进程 ID (PID)2netstat -ano | findstr :300234# 结束进程(谨慎使用)5Stop-Process -Id <PID> -Force
8.2 Pod 无法启动
问题: Pod 一直处于 Pending 或 ContainerCreating 状态
解决方案:
1# 查看 Pod 详细信息2kubectl describe pod <pod-name>34# 查看事件日志5kubectl get events --sort-by='.lastTimestamp'67# 检查镜像拉取状态8kubectl get pods -o wide常见原因:
- 镜像拉取失败:检查网络连接
- 资源不足:增加 Minikube 的 CPU 和内存配置
- 存储不足:清理 Docker 镜像和容器
8.3 端口转发失败
问题: 无法通过 localhost 访问服务
解决方案:
1# 检查端口是否被占用2netstat -ano | findstr :300234# 使用不同的本地端口5kubectl port-forward svc/opentwins-grafana 3003:8067# 检查服务是否存在8kubectl get svc opentwins-grafana8.4 Minikube 启动失败
问题: Minikube 无法启动
解决方案:
1# 查看详细日志2minikube start --alsologtostderr -v=734# 删除并重新创建5minikube delete6minikube start --cpus 4 --memory 8192 --disk-size 40gb --driver=docker78# 检查 Docker Desktop 是否运行9docker ps8.5 Telegraf CrashLoopBackOff
问题: opentwins-telegraf Pod 显示 CrashLoopBackOff
说明: 这是正常现象。Telegraf 在等待 InfluxDB 完全启动。一旦 InfluxDB 就绪,Telegraf 会自动恢复正常。
验证:
1# 检查 InfluxDB 状态2kubectl get pod -l app.kubernetes.io/name=influxdb234# 查看 Telegraf 日志5kubectl logs <telegraf-pod-name>8.6 内存不足
问题: Pod 被驱逐或 OOMKilled
解决方案:
1# 停止 Minikube2minikube stop34# 增加内存配置5minikube config set memory 1228867# 重新启动8minikube start九、性能优化
9.1 调整资源配置
根据实际使用情况调整 Minikube 资源:
1# 停止 Minikube2minikube stop34# 调整配置5minikube config set cpus 66minikube config set memory 1228878# 重新启动9minikube start9.2 持久化数据
默认情况下,数据存储在 Minikube 虚拟机中。如果需要持久化数据:
1# 查看持久卷2kubectl get pv3kubectl get pvc45# 备份数据(以 MongoDB 为例)6kubectl exec -it <mongodb-pod-name> -- mongodump --out /tmp/backup7kubectl cp <mongodb-pod-name>:/tmp/backup ./mongodb-backup9.3 镜像缓存
为了加快后续部署,可以预拉取镜像:
1# 进入 Minikube2minikube ssh34# 手动拉取镜像5docker pull eclipse/ditto-gateway:latest6docker pull grafana/grafana:latest7# ... 其他镜像十、总结
10.1 部署清单
完整的部署流程包括:
- ✅ 安装 Docker Desktop
- ✅ 安装 Chocolatey(可选)
- ✅ 安装 Helm
- ✅ 安装 Minikube
- ✅ 启动 Kubernetes 集群
- ✅ 部署 OpenTwins
- ✅ 配置端口转发
- ✅ 访问和配置服务
10.2 关键要点
- 网络访问: Windows 上必须使用端口转发,不能直接访问 Minikube IP
- 资源配置: 确保分配足够的 CPU 和内存(最低 4 核 8GB)
- 部署时间: 首次部署需要 20-25 分钟,主要时间用于下载镜像
- Telegraf 重启: 在 InfluxDB 启动前会出现 CrashLoopBackOff,这是正常现象
10.3 快速访问
部署完成后,通过以下地址访问:
- Grafana: http://localhost:3002 (admin/admin)
- Ditto API: http://localhost:8080 (API 文档: /apidoc/)
- Extended API: http://localhost:8081/docs/ (注意:根路径会显示 "Cannot GET /")
- InfluxDB: http://localhost:8086
- MQTT: localhost:1883 (⚠️ 不能用浏览器访问,需要 MQTT 客户端)
10.4 常见问题速查
| 问题 | 原因 | 解决方案 |
|---|---|---|
| localhost:8081 显示 "Cannot GET /" | 正常现象,根路径未配置 | 访问 http://localhost:8081/docs/ |
| localhost:1883 无法在浏览器打开 | MQTT 协议不是 HTTP | 使用 MQTT Explorer 或 MQTT 客户端 |
| 端口 3002 已被占用 | 端口转发已运行或端口冲突 | 使用 netstat 检查,或换个端口 |
| Telegraf CrashLoopBackOff | 等待 InfluxDB 启动 | 等待几分钟,会自动恢复 |
| Pod 一直 ContainerCreating | 正在拉取镜像 | 首次部署需要 15-25 分钟 |
10.5 后续步骤
- 熟悉 Grafana 仪表板
- 学习 Ditto API 使用
- 创建自己的数字孪生实例
- 集成 MQTT 设备
- 开发自定义应用
十一、参考资源
官方文档
推荐工具
- MQTT Explorer - MQTT 客户端(图形界面)
- Postman - API 测试工具
- Visual Studio Code - 代码编辑器
文档版本: 1.0
最后更新: 2025-01-14
测试环境: Windows 11 Pro, Docker Desktop 28.5.1, Minikube 1.37.0, Kubernetes 1.34.0
参与讨论