实验制作 Pi Zero Cluster


之前试用了一下 ArduCam Multiple Camera Adapter,基本上实现了一个 Raspberry Pi Zero 拖四个摄像头。但是缺点也是显而易见的:

  1. 贵!这个多摄像头转接板在 RobotShop CA 上面卖 $64.99+tax。
  2. 慢!每个摄像头拍一张照片大概要 5 秒,四个摄像头只能顺序拍摄,不能同时拍摄

于是,想出一个念头,能不能用 Pi Zero Cluster 来代替这个转接板呢?

I. 系统结构

                        +--------------+     +--------+
                   +----|  Cluster Pi  |=====| Camera |
                   |    +--------------+     +--------+
                   |
                   |    +--------------+     +--------+
                   +----|  Cluster Pi  |=====| Camera |
+-------------+    |    +--------------+     +--------+
|   Host Pi   |----+
+-------------+    |    +--------------+     +--------+
                   +----|  Cluster Pi  |=====| Camera |
                   |    +--------------+     +--------+
                   |
                   |    +--------------+     +--------+
                   +----|  Cluster Pi  |=====| Camera |
                        +--------------+     +--------+

              |_________|              |_____|
                USB 2.0                  CSI

II. 为什么用 Pi Zero?

可行性

因为 Pi Zero 可以开启 Ethernet gadget 模式,也就是将 USB OTG 端口虚拟成网卡,USB 连接线虚拟成网线,这样一来就有了高速稳定的网络连接(USB 2.0 最大连接速度 480Mbps)。

成本

每个 Pi Zero 的售价差不多是 $7,USB 线大概 $1,USB Hub 好一点的 $15 能搞定,这差不多就是 $47 了。如果 SD 卡能控制在每张 $4.5 左右,成本就基本上持平。还是能做到的。

SD 卡启动还是 USB Boot

使用 USB Boot 的确能省下 SD 卡的成本,但是其弊端也是比较明显的。

  1. USB Boot 一次只能启动一个 Cluster Pi,这样不仅仅是顺序启动增加时间,还需要控制每一个 Cluster Pi 的供电,增加了系统复杂性。
  2. USB Boot 需要通过 NFS 挂载系统镜像,这需要严格的网络控制(MAC/IP 分配)

更多关于 USB Boot 的细节可以参考 Super-cheap Computing Cluster for LearningHow do I setup usbboot for the Cluster HAT?

III. 开启 Ethernet gadget 模式

只有 Cluster Pi 需要开启 Ethernet gadget 模式。

  1. 首先刷写一张 Raspbian
  2. 如果用 Windows 10,可以在 WSL (Ubuntu or Debian) 里面挂载 boot 分区
    sudo mount -t drvfs F: /mnt/sdcard
  3. 打开 boot 分区的 config.txt 并在最后添加一行
    dtoverlay=dwc2
  4. 打开 boot 分区的 cmdline.txt 找到 rootwait 然后在后面加一个空格,再写上
    modules-load=dwc2,g_ether
  5. 在 boot 分区下建一个 ssh 文件
    touch ssh

打开了 Ethernet gadget 模式之后,可以只用一根 USB 线,插入 Raspberry Pi Zero 的 OTG 口。如果接上 HDMI 线的话,能看到 Pi Zero 启动后自动为 usb0 设置了 169.254.x.x IP 地址。

参考资料:Simple guide for setting up OTG modes on the Raspberry Pi Zero

IV. 怎样设置网络?

Host Pi

Host Pi 需要设置 IP 转发。

  1. /etc/sysctl.conf 添加(或修改)一行
    net.ipv4.ip_forward=1
  2. 将出站流量伪装成本地发出的流量
    sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
  3. /etc/rc.local 里面,exit 0 之前加上
    iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

然后设置 IP 地址,在 /etc/network/interfaces 里面加上

allow-hotplug usb0 usb1 usb2 usb3
auto br0
iface br0 inet static
    address 192.168.10.254
    network 192.168.10.0
    netmask 255.255.255.0
    broadcast 192.168.10.255
    bridge_ports usb0 usb1 usb2 usb3

Cluster Pi

首先要区分 Cluster 里面的各个 Pi Zero。我的思路是用 GPIO 来区分。在 Pi Zero 启动的时候,读取 GPIO 来确定自己在 Cluster 里面的位置,然后自行设定 IP 地址

sudo ifconfig usb0 192.168.10.1 netmask 255.255.255.0 broadcast 192.168.10.255
route add default gw 192.168.10.254

这个脚本甚至都可以放在 boot 分区,然后在 /etc/rc.local 里面执行。

V. 设置 NFS

Host Pi

  1. 安装 NFS
    sudo apt-get install nfs-common nfs-kernel-server
  2. 建立共享目录
    sudo mkdir -p /srv
  3. 发布共享目录,在 /etc/exports 里面加上
    /srv 192.168.10.0/24(rw,sync,no_subtree_check)
  4. 重启 NFS 服务
    sudo service nfs-kernel-server restart

Cluster Pi

  1. 安装 NFS
    sudo apt-get install nfs-common
  2. 建立共享目录
    sudo mkdir /host
  3. 修正权限
    sudo chown -R pi:pi /host
  4. 挂载共享目录
    sudo mount 192.168.10.254:/srv /host

VI. 从 Host Pi 通过公钥(免密码)登陆 Cluster Pi

Host Pi

  1. 生成 SSH 密钥对
    ssh-keygen -f id_rsa -t rsa -N ''
  2. 将公钥放置在 NFS 共享目录中
    cp /home/pi/.ssh/id_rsa.pub /srv/host.pub
  3. 注册 Cluster Pi 的 SSH 主机指纹
    ssh-keyscan -H 192.168.10.1 >> ~/.ssh/known_hosts

Cluster Pi

  1. 手工建立 .ssh 目录
    mkdir -p /home/pi/.ssh
  2. 将公钥放置在 .ssh 目录下
    cp /host/host.pub /home/pi/.ssh/authorized_keys
  3. 修正权限
    chmod 700 /home/pi/.ssh && chmod 600 /home/pi/.ssh/authorized_keys

然后就可以从 Host Pi 直接 SSH 到 Cluster Pi 了。

添加新评论