树莓派搭建开发环境
背景
自从上次心血来潮给树莓派装完系统,一直没想好怎么具体使用它的场景,它就这样默默地躺在抽屉吃灰了一年
再次想起它,是一个周日的下午:收到之前在腾讯云买的云服务器快过期的提醒,一个4核8G内存的ubuntu,平时主要用它作为开发机,在本地电脑性能不够的时候,辅助 调试代码,以及 编译服务 ,还是非常顺滑的
但随后登录控制台,一看续期的价格,同样性能比去年要贵个200多(去年 388,今年 646),横向对比了国内几个云厂商价格也都差不多,索性放弃续期了,想着有没有其他办法整个独立的开发环境呢?
让家里台式机一直跑着是种方法,windows 的 wsl 已经非常完善,完全可以当 linux 开发机用了
不过目前自己要跑的服务,也用不上台式机的性能,还有没有更轻量运行的方式呢?
这不就正好,终于可以重新唤醒尘封已久的树莓派咯。虽然4U4G的性能说不上绰绰有余,但就跑几个服务来说还是足够的
本文内容
搭建开发环境(docker、各开发语言、code server)
文件服务器(samba)
监控(prometheus + grafana + node exporter)
远程桌面连接
智能开关
后续展望
系统准备
我的树莓派上安装的是 ubuntu 22,通过 raspberry pi imager(官方刷系统工具)刷入系统并安装,具体的安装可以参考去年写的博客
安装开发环境
笔者比较熟悉的开发模式: docker + 各语言开发环境 + vscode,在树莓派上原样进行安装
docker
安装 docker 的目的主要是能快速启动与主机环境隔离的容器,并进行服务编译。特别是编译 C++ 服务的时候,centos、ubuntu 这类的系统镜像自带的 gcc、glibc 版本往往不足要求,需要升级,但 glibc 的升级稍有操作不慎,又会对系统本身造成影响,所以还是建议在容器中编译相关服务
1 | 使用阿里源安装 docker |
安装后查看版本:
1 | ❯ docker -v |
关于在国内拉取容器镜像下载加速方式: 对不同的镜像仓库,如 docker hub 官方镜像、registry.k8s.io(kubernetes 相关服务的镜像仓库,旧域名是 k8s.gcr.io)、quay.io(红帽镜像仓库)等,使用的仓库代理地址各有不同
1 | 原拉取镜像方式 |
各个语言的开发环境
关于各种开发语言如何安装环境,网上教程一大把,过程无外乎是下载和解压安装包、环境变量配置和下载源配置,熟悉了操作也快,但每次重装系统,或者基于一个基础镜像安装开发环境,都需要重新操作一遍还是挺麻烦的
笔者把常用语言和服务的安装脚本整理在 shell-tools 这个仓库了,可以直接一行指令帮我安装,还可以指定需要安装的版本
比如安装 go、java、python 和 nodejs:
1 | go_version: 指定版本,默认版本在 Makefile.vars.version 中定义 |
升级 gcc、glibc,也可以使用这个脚本
1 | 升级 gcc 到 12.3.0 |
code server
关于 vscode 之前写过常用插件的介绍,远程开发模式下,本地装 vscode,通过 remote ssh 连接到远端服务器,再安装各个开发语言的插件,体验还是很丝滑的
架构如上图: 本地运行 vscode 的前端UI框架,后台服务器自动运行 vscode server,负责具体项目和具体开发语言的插件的运行,并提供 debugger、terminal 等功能
更进一步,我们还可以直接在远端服务器安装 code server,它是 vscode 的在线版,相当于UI服务也在服务器上运行,直接通过浏览器就能打开了
vscode 和 code server 的对比如上图,区别就是 nodejs(即 UI)也是运行在服务器上的,本机只需打开浏览器即可
code server 在树莓派的安装和配置方式如下:
1 | 通过 shell-tools 安装 code server 4.19.0 |
之后打开 http://树莓派内网ip:8080 就能开始愉快地享受网页版 vscode 了
扩展: 如果你想把 code server 提供给小伙伴们一起使用,配置就比较麻烦了,需要加一层 oauth proxy 或其他代理,以支持多用户登录。 jupyterhub 也是一种选择,后续有机会可以写写具体怎么做
文件服务器
除了用于开发,树莓派作为常驻 linux 主机,还可以安装 samba 并作为文件服务器,视频、音乐等媒体统一放到一块硬盘上,作为本地的媒体库
samba
samba 服务对应的 SMB(Server Message Block) 是一种在局域网中共享文件的协议,直接说下它在linux系统的安装方法
1 | 安装 samba,并添加 samba 的访问用户(注意和系统用户不同) |
安装后,在 /etc/samba/smb.conf 中配置开放访问的目录
1 |
|
挂载机械硬盘
在尝试把之前买的机械硬盘(作为媒体数据盘)挂载到树莓派的时候,遇上了一点小问题: 硬盘格式已经是 NTFS 并且放了一些数据了,但linux 系统无法直接读取,需要安装 ntfs-3g 驱动才行
1 | apt -y install ntfs-3g |
并在 /etc/fstab 中设置开机自动挂盘,参考
1 | /dev/sdb1 /data/music ntfs-3g defaults,nofail,uid=1000,gid=1000,umask=0007,x-systemd.device-timeout=5 0 0 |
远程桌面
对 linux 系统来说,平时开发写写代码敲敲指令,是不太需要访问桌面的。不过有时想体验 linux 版的应用(QQ),还是可以装个远程桌面来体验一下
常见的远程桌面协议是 xrdp 和 vnc,这里我们通过 xrdp 来配置:
1 | 安装 xrdp |
xrdp 的端口 3389 可以在 /etc/xrdp/xrdp.ini 配置中查看和修改
然后通过 microsoft remote desktop 连接:
非常简洁的桌面
然后我们可以安装新版适配了 linux 的 QQ,从官网下载
1 | 下载 |
监控
到这一步,我们给树莓派装的开发环境算是基本弄好了,可以愉快地在上面构建镜像、运行服务,不过摸着那微微发烫的 cpu,担心也随之而来: 是不是有个好看的面板,能直接看到当前树莓派的状态,做个监控更好呢?
那就话不多说,开始整看板吧
获取树莓派的性能指标
先来看看命令行获取树莓派 cpu 的温度的方式:
参考-使用 vcgencmd 指令查看 Raspberry Pi 的 CPU 溫度、運行速度與電壓等資訊
1 | vcgencmd measure_temp | grep -o -E '[[:digit:]].*' |
vcgencmd 指令是基于树莓派的内核 firmware 自带的指令,能拿到关于系统资源和硬件状态相关信息,如时钟频率、电压、内存等
但通过指令获取参数的方式,采集起来需要额外写脚本,相比 exporter 的方式来说还是不太方便,那么有没有原生的 exporter 可以直接拿到温度数据呢?
node exporter
前面说的系统指令只是粗略看看 cpu 的指标,要想持续监控,还得通过 prometheus 采集、exporter 提供系统指标的机制,把相关指标提前暴露出来
node exporter 是提供系统相关监控指标的服务,在树莓派上部署它的 arm 版本后,可通过 node_thermal_zone_temp 指标获取温度,数据来源是系统文件 /sys/class/thermal/thermal_zone0/temp 即由系统直接提供的 cpu 温度数据
部署 prometheus、node exporter 和 grafana
继续使用 shell-tools 工具一键安装
1 | 安装 prometheus 和 node exporter |
安装后,在 prometheus 配置文件中添加 node exporter 的本地地址即可开始采集指标
1 | # vim /opt/modules/prometheus/prometheus.yml |
prometheus 对接 grafana
采集到指标后,关键的一步就是用“酷炫”的grafana看板展示出来,让我们能及时看到系统状态
node exporter 的官方的看板是 node exporter full,分类非常详细,导入看板的 json 文件,并添加 prometheus 数据源(localhost:3001)即可
开机服务自动启动
前面我们给树莓派已经安装了一系列服务,那么有时候树莓派要重启,我们会想让这些服务也在系统重启后自动启动。docker 这种通过 systemctl 管理的服务,直接执行 systemctl enable docker 就可以了,手动安装的 code server 、prometheus,应该怎么配置呢?
方法也有很多种,常见的有: rc.local、init.d、crontab @reboot 等方法,它们执行的时机各有不同
什么时候触发执行
linux 系统启动后,/sbin/init 脚本会进行一众系统服务的初始化,顺序我们可以通过 systemd-analyze plot > startup_order.svg 导出,一些自动启动的脚本启动顺序如下:
/etc/init.d: 最先初始化的一批系统服务
rc.local: network 即网络服务启动之后
crontab @reboot: network 启动之前
为什么要特别提到启动顺序,因为有的服务依赖网络相关的基础服务(如网卡初始化),如果通过 /etc/init.d 或是 crontab @reboot 很可能启动失败。相对比,rc.local 的启动顺序较后,可以保证在系统基础服务启动后开始。另外从配置方式来看,systemctl 和 /etc/init.d 都需要基于一定的格式规范,如服务名、依赖哪些服务等,rc.local 则直接写入服务的启动指令即可
下面我们来看看 rc.local 如何配置
rc.local 添加服务启动指令
root 用户下编辑 /etc/rc.local 文件,添加服务的启动指令
1 | vim /etc/rc.local |
之后通过 chmod +x /etc/rc.local 添加可执行文件,重启树莓派再次登录,可以看到相关服务已经运行起来了
另一个注意点是 rc.local 中的指令是串行执行,前面的指令报错,后面的也不会执行,所以也建议通过 nohup 即后台方式启动服务
智能插座
毕竟性能有限,随着我们在树莓派上部署的服务越来越多,也难免会遇到资源用尽,直接卡住无法连接的情况,除了重启没有别的恢复办法
好几次在外面远程连接家里树莓派,跑了几个比较吃资源的服务卡住之后,又没法重启,真的是很无奈,索性搞了个小米智能插座,感受了一波物联网带来实际的便利
后续展望
经过了一个多月的折腾,我的树莓派终于可以作为开发服务器长期跑起来了。相比开头说的云服务器,性能方面稍弱,但也带来可以对接本地数据、可随时在手机端重启等好处
之后还能在上面跑什么服务,或者还能和现实世界有什么交互呢?我也还没有特别想好,就粗略地列一列零散的点子吧,看看以后有没有时间继续折腾一下
nas: 我是真没想到竟然真有人去把树莓派当作 nas,参考,数据传输速度上的瓶颈应该还是挺明显的,当作小型文件服务器才比较现实
本地文档库+媒体库: 归档自己所有的音乐、相册、视频、电子书等
传感器: 搞个空气质量检测器,参考