在 Docker Desktop 中使用 USB/IP

引入于 Docker Desktop 版本 4.35.0

注意

可在 Docker Desktop 的 Mac、Linux 和 Windows 版本上使用,需启用 Hyper-V 后端。

USB/IP 使您能够通过网络共享 USB 设备,这些设备随后可在 Docker 容器内访问。本页面重点介绍如何共享连接到您运行 Docker Desktop 的主机上的 USB 设备。您可以根据需要重复以下流程,以附加和使用其他 USB 设备。

注意

Docker Desktop 的虚拟机内核镜像已预先配置了多种常见 USB 设备的驱动程序,但 Docker 无法保证所有可能的 USB 设备都能在此设置下正常工作。

设置与使用

第一步:运行 USB/IP 服务器

要使用 USB/IP,您需要运行一个 USB/IP 服务器。在本指南中,将使用 jiegec/usbip 提供的实现。

  1. 克隆代码仓库。

    $ git clone https://github.com/jiegec/usbip
    $ cd usbip
    
  2. 运行模拟的人机交互设备(HID)示例。

    $ env RUST_LOG=info cargo run --example hid_keyboard
    

第二步:启动一个具有特权的 Docker 容器

要附加 USB 设备,请以特权模式启动一个 Docker 容器,并将 PID 命名空间设置为 host

$ docker run --rm -it --privileged --pid=host alpine

步骤三:进入 PID 1 的挂载命名空间

在容器内,进入 init 进程的挂载命名空间,以访问预先安装的 USB/IP 工具:

$ nsenter -t 1 -m

第四步:使用 USB/IP 工具

现在,您可以像在其他任何系统上一样使用USB/IP工具:

列出USB设备

列出主机上可导出的USB设备:

$ usbip list -r host.docker.internal

预期输出:

Exportable USB devices
======================
 - host.docker.internal
      0-0-0: unknown vendor : unknown product (0000:0000)
           : /sys/bus/0/0/0
           : (Defined at Interface level) (00/00/00)
           :  0 - unknown class / unknown subclass / unknown protocol (03/00/00)

连接 USB 设备

要附加特定的 USB 设备,或在此情况下附加模拟键盘:

$ usbip attach -r host.docker.internal -d 0-0-0

验证设备连接

连接模拟键盘后,请检查 /dev/input 目录中的设备节点:

$ ls /dev/input/

示例输出:

event0  mice

步骤五:在另一个容器中使用已附加的设备

虽然初始容器仍在运行以保持USB设备正常工作,但您可以通过另一个容器访问已连接的设备。例如:

  1. 使用附加设备启动一个新容器。

    $ docker run --rm -it --device "/dev/input/event0" alpine
    
  2. 安装类似 evtest 的工具以测试模拟键盘。

    $ apk add evtest
    $ evtest /dev/input/event0
    
  3. 与设备进行交互,并观察输出结果。

    示例输出:

    Input driver version is 1.0.1
    Input device ID: bus 0x3 vendor 0x0 product 0x0 version 0x111
    ...
    Properties:
    Testing ... (interrupt to exit)
    Event: time 1717575532.881540, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7001e
    Event: time 1717575532.881540, type 1 (EV_KEY), code 2 (KEY_1), value 1
    Event: time 1717575532.881540, -------------- SYN_REPORT ------------
    ...
    

重要

初始容器必须保持运行状态,以维持与USB设备的连接。退出容器将导致设备停止工作。