內容目錄

macOS下的 multipass-vscode 编译环境建立

依據此篇做了一個script。太長不看的可以去這裡

[toc]

Part 1. 虚拟机与工具设置

0. 介绍

Canonical 公司为其 Ubuntu系统制作了 multipass 轻量的跨平台的虚拟环境,可在linux的KVM、 Windows 的 Hyper-V 和 macOS 的 HyperKit 虚拟技术下,以較少的资源和性能损耗,快速的建立轻量的虚拟机实体,用起來比docker簡單方便。

Canonical官方维护的ubuntu镜像,都可以用来快速的建立虚拟机实体。目前对x86 macOS宿主提供的虚拟机镜像有:

$ multipass find

Image                       Aliases           Version          Description
snapcraft:core18            18.04             20201111         Snapcraft builder for Core 18
snapcraft:core20            20.04             20210921         Snapcraft builder for Core 20
snapcraft:core22            22.04             20220426         Snapcraft builder for Core 22
18.04                       bionic            20221207         Ubuntu 18.04 LTS
20.04                       focal             20221213         Ubuntu 20.04 LTS
22.04                       jammy,lts         20221214         Ubuntu 22.04 LTS
anbox-cloud-appliance                         latest           Anbox Cloud Appliance
charm-dev                                     latest           A development and testing environment for charmers
docker                                        latest           A Docker environment with Portainer and related tools
jellyfin                                      latest           Jellyfin is a Free Software Media System that puts you in control of managing and streaming your media.
minikube                                      latest           minikube is local Kubernetes

底下幾個特殊的鏡像我目前沒有嘗試,其中docker鏡像可參考網上找的這篇。。。

不同项目的SDK可能有不同的系统库需求,往往会造成相互间的冲突。对每个开发环境建立轻量、干净的虚拟环境来执行工作,是很好的解决办法。

例如 OpenWRT SDK,不能在 ubuntu 20.04 及以上的环境无痛的编译。我们可以使用 multipass 轻易的建立一个 ubuntu 18.04 开发环境,将 OpenWRT 的 SDK和导入的系统库,隔离到此虚拟机实体上运行。

VS Code越来越多人使用了,跨平台、提供大量插件、且容易客制化。新版的 VS Code提供了 Remote SSH插件,这样我们只要在宿主机安装一套 VSCode,设定好每个虚拟机实体的 sshd 服务,所有的虚拟机实体可使用同一套 VS Code,不同的插件环境配置,定制自己的IDE环境来工作。

有的应用场景会需要执行虚拟机中的图形应用。除了在虚拟机下安装X11桌面环境,再使用 RDP或VNC连接虚拟机桌面的方法外,我们可在host上建立X11 服务,直接将虚拟机的X11 GUI输出转向到宿主机。三大平台都有可用的X11服务器。宿主机若是Linux可直接使用X11服务,Windows 下可使用Xming/VCXrv 应用,macOS下可使用XQuartz 应用来提供X11服务。

HyperKit/Hyper-V 等轻量虚拟化技术使用系统资源较低,但并未模拟整机。在嵌入式开发的场景下,会需要透过USB或其他周边来完成烧录、仿真等工作,此时我们会需要透过宿主机的工具来运行。利用scp、sshfs、或SAMBA 文件服务可以将文件复制,或将文件系统共享给宿主机来完成这些硬件需求的工作。

使用Multipass也可将建立好的虚拟机实体切换到 Virtualbox 虚拟环境执行,有机会利用 Virtualbox 挂载USB周边,在虚拟机中控制管理设备。但当虚拟系统越来越复杂,直接采用 Parallels/Virtualbox/Vmware 或其他完整的模拟器工作会更为直观。

在此我们依照定制项目的需求,一步步的完成 multipass + VS Code IDE 开发环境建设工作。

在此我们使用一个自动化的脚本,用很少的选项自动生成虚拟机,并做需要的设定。以下分章节介绍此脚本。并在附录张贴完整脚本。

0. 使用 brew 在Mac上 安装 multipass

使用 brew cask 安装管理 multipass,以后可以随 brew upgrade 更新:

brew cask install multipass

1. 建立 multipass 虚拟机

multipass 使用 launch 命令建立虚拟机,我们用 vm(虚拟机名)、img(选择的ubuntu镜像)、usr(RDP远端桌面用户名)。core(虚拟机CPU核心数)、mem(虚拟机RAM大小)、disk(虚拟机磁盘大小)当选择参数。

usr 参数只在安装RDP时添加额外的用户账户,建立虚拟机时不使用。

#==============================================================
# 1. 建立 multipass 虚拟机
# 1.1 Script 缺省的参数依序为:虚拟机名稱、选择的ubuntu镜像、RDP(远端桌面)用户名。
export vm=u20 
export img=20.04
export usr=cyue
if [ "" != "$1" ];then export vm=$1; fi
if [ "" != "$2" ];then export img=$2; fi
if [ "" != "$3" ];then export usr=$3; fi

# 1.2 虚拟机的 CPU数、记忆体容量、硬盘容量定义在此,依宿主机调整:
export core=8
export mem=8G
export disk=80G

# 1.3 安装 multipass app (使用万能的 brew):
#     brew install --cask multipass

# 1.4 依据前面的参数建立虚拟机:
echo multipass launch  -c $core -m $mem -d $disk -n $vm  $img
multipass launch  -c $core -m $mem -d $disk -n $vm  $img

2. 国内源处理

没有梯子是很困扰的,各种工程下载缓慢或失败。还好ubuntu的apt与snap国内有镜像可使用。

snap proxy 的两个包很大,并且也是用 snap 下载,由于我们现在只需要用snap下载 multipass-sshfs,可依自己的需求决定是否安装。

#==============================================================
# 2. 国内源处理
# 2.1 apt 更换为中科大 ustc 源
multipass exec $vm --  sudo cp /etc/apt/sources.list /etc/apt/sources.list.org
multipass exec $vm --  sudo sed -i 's@archive.ubuntu.com@mirrors.ustc.edu.cn@g' /etc/apt/sources.list
multipass exec $vm --  sudo sed -i 's@security.ubuntu.com@mirrors.ustc.edu.cn@g' /etc/apt/sources.list
multipass exec $vm --  sudo apt update -y 
multipass exec $vm --  sudo apt upgrade -y

# 2.2 snap 国内proxy设定(视需要)
# multipass exec $vm --  sudo snap install snap-store-proxy
# multipass exec $vm --  sudo snap install snap-store-proxy-client

3. 挂载主機共享文件夹

许多主机资源可以提供虚拟机使用,multipass内部使用变种的sshfs,可以让虚拟机挂载(mount) 主机的分区或文件夹。此script示范挂载两个主机目录到虚拟机的 /mnt 下,一个是用户 home(~),一个是主机的区分大小写分区(/Volume/Work

#==============================================================
# 3. 挂载主機共享文件夹
# 3.1. 安装 multipass-sshfs 以挂载主机文件夹
multipass exec $vm --  sudo snap install multipass-sshfs

# 3.2 挂载主机文件夹(到 /mnt 下)如:
multipass mount   /Volumes/Work $vm:/mnt/work 
multipass mount   ~  $vm:/mnt/host

# 3.3 macOS 多了一层权限管理,需要允许 multipassd 的磁盘访问权限:
#   打开 设定app --> 安全性与隐私 --> 隐私页 --> 左下角解锁 --> 完全磁盘访问权限 --> 勾选允许 multipassd

⚠️注意:由于 macOS新增加了应用的文件可存取权限管理,安装 multipass后应该打开 multipassd的完全磁盘访问权限,受macOS保护的文件系统内容才能挂载到虚拟机中使用。方法:
打开 设定app --> 安全性与隐私 --> 隐私页 --> 左下角解锁 --> 4. 完全磁盘访问权限 --> 勾选允许 multipassd ,参考下图:


4. ssh 连接设置

ssh 是安全加密的通信方式。虽然 multipass 提供了 shellsh)命令可以快速切入虚拟机的终端,但 VScode 等其他应用使用的还是标准ssh。

这里的script除了为虚拟机安装 ssh,还设置了金钥,并让主机与虚拟机交换金钥,可以方便、免密的ssh到虚拟机。

4.1 宿主机安装配置ssh检查

  • Linux Desktop 和 macOS一般已安装好了ssh client/server。
  • Windows要从市场安装 OpenSSH。
  • 若宿主机账户下 ~/.ssh/id_rsa.pub 文件不存在,执行 ssh-keygen 建立金钥。
    ⚠️:若文件存在请不要重建金钥,以免对其他网路设备连接失败。
# 1 宿主机也使用 `ssh-keygen` 建立 ssh 公钥。
#    若已有 ~/.ssh/id_rsa.pub 文件,请勿执行 `ssh-keygen`,以免对其他网路设备连接失败。

# 2 VM 安装 ssh,并执行 `ssh-keygen` 
#    使用缺省多次 enter后,公钥放在 ~/.ssh/id_rsa.pub
multipass exec $vm -- sudo apt install ssh -y
multipass exec $vm -- ssh-keygen

# 3 sshd 守护进程设定
#     打开密码,允许无密码登入、重启 sshd 
multipass exec $vm -- sudo sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config
multipass exec $vm -- sudo sed -i 's/#PermitEmptyPasswords no/PermitEmptyPasswords yes/g' /etc/ssh/sshd_config
multipass exec $vm -- sudo service sshd restart

# 4 绑定VM的ssh别名、并交换公钥
# 绑定虚拟机名称和虚拟机IP
echo "\nHost $vm\n  HostName $(multipass ls | grep $vm | awk '{print $3}')\n  User ubuntu" >> ~/.ssh/config
# 允许主机的本账号,免密ssh进虚拟机
multipass exec $vm -- sed -i "$ a\ $(cat ~/.ssh/id_rsa.pub)" .ssh/authorized_keys
# 允许VM的ubuntu账号,免密ssh进主机
multipass exec $vm -- cat /home/ubuntu/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys

# 5 将inode数调到最大,以利未来VSCode工作
#    Vscode 会同时操作多个文件,将inode数给到到最大值(524288)并重置此值。
multipass exec $vm -- sudo sed -i "$ a\fs.inotify.max_user_watches=524288" /etc/sysctl.conf
multipass exec $vm -- sudo sysctl -p

#显示安装的虚拟机信息
multipass info $vm 

5 宿主机 VScode 安装设置(可改成直接虚拟机安装)

VScode是微软的跨平台、多语种、可扩展的整合开发环境(IDE)。

5.1 宿主机安装 Vscode

  • 从微软下载适用于不同平台的 Visual Studio 应用。解压后放到 Applications 文件夹。

  • macOS可使用 brew 命令下载:

# 6 宿主 vscode安装:
brew install visual-studio-code

5.2 Vscode 中安装Remote SSH 扩展

点击扩展图标,搜索安装 “Remote – SSH” 扩展,用于连接到 SSH 宿主机。

5.3 Vscode 远端连线设置

登入或修改 ssh宿主机config

  • 安装远程 – SSH 扩展后,您将在最左下角看到一个新的状态栏项目(连线图标)。点击后弹出连接选项:

  • 点击 “Connect to Host” 可寻找 ~/.ssh/config 文件已定义的ssh服务器/虚拟机,或添加已知机器。也可以点击“Open SSH Configuration File” 去修改 ~/.ssh/config 文件内容,增删 ssh 虚拟机设定。
    我们选择之前已添加的 tina 虚拟机。

  • 第一次尝试连接时,会询问是否安装远端机器金钥(安装到本地 ~/.ssh/known_hosts ),选 continue 继续。VSCode还会在远端机器上安装 VSCode Server,以提供远端协同开发的能力。

  • 若之前有将主机的账户金钥保存到虚拟机账户的 .ssh/authorized_keys ,登录时就不会询问连线账户的密码了。

  • 连接成功后,点击左上角文件夹图标,打开虚拟机中的工程文件夹。

  • 可以编译工程文件了。在Vscode 主菜单的 “查看”下选择“终端”,app 右下方会切割出一个登入到虚拟机的终端框。我们可以直接在此终端框做编译工程的命令,或其他对虚拟机的操作了。

可以用 VS code IDE做开发工作了。。。


6. 为虚拟机添加图形界面

需求场景案例:

  • 场景1: 若我们开发的是 Linux下的GUI程式,当然会需要能能透过X11来显示了。
  • 场景2: 有些GUI工具只有Linux版本,没有macOS/Wondows版本,我们就需要在虚拟机中运行他们。

除了可以在虚拟机安装各种桌面环境,并安装VNC或RDP服务,供宿主机登入的方式外,我们可以在宿主机端安装 X11服务,直接将虚拟机的GUI显示输出指向到宿主机。这是这章要做的。

本章提供两种方式让虚拟机输出图像到主机上:

  • 第一种方法是在宿主机端安装 X11服务(如 macOS的XQuartz),直接将虚拟机的GUI显示输出指向到宿主机。这个方法不必安装X11桌面,直接把应用的 X11 图形需求导向宿主机的 XQuartz显示。

  • 第二种方法是宿主机使用微软的RDP工具(Windows自带,macOS也可从微软取得),远端连接虚拟机桌面。

6.1 使用 XQuartz 提供虚拟机 X11 GUI(可选,非必要)

若有完整GUI桌面需求,可跳到下一节。使用RDP比 Xquartz更容易,不过较占用空间。

6.1.1 安装设定 XQuartz:

#==============================================================
# 6.1 提供虚拟机 X11 GUI - 使用 XQuartz(若只想要完整桌面跳到下一章)
# 6.1.1. 安装 XQuartz, 可用萬能的 brew:
brew install --cask xquartz

# 6.1.2. 設定 XQuartz app: 
#  xhost& 在背景打开 XQuartz.app。
#  - app菜单 --> 偏好 --> 安全性页面,勾选允许从网路客户端链接。
xhost&

# 6.1.3. 安装基础 X11庫,用于直连 host的 X11 。
multipass exec $vm -- sudo apt install xinit -y

# 6.1.4. VM X11相关的設定:
#  - 设定 DISPLAY 环境变量、链接主机 .Xauthority 文件、挂载主机 X11 暂存目录。
multipass exec $vm -- sed -i "$ a\export DISPLAY=$\(echo $\SSH_CLIENT |awk '{print $\1}'):0"  /home/ubuntu/.bashrc 
multipass exec $vm -- ln -s /mnt/host/.Xauthority .Xauthority
multipass mount /tmp/.X11-unix $vm:/tmp/.X11-unix

安装 script 在执行 xhost& 后,即在后台打开 xquartz app。我们需要对此app做设定;

打开 Xquartz 菜单 –> 偏好设置 — > 安全性,勾选允许从网路客户端链接即可。

6.1.2 要求虚拟机执行 GUI程式的 shell script

在虚拟机GUI程序开始前需要启动 xhost,并将虚拟机的IP添加给 xhost。

我们可以用以下 vmup.sh script 来 sh 进入虚拟机,就可以确保X11环境已工作,直接执行 GUI程式。

script的参数是虚拟机名。

#! sh
# 1. 缺省的虚拟机名稱。
export vm=tina

# 2. 若script有参数,第一个参数当虚拟机名。
if [ "" != "$1" ];then export vm=$1; fi

# 3. 确认macOS已开启xquartz
xhost&

# 4. 确认虚拟机已启动。
if [ "Running" != "$(multipass ls | grep $vm | awk '{print $2}')" ];then
multipass start $vm
fi

# 5. xhost 添加允许虚拟机IP连线。
xhost +$(multipass ls | grep $vm | awk '{print $3}')

# 6. ~/.Xauthority 已改用文件系统挂载,不用在 script 中复制。
#if [ "" = "$(multipass exec $vm -- ls -lia | grep .Xauthority)" ];then
# multipass transfer ~/.Xauthority $vm:/home/ubuntu/.Xauthority
#fi

# 7. 进入虚拟机的shell
multipass sh $vm

执行此script就会启动宿主机的X11服务,并打开虚拟机 shell。在此shell执行 X11 GUI 即可将GUI画面转到宿主机。

到此可执行GUI的虚拟环境建立完成。可以试试安装 xterm,或使用 apt/snap 安装其他 GUI 程式。

6.2 使用 XRDP 提供虚拟机远端桌面环境

想要完整的Ubuntu桌面?

希望直接使用主机周边(如喇叭、麦克风、摄像头、打印机、智慧卡)?(需要有 Virtual Driver实现,但 LibVrt还在试验中)
虽然会占用许多资源,但真的有需求时,我们可以在虚拟机安装 XRDP服务,让主机或其他机器可以Windows RDP模式连接虚拟机桌面。

6.2.1 虚拟机安装ubuntu桌面套件与xrdp服务

虚拟机中安装最小桌面与 xrdp 套件,并查看虚拟机 IP:

multipass exec $vm -- sudo apt install -y ubuntu-desktop-minimal xrdp

# 2. 解决RDP登录时反复验证问题
echo "[Allow Wifi Scan]
Identity=unix-user:*
Action=org.freedesktop.NetworkManager.wifi.scan;org.freedesktop.NetworkManager.enable-disable-wifi;org.freedesktop.NetworkManager.settings.modify.own;org.freedesktop.NetworkManager.settings.modify.system;org.freedesktop.NetworkManager.network-control
ResultAny=yes
ResultInactive=yes
ResultActive=yes" | multipass exec $vm -- sudo tee /etc/polkit-1/localauthority/50-local.d/47-allow-wifiscan.pkla

# 3. 解决“色彩管理设备” / “color managed device” 弹窗
echo "[Allow Colord all Users]
Identity=unix-user:*
Action=org.freedesktop.color-manager.create-device;org.freedesktop.color-manager.create-profile;org.freedesktop.color-manager.delete-device;org.freedesktop.color-manager.delete-profile;org.freedesktop.color-manager.modify-device;org.freedesktop.color-manager.modify-profile
ResultAny=no
ResultInactive=no
ResultActive=yes" | multipass exec $vm -- sudo tee /etc/polkit-1/localauthority/50-local.d/45-allow-colord.pkla

# 4. 解决“刷新系统软件源需要认证” / “refresh the system repositories” 弹窗
echo "[Allow Refresh Repository all Users]
Identity=unix-user:*
Action=org.freedesktop.packagekit.system-sources-refresh
ResultAny=no
ResultInactive=no
ResultActive=yes" | multipass exec $vm -- sudo tee /etc/polkit-1/localauthority/50-local.d/46-allow-packagekit.pkla

# 5. 注释掉 `AutomaticLoginEnable` 和 `AutomaticLogin` 变量:
multipass exec $vm -- sudo sed -i 's/AutomaticLoginEnable/#AutomaticLoginEnable/g' /etc/gdm3/custom.conf
multipass exec $vm -- sudo sed -i 's/AutomaticLogin/#AutomaticLogin/g' /etc/gdm3/custom.conf

# 重启RDP服务
multipass exec $vm -- sudo systemctl restart xrdp
# 查看 XRDP服务
multipass exec $vm -- sudo systemctl status xrdp


multipass ls | grep $vm

最后的虚拟机IP显示如下:

4:u20                     Running           192.168.64.5     Ubuntu 20.04 LTS

看到当前虚拟机 u20 的 IP 是 192.168.64.5。虚拟机是在本机网域,足够安全,为了方便使用,我们不为预设用户(ubuntu)设定密码。

Cyue: XRDP 第一次进入时必须要密码,否则无法进入。我们可以先对 ubuntu 设密码,连接 RDP桌面成功后,再取消密码:

  • 设定 ubuntu 的密码:
    sudo passwd ubuntu
    
  • 删除 ubuntu 的密码:
    sudo passwd -d ubuntu
    

6.2.2 主机安装 RDP Client app

在 App Store 中搜寻 RDP,下载微软的 “Microsoft Remote Desktop” 套件:

  • RDP添加 multipass虚拟机 IP、账户、昵称。之后就可以透过 RDP连虚拟机了。

将 IP、用户名称、虚拟机名填入,点击添加。

点击刚添加的虚拟机图标执行远端桌面:

我们没给 ubuntu 用户密码,直接选 OK。

之后就进入 Ubuntu桌面环境了。初始化时可以都 Skip跳过,就进入ubuntu桌面了。

点 Active — 所有App 图标,可看到最小安装所安装的应用(有两页)。

6.3 添加 OpenVPN Client 支持:

在 network 下 添加一行 renderer: NetworkManager

# netplan 使用 NetworkManager renderer,或可往前移到 `network:` 后
echo "    renderer: NetworkManager" | sudo tee -a /etc/netplan/50-cloud-init.yaml

sudo apt install -y openvpn network-manager-openvpn network-manager-openvpn-gnome
sudo netplan apply

6.3.1 自服务器下载 ovpn文件,然后在 RDP下 透过 NetworkManager 设定。。。

自服务器下载 ovpn文件,然后在 RDP下 透过 NetworkManager 设定 VPN。。。

image-20221129232437092

image-20221129232551586

注意:宿主機不能登入 OpenVPN,網路會衝突。虛擬機可以。

6.4 添加 Google Chrome 浏览器

# 从官网 amd64 版的chrome deb 包安装 chrome:
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo dpkg -i google-chrome-stable_current_amd64.deb
# 安装后透过 RDP 桌面执行 chrome,会有一些 keyring 密码与初始化要求。。。

6.5 直接在虚拟机安装 VsCode

使用RDP,就直接采用 linux版的 VSCode 当开发工具好了。官网 https://code.visualstudio.com/

https://code.visualstudio.com/Download 找arm64的deb下载包。

# 目前是 1.73.1 版
wget https://az764295.vo.msecnd.net/stable/6261075646f055b99068d3688932416f2346dd3b/code_1.73.1-1667966450_arm64.deb
# 安装
sudo dpkg -i code_1.73.1-1667966450_arm64.deb 

安装后可以从桌面 Activities下找到 应用执行。可长按icon,选 pin to dash,保留icon在 dashboard上。


Part 2 全志 D1-tina 编译环境设定

2.1 安装编译相依套件

全志 D1-tina 是基于openWrt工程建构。在 Ubuntu18.04 及以下的环境才可无问题的编译。首先先安装相依套件:

#安装相依套件
sudo apt install build-essential subversion git-core libncurses5-dev zlib1g-dev gawk flex quilt libssl-dev xsltproc libxml-parser-perl mercurial bzr ecj cvs unzip lib32z1 lib32z1-dev lib32stdc++6 libstdc++6 automake -y

2.2 建立全志账号

请在全志官网建立账号 https://open.allwinnertech.com/ ,才能下载 code。

2.3 在官网更新本机公钥

git仓库需要 rsa公钥才能工作。若本机还没有公钥,需要执行 ssh-keygen 生成。

#生成本机公钥, 需要连按几次 return
ssh-keygen 
# 显示本机公钥,并复制显示的文件内容。(从 “ssh-rsa” 到 “用户@主机” 的整个内容)
cat ~/.ssh/id_rsa.pub 


# 将复制的公钥黏贴到全志账户官网的公钥栏位中:
https://open.allwinnertech.com/#/sdk/0/key

2.4 更改repo为全志的版本:

#下载全志版本的 repo,cyue12改成你的全志账号
git clone ssh://cyue12@sdk.allwinnertech.com/git_repo/repo.git
# 用 sed将 repo/repo内的 username 更换成自己的账号(cyue12)
sed -i 's@username@cyue12@g' repo/repo
# 把 repo放到系统中
sudo cp repo/repo /usr/bin/repo && sudo chmod 777 /usr/bin/repo

2.5 使用 repo 下载官网 tina SDK 工程

#建立工程目录
mkdir tina-d1-open  
cd tina-d1-open 

# (若没设定过)设定全志 git 仓库的账户和email
  git config --global user.name "cyue12"
  git config --global user.email "cyue12@gmail.com"

# cyue12替换为您的全志客户服务平台账号
repo init -u ssh://cyue12@sdk.allwinnertech.com/git_repo/D1_Tina_Open/manifest.git -b master -m tina-d1-open.xml 

#同步 repo 仓库
repo sync 
# 仓库全部下载完成之后,创建分支 
repo start product-smartx-d1-tina-v1.0-release --all  

2.6 编译与打包

# 定义自己的新 branch
repo start d1-cyue-1.0 --all 
source build/envsetup.sh 

launch
# 选 d1_nezha-tina

make -j18
#打包成可烧录的 img 文件
pack 
#烧录文件在: /home/ubuntu/tina-d1-open/out/d1-nezha/tina_d1-nezha_uart0.img
# -rwxr-xr-x  1 ubuntu 501 32619520 Dec 19 15:46 tina_d1-nezha_uart0.img*

虚拟机性能验证:

  • 主机使用MBP15/2015

  • 三星970Evo Plus SSD的 【读|写】 速度约在 【2040MB/s|2378MB/s】

结果:几乎不影响编译,8核CPU能维持在接近 99%的使用率,编译耗时与 Parallels下几乎一致。

“`bash
#### make completed successfully (41:27 (mm:ss)) #### 首次编译耗时
#### make completed successfully (25:37 (mm:ss)) #### clean后重编译耗时
“`

2.7 烧录运行

multipass HyperV/Hyperkit 虚拟机不能挂载usb硬件,需要用宿主机工具将 img 文件烧录到目标平台。我们可以用SAMBA服务将文件夹共享给宿主机做操作。我们在第四章做SAMBA服务器安装介绍。
全志提供Windows/Linux/MacOS全平台的烧录工具 LiveSuit。用法如下:

  • 在 LiveSuit app中选好Image。
  • 按下D1 主板 fex按键不放。
  • USB TypeC口插入 host,放开 fex按键。
  • LiveSuit将自动升级 Firmware。
  • 升级完后可改用 type-C power 接口供电开机,并用USB转TTL UART线连接到主机。
  • Linux/macOS直接用 screen命令,115200bps 就可以连接开发板的UART terminal。
    (screen 使用 Ctrl-A + Ctrl-D 退出)
screen /dev/cu.usbserial-A50285BI 115200
root@TinaLinux:/# 
root@TinaLinux:/# exit
Please press Enter to activate this console.



BusyBox v1.27.2 () built-in shell (ash)

 _____  _              __     _
|_   _||_| ___  _ _   |  |   |_| ___  _ _  _ _
  | |   _ |   ||   |  |  |__ | ||   || | ||_'_|
  | |  | || | || _ |  |_____||_||_|_||___||_,_|
  |_|  |_||_|_||_|_|  Tina is Based on OpenWrt!
 ----------------------------------------------
 Tina Linux (Neptune, 5C1C9C53)
 ----------------------------------------------
root@TinaLinux:/# 

LiveSuit 下载链接:
https://androidmtk.com/download-livesuit-all-versions
https://linux-sunxi.org/LiveSuit
https://androiddatahost.com/wp-content/uploads/LiveSuit_ForMac.zip
https://github.com/linux-sunxi/sunxi-livesuite


Part 3 存取虚拟机内文件

Note:

  • multipass的mount命令(目前)只能单向的将宿主机的文件目录挂载到虚拟机上。
    将虚拟机的文件系统共享/挂载到主机,主机就可用各种本地工具操作虚拟机文件内容。

  • ubuntu桌面环境已经安装了samba。

虚拟机的文件共享,可以使用sshfssambanfs。性能参考此篇文章内容。

  • sshfs 底层传输走SSH,文件传输用SFTP,做法是将服务器的SFTP服务,利用FUSE在用户模式下打包成文件系统挂载。由于ssh已有防火墙和密钥,可安全的、远距离的存取文件。虚拟机不必另安装 driver,宿主机要安装文件系统。如 macOS下是采用macFUSE 安装内核driver,再把sshfs在用户模式实现。虚拟机上无sshfs服务广播,只能静态手动挂载。
  • samba是windows的局域网路文件共享协议,macOS和windows都预设能使用。但虚拟机要安装相关协议并作权限设定。可在网路芳邻发现局域网内主机所共享的文件。

以多虚拟机环境来看, sshfs只要在主机安装、挂载,而samba需要在每个虚拟机安装协议并另作权限设定,系统负担较重。

⚠️(2021-1-12)注意: sshfs 使用的 macFUSE 服务不稳定,在某些时候(如mount时?)会拉住宿主系统。为免困扰,macOS下建议采用 SAMBA 存取虚拟机文件。

1 使用SAMBA协议

samba协议是微软Windows预设的局域网文件共享协议,macOS内建支持。linux系统需要安装服务。

###1.1 安装Samba服务

sudo apt install samba samba-common -y

1.2 配置需要多人共享的目录(可选)

改变需要共享目录的权限,让其他人可以更改文件和目录,以/home/xxx为例(若多人使用同一服务器建议在每个用户家目录单独共享,不建议共享整个home目录,防止误操作删除他人文件)
sudo chmod 770 /home/ubuntu/xxx -R

1.3 添加samba用户

添加samba用户/密码,用于其他人或设备认证,这里添加的用户需要在系统账号中存在,否则添加失败
sudo smbpasswd -a ubuntu

1.4 配置samba

先备份,再修改 /etc/samba/smb.conf  配置文件,添加共享文件夹。
sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.old
sudo pico /etc/samba/smb.conf

​ 在配置尾端添加一个共享文件夹:

[tina]
   comment = tina home dir
   path = /home/ubuntu
   guest ok = no
   browseable = yes
   create mask = 0775
   directory mask = 0775
   valid users = ubuntu,root
   write list = ubuntu,root
    valid users 和 write list 是这个共享项目的可用和可写的用户列表。

1.5 重启SAMBA服务:

sudo service smbd restart

1.6 在宿主机下就能用刚刚设定的 ubuntu 的 smb 密码,存取 tina 文件夹了。

macOS下:先用 browser打开smb连接来进入Finder:

再设定使用ubuntu用户密码:

然后 finder中就可以看到共享了。

1.7 使用 multipass 执行SAMBA自动安装script范例

假设要安装 SAMBA服务到虚拟机 $vm 中,共享的目录名称为 vm_work

# 7 使用SAMBA协议共享虚拟机文件夹
# samba协议是微软Windows预设的局域网文件共享协议,macOS内建支持。linux系统需要安装服务。
echo setup SAMBA server 

# 7.1 安装Samba服务
multipass exec $vm -- sudo apt install samba samba-common -y

# 7.2 配置需要多人共享的目录(可选)
# 改变需要共享目录的权限,让其他人可以更改文件和目录,
# 以/home/vm_work 为例(若多人使用同一服务器建议在每个用户家目录单独共享,不建议共享整个home目录,防止误操作删除他人文件)
multipass exec $vm -- mkdir vm_work 
multipass exec $vm -- sudo chmod 770 /home/ubuntu/vm_work -R

# 7.3 添加samba用户密码
# 添加samba用户/密码,用于其他人或设备认证,这里添加的用户需要在系统账号中存在,否则添加失败
multipass exec $vm -- sudo smbpasswd -a ubuntu

# 7.4 配置samba
# 先备份,再修改 /etc/samba/smb.conf  配置文件,添加共享文件夹。
multipass exec $vm -- sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.old

# 在 /etc/samba/smb.conf 尾端添加一个共享文件夹:
echo "[vm_work]\
    \n  comment = $vm vm_work dir\
    \n  path = /home/ubuntu/vm_work\
    \n  guest ok = no\
    \n  browseable = yes\
    \n  create mask = 0775\
    \n  directory mask = 0775\
    \n  valid users = ubuntu,root\
    \n  write list = ubuntu,root" | multipass exec $vm -- sudo tee -a  /etc/samba/smb.conf


# 7.5 重启SAMBA服务:
multipass exec $vm -- sudo service smbd restart

# 7.6 在宿主机下就能用刚刚设定的 ubuntu 的 smb 密码,存取 vm_work 文件夹了。
echo macOS 在 browser 地址栏输入 smb://$vm/vm_work 就能打开 Finder,输入SAMBA用户密码,连接网盘了。

2 使用 sshfs协议

macOS下使用sshfs的介绍。

2.1 安装sshfs + macFUSE:

sshfs 项目需要fuse依赖,目前brew宣称macFUSE有版权问题关闭支援,需要直接由osxfuse官网的git下载安装:

  1. git下载安装 macFUSE ,macOS的 系统偏好设置-安全与隐私-允许 macFUSE 后,依指示重启动。
  2. git下载安装 sshfs

2.2 挂载:

使用 sshfs 命令挂载远端文件/目录。与其他文件系统的 mount 命令一样,需要先建立一个目录挂载文件系统。
由于在之前已经为 tina申请ssh别名,并让宿主机免密 ssh到 tina了,以下命令可用 tina 取代 [remote_user]@[remote_server] 。

mkdir tina
#sshfs [remote_user]@[remote_server]:[remote_directory] [mountpoint] -o allow_other
sshfs tina:/home/ubuntu tina -o allow_other

可以看到 tina下已经是 tina虚拟机的ubuntu用户目录了。

2.3 取消挂载:

使用系统的 umount 命令即可。
umount tina

2.4 Linux 开机挂载 sshfs:

在fstab中添加如下挂载条目
sshfs#[remote_user]@[remote_server]:[remote_directory] [mountpoint] [mountpoint] fuse allow_other 0 0

2.5 挂载失败处置:

文件系统出问题需要重挂载,在取消挂载(umount)遇到失败时,要剔除进程才能重挂载。
pgrep -lf sshfs
pkill -9 sshfs

附录

更改虚拟机的主用户名?

⚠️:主用户名可以更改,但之后multipass只能用 ssh 登入,不能用 multipass sh 命令进入,也就是说,multipass 工具会出状况,还不知怎么处理,还请谨慎,若有用户名需求,还是添加用户好了。。。

⚠️注意:更改用主戶名可能造成無法登入,执行请小心:

執行前,請確認以下都做了:

# ⚠️需要完全在 root下工作
sudo -s

# ⚠️允許用密碼 ssh(no 改 yes),不必一直用 ssh-key(可能影響登入安全)登入:
sed -i 's/#   PasswordAuthentication/PasswordAuthentication/g' /etc/ssh/sshd_config
sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config/

# ⚠️要先给 ubuntu 账户加密码,否则更名之後可能无法 sudo 了。。。
passwd ubuntu

開始修改相关文件:

cd /

# 改变 /etc 下的 passwd、shadow、group 用户名。可以用 nano 编辑,或 sed 自动修改
  # 账户密码的 户名、全名、工作目录:
  sed -i 's/ubuntu/cyue/g' /etc/passwd
  sed -i 's/Ubuntu/CYUE/g' /etc/passwd

  # shadow的 户名:
  sed -i 's/ubuntu/cyue/g' /etc/shadow
  # 旧帐户加入的群组:
  sed -i 's/ubuntu/cyue/g' /etc/group
  # 工作目录名变换
  mv /home/ubuntu /home/cyue

  #.ssh/ 下用户名更换:
  sed -i 's/ubuntu/cyue/g' /home/cyue/.ssh/authorized_keys
  sed -i 's/ubuntu/cyue/g' /home/cyue/.ssh/id_rsa.pub

# nano /etc/sudoers,在root后添加新用户名(以cyue为例),为可以执行 sudo的用户。
    echo 'cyue    ALL=(ALL:ALL) ALL' >> /etc/sudoers

# reboot完成vm的用户更名!!
  reboot


之后 ssh 可以用 cyue + 密码 登入了,不过,host端也要修改 ssh 登入的用户名。。。

sed -i 's/ubuntu/cyue/g' ~/.ssh/config

自动安装设定虚拟机 script

这里提供自动化script,自动建立multipass虚拟机。

1. vmbuild.sh :

在一个多月的嵌入系统开发操作上,发现 XRDP桌面比 XQuartz好用,SAMBA文件共享比用到 macFUSE的ssh文件系统简单易用,我们的自动安装 Script就直接选用了。Script的工作歩驺如下:

  1. 建立 multipass 虚拟机
  2. 国内源处理
  3. 挂载主機共享的文件夹
  4. 设置ssh服务,并为VSCode设置极限文件数
  5. 主机VSCode设定说明(script无工作)
  6. 安装 XRDP 以及最小桌面环境
  7. 使用SAMBA协议共享虚拟机文件夹(主目录下的工作目录)

Script 使用法:source vmbuild.sh [vm_name [ubuntu_ver [share_path]]] ,可调的参数:

  • vm_name: 虚拟机名稱
  • ubuntu_ver: 建立虚拟机的 ubuntu镜像版次
  • share_path: 虚拟机将共享出来的的文件夹名称

其他 cpu core数、虚拟磁盘大小、使用记忆体大小固定在 script里,需要时再修改。

vmbuild.sh 内容:

#! sh
#====================================================================================
echo "=== macOS 下自动建立 multipass 虚拟机 ==="
echo " 会修改为ustc源、挂载主机目录、自动安装ssh并为远端Vscode设定多文件开启、安装XRDP服务、安装SAMBA服务并共享目录。"

# 1. 建立 multipass 虚拟机

echo "useage: $0 [vm_name [ubuntu_ver [share_path]]]"
echo "参数依序为:虚拟机名稱、选择ubuntu镜像的版次。"
# 1.1 Script 缺省的参数依序为:虚拟机名稱、选择ubuntu镜像的版次。
export vm=u22 
export img=22.04

# 1.2 虚拟机的 CPU数、记忆体容量、硬盘容量定义在此,依宿主机调整:
export core=4
export mem=6G
export disk=80G


# 1.3 macOS:安装 multipass app (使用万能的 brew):
#     brew install --cask multipass

# 1.4 依据前面的参数建立虚拟机:
if [ "" != "$2" ];then export img=$2; fi
if [ "" != "$1" ];then export vm=$1; fi 

# SAMBA sharefolder...
export vm_share=${vm}_share

echo multipass launch  -c $core -m $mem -d $disk -n $vm  $img
multipass launch  -c $core -m $mem -d $disk -n $vm  $img

#====================================================================================
# 2. 国内源处理
# 2.1 apt 更换为中科大 ustc 源
multipass exec $vm --  sudo cp /etc/apt/sources.list /etc/apt/sources.list.org
multipass exec $vm --  sudo sed -i 's@archive.ubuntu.com@mirrors.ustc.edu.cn@g' /etc/apt/sources.list
multipass exec $vm --  sudo sed -i 's@security.ubuntu.com@mirrors.ustc.edu.cn@g' /etc/apt/sources.list
multipass exec $vm --  sudo apt update -y 
#multipass exec $vm --  sudo apt upgrade -y

# 2.2 snap 国内proxy设定(视需要)
# multipass exec $vm --  sudo snap install snap-store-proxy
# multipass exec $vm --  sudo snap install snap-store-proxy-client

#====================================================================================
# 3. 挂载主機共享文件夹
# 3.1. 安装 multipass-sshfs 以挂载主机文件夹
multipass exec $vm --  sudo snap install multipass-sshfs

# 3.2 挂载主机文件夹(到 /mnt 下)如:
multipass mount   ~  $vm:/mnt/host

# 3.3 macOS 多了一层权限管理,需要允许 multipassd 的磁盘访问权限:
#   打开设定app --  安全性与隐私 -- 隐私页 -- 左下角解锁 -- 完全磁盘访问权限 -- 勾选允许 multipassd



#====================================================================================
# 4. 为 VSCode 设置 ssh  
# 宿主机 VSCode 可透过 ssh 直接编译虚拟机的工程
# 4.1 宿主机使用 `ssh-keygen` 建立 ssh 公钥(若未执行过,需执行一次)
#    使用缺省多次 enter后,公钥放在 ~/.ssh/id_rsa.pub

# 4.2 VM 安装 ssh,并执行 `ssh-keygen` 
#    使用缺省多次 enter后,公钥放在 ~/.ssh/id_rsa.pub
multipass exec $vm -- sudo apt install ssh -y
multipass exec $vm -- ssh-keygen

# 4.3 sshd 守护进程设定
#     打开密码,允许无密码登入、重启 sshd 
multipass exec $vm -- sudo sed -i 's/PasswordAuthentication\ no/PasswordAuthentication yes/g' /etc/ssh/sshd_config
multipass exec $vm -- sudo sed -i 's/#PermitEmptyPasswords\ no/PermitEmptyPasswords yes/g' /etc/ssh/sshd_config
multipass exec $vm -- sudo service sshd restart

# 4.4 绑定VM的ssh别名、并交换公钥
# 绑定虚拟机名称和虚拟机IP
echo "\nHost $vm\n  HostName $(multipass ls | grep $vm | awk '{print $3}')\n  User ubuntu" >> ~/.ssh/config
# 允许主机的本账号,免密ssh进虚拟机
multipass exec $vm -- sed -i "$ a\ $(cat ~/.ssh/id_rsa.pub)" .ssh/authorized_keys
# 允许VM的ubuntu账号,免密ssh进主机
# (等同于执行: `ssh-copy-id -i ~/.ssh/id_rsa.pub ubuntu@${vm}`)
# (multipass exec $vm -- cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys)



# 4.5 将inode数调到最大,以利VSCode工作
#    Vscode 会同时操作多个文件,将inode数给到到最大值(524288)并重置此值。
multipass exec $vm -- sudo sed -i "$ a\fs.inotify.max_user_watches=524288" /etc/sysctl.conf
multipass exec $vm -- sudo sysctl -p

#====================================================================================
# 5. 安装 VSCode 并设置远程连接  
# 5.1 宿主 vscode安装:
#    brew install visual-studio-code
# 5.2 执行 vscode app,并安装 Remote - SSH 扩展:

# 5.3 用 vscode 远端连接虚拟机
#    vscode安装 ssh remote扩展,然后用左下角的连接按钮连接VM
#    第一次连接会发现金钥需求。点选 continue,会把3个金钥放到 ~/ssh/know_hosts中
#    之后vscode会透过ssh在虚拟机安装ssh下的私密服务,以让vscode更好的和VM协同工作。  

#显示虚拟机的安装信息
multipass info $vm 
#====================================================================================
# 6. 为虚拟机 $vm 添加图形界面
# 6.2 使用 XRDP 提供虚拟机远端桌面环境
# 6.2.1 虚拟机安装最简ubuntu桌面套件与xrdp服务
if [ "18.04" != "$img" ]; then
  multipass exec $vm -- sudo apt install -y ubuntu-desktop-minimal xrdp
else
  multipass exec $vm -- sudo apt install ubuntu-desktop xrdp -y 
fi

multipass exec $vm -- sudo apt remove libreoffice* thunderbird* totem* rhythmbox* transmission* -y
multipass exec $vm -- sudo apt autoremove -y

multipass ls | grep $vm

# 为用户 ubuntu 添加密码,RDP需求。
multipass exec $vm -- sudo passwd ubuntu

# 6.2.2 主机安装 RDP Client app
# 在 App Store 中搜寻 RDP,下载微软的 “Microsoft Remote Desktop” 
# 上个 multipass ls | grep $vm 命令可看到虚拟机 名称和 IP,加上账号 ubuntu,不用密码,
# 就可以设定此虚拟机的环境 RDP




#====================================================================================
# 7 使用SAMBA协议共享虚拟机文件夹
# samba协议是微软Windows预设的局域网文件共享协议,macOS内建支持。linux系统需要安装服务。
echo setup SAMBA server 

# 7.1 安装Samba服务
multipass exec $vm -- sudo apt install samba samba-common -y

# 7.2 配置需要多人共享的目录(可选)
# 改变需要共享目录的权限,让其他人可以更改文件和目录,
# 以/home/$vm_share 为例(若多人使用同一服务器建议在每个用户家目录单独共享,不建议共享整个home目录,防止误操作删除他人文件)
multipass exec $vm -- sudo mkdir -p /home/$vm_share 
multipass exec $vm -- sudo chown ubuntu:ubuntu /home/$vm_share -R
multipass exec $vm -- sudo chmod 770 /home/$vm_share -R

# 7.3 添加samba用户密码
# 添加samba用户/密码,用于其他人或设备认证,这里添加的用户需要在系统账号中存在,否则添加失败
multipass exec $vm -- sudo smbpasswd -a ubuntu

# 7.4 配置samba
# 先备份,再修改 /etc/samba/smb.conf  配置文件,添加共享文件夹。
multipass exec $vm -- sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.old

# 在 /etc/samba/smb.conf 尾端添加一个共享文件夹:
echo "[$vm_share]\
    \n  comment = $vm $vm_share dir\
    \n  path = /home/$vm_share\
    \n  guest ok = no\
    \n  browseable = yes\
    \n  create mask = 0775\
    \n  directory mask = 0775\
    \n  valid users = ubuntu,root\
    \n  write list = ubuntu,root" | multipass exec $vm -- sudo tee -a  /etc/samba/smb.conf


# 7.5 重启SAMBA服务:
multipass exec $vm -- sudo service smbd restart

# 7.6 在宿主机下就能用刚刚设定的 ubuntu 的 smb 密码,存取 $vm_share 文件夹了。
echo macOS 在 browser 地址栏输入 smb://$vm/$vm_share 就能打开 Finder,输入SAMBA用户密码,连接网盘了。

2. vmadd_xquartz.sh 和 vmup.sh:

还想使用 XQuartz? 可以用 vmadd_xquartz.sh 以下附加script来添加。

  • vmadd_xquartz.sh:
    假设之前 使用 source 执行过 vmbuild.sh,变量 vm 还保持了虚拟机的名称。
#! sh

# 6. 为虚拟机 $vm 添加图形界面
# 6.1 提供虚拟机 X11 GUI - 使用 XQuartz(若只想要完整桌面跳到下一章)
# 6.1.1. 安装 XQuartz, 可用萬能的 brew:
brew install --cask xquartz
# 6.1.2. 設定 XQuartz app: 
#  xhost& 会在背景打开 XQuartz.app。
#  - app菜单 --> 偏好 --> 安全性页面,勾选允许从网路客户端链接。
xhost&
# 6.1.3. 安装基础 X11庫,用于直连 host的 X11 。
multipass exec $vm -- sudo apt install xinit -y

# 6.1.4. VM X11相关的設定:
#  - 设定 DISPLAY 环境变量、链接主机 .Xauthority 文件、挂载主机 X11 暂存目录。
multipass exec $vm -- sed -i "$ a\export DISPLAY=$\(echo $\SSH_CLIENT |awk '{print $\1}'):0"  /home/ubuntu/.bashrc 
multipass exec $vm -- ln -s /mnt/host/.Xauthority .Xauthority
multipass mount /tmp/.X11-unix $vm:/tmp/.X11-unix
  • vmup.sh

    主机开启xquartz设定后,再使用 vamp.sh 登入虚拟shell,shell中就可以执行 X11 GUI应用。

#! sh
# 1. 缺省的虚拟机名稱。
export vm=tina

# 2. 若script有参数,第一个参数当虚拟机名。
if [ "" != "$1" ];then export vm=$1; fi

# 3. 确认macOS已开启xquartz
xhost&

# 4. 确认虚拟机已启动。
if [ "Running" != "$(multipass ls | grep $vm | awk '{print $2}')" ];then
multipass start $vm
fi

# 5. xhost 添加允许虚拟机IP连线。
xhost +$(multipass ls | grep $vm | awk '{print $3}')

# 6. ~/.Xauthority 已改用文件系统挂载,不用在 script 中复制。
#if [ "" = "$(multipass exec $vm -- ls -lia | grep .Xauthority)" ];then
# multipass transfer ~/.Xauthority $vm:/home/ubuntu/.Xauthority
#fi

# 7. 进入虚拟机的shell
multipass sh $vm

Multipass 快速上手

0. 取得命令辅助说明

  • multipass 命令后加上 -h ,即可查看相关命令使用说明。

  • multipass version 可看版次信息。

1. 查询相关命令 find、list(ls)、info

  • find: 查询官方可用镜像。
#find: 查询官方可用镜像。
$ multipass find
Image                       Aliases           Version          Description
18.04                       bionic            20211129         Ubuntu 18.04 LTS
20.04                       focal,lts         20211129         Ubuntu 20.04 LTS
21.04                       hirsute           20211130         Ubuntu 21.04
21.10                       impish            20211209         Ubuntu 21.10
anbox-cloud-appliance                         latest           Anbox Cloud Appliance
minikube   
  • list (ls): 已有虚拟机列表。
# list:已有虚拟机列表。
$ multipass ls
Name                    State             IPv4             Image
tina                    Running           192.168.64.6     Ubuntu 18.04 LTS
  • info: 显示虚拟机状态。--all 参数显示所有虚拟机。
# 显示虚拟机状态。`--all` 参数显示所有虚拟机。
$ multipass info tina
Name:           tina
State:          Running
IPv4:           192.168.64.6
Release:        Ubuntu 18.04.6 LTS
Image hash:     eeff819e8474 (Ubuntu 18.04 LTS)
Load:           0.00 0.00 0.00
Disk usage:     26.1G out of 38.6G
Memory usage:   183.3M out of 7.8G
Mounts:         /Volumes/Work => /home/ubuntu/work
                    UID map: 501:default
                    GID map: 20:default
                /Users/cyue   => /home/ubuntu/host
                    UID map: 501:default
                    GID map: 20:default

2. 创建、删除、和恢复虚拟机: launch | delete | recover

  • launch:从镜像创建虚拟机实体。可从同个镜像建立多个实体。
    • 语法:multipass launch [参数] [虚拟机名称 [使用镜像]]
    • 参数:
      • -n, –name: 名称, 默认值: primary
      • -c, –cpus: cpu核心数, 默认值: 1
      • -m, –mem: 内存大小, 默认值: 1G
      • -d, –disk: 硬盘大小, 默认值: 5G
multipass launch -n u18 -c 4 -m 4G -d 40G 18.04
  • delete:删除系统中镜像。可选 -p 参数,将完全删除不能恢复。
  • recover:恢复删除的虚拟机。
multipass delete u18
multipass recover u18 #恢复删除的虚拟机
multipass delete -p u18 #彻底删除,不能恢复

3. 开|关|重启|挂起 虚拟机命令:start|stop|restart|suspend

multipass start
multipass stop
multipass restart
multipass suspend u18

4. 操作虚拟机 shell(sh)、exec

  • sh : 进入虚拟机终端。

语法:multipass sh [虚拟机名称]

multipass sh u18

在虚拟机 shell 中,使用 exit 命令即退出 shell,但虚拟机仍在执行状态,可快速sh重新进入。

  • exec : 执行虚拟机shell命令。

语法:multipass exec [虚拟机名称] — 命令
相当于 sh 进虚拟机 shell,执行命令后,exit 退出 虚拟机 shell。

multipass exec u18 -- ls  # 在 u18虚拟机执行 ls 命令后返回

5. 传递文件,及挂载主机文件夹 transfer、mount、umount

  • transfer : 文件传送。可有多个来源文件传到单一目的地文件

语法:multipass transfer [options] <来源> [<来源> ...] <目的地>

复制一或多个文件到单一目的地。

<来源>或<目的地> 参数前若加 “name:” ,是指虚拟机“name”内的文件。

#复制主机用户目录下的 .Xauthority文件到u18虚拟机的复制传送
multipass transfer ~/.Xauthority $vm:/home/ubuntu/.Xauthority 
  • mount : 挂载 host目录。

语法:multipass mount [参数] 宿主机目录 虚拟机名称[:目录名称 ]

参数:

-u host_id:instance_id : 将 host 目录的 user id 对应到虚拟机目录的 user id

-g host_id:instance_id : 将 host 目录的 group id 对应到虚拟机目录的 group id

multipass mount /mnt u18
multipass mount /mnt u18:/mnt

⚠️注意1: 虚拟机 ubuntu的第一个用户 id 通常是 1000,macOS的第一个用户 id 可能是 501。

可在宿主机和虚拟机内用 id 命令查看 id号。在重新定义。这样才能控制好存取权限。

⚠️注意2: 停止(stop)虚拟机后,再做挂在动作,再重开启虚拟机,以免状况不同步。

  • umont : 卸载虚拟机内挂在的host目录。

语法:multipass unmount 虚拟机名称[:目录名称 ]

若没有指定目录,所有虚拟机内的host挂载都会被卸载。

multipass unmount u18
  • 此外在主机或虚拟机终端中可用 scpssh 等 unix shell 命令,透过 IP 与主机或其他机器联系。

6. 更改Multipass实例的内存和CPU数

# 先停止 multipassd 服务
sudo launchctl unload /Library/LaunchDaemons/com.canonical.multipassd.plist

# 修改配置文件
sudo pico /var/root/Library/Application\ Support/multipassd/qemu/multipassd-vm-instances.json

# 再启动 multipassd 服务
sudo launchctl load /Library/LaunchDaemons/com.canonical.multipassd.plist

配置文件的格式应该很容易理解:

{
    "primary": {
        "deleted": false,
        "disk_space": "10737418240",// 10G
        "mac_addr": "52:54:00:5d:ed:45",
        "mem_size": "4294967296",//4096M
        "metadata": {
        },
        "mounts": [
        ],
        "num_cores": 2,
        "ssh_username": "ubuntu",
        "state": 0
    }
}

multipass 常用命令快速参考

multipass -help 可查阅使用方式。

  • multipass ls: 查看已安装的VM,multipass find: 搜寻官方提供的系统镜像(image)。
  • multipass launch [-n vm_name] [-c cpu_cores] [-d disk_size] [-m mem_size] [image]: 【使用 指定 镜像】创建【指定名称】、【cpu核心数】、【磁碟大小】、【记忆体大小】的虚拟机实体。
  • multipass delete [-p] [vm]: 删除VM实体(-p 强制释放虚拟机磁盘空间,不能recover回来)。
  • multipass sh [vm]: 进入指定VM的 shell。
  • multipass start [vm]: 启动已创建的VM实体。multipass stop [vm|--all]:停止VM或全部VM。 multipass restart [vm]: 重启VM。
  • multipass mount [-u uid>:vm_uid] [-g gid:vm_gid] <host_path> <vm1:path> [<vm2:path> ...]: 将主机目录挂载到(多个)虚拟机目录中。可映射目录的用户id/群组id到虚拟机的用户id/群组id以设定存取权限。
  • multipass transfer [options] <source> [<source> ...] <dest>: 传送(多个)来源到目的地。
    source 和 dest 可以是主机的 path 或是 vm:path 格式的虚拟机vm的path。可传递整个目录。
    path 若是 - 表示是 stdin 或 stdout 。
  • multipass exec <vm> [--] <command>: 直接在宿主机执行虚拟机实体的命令,不进入虚拟机。注意没执行虚拟机的 ~/.bashrc ,环境变量与 sh进虚拟机的不同。

#某使用32bit工具开发项目XX的编译环境设定

这里操作在 Ubuntu 20.04 镜像的虚拟机后,安装一个需要32bit环境的老SDK的一般需求。确认 multipass环境能为该SDK建立良好的虚拟开发环境。

添加32bit支持

  • 由于 SDK 中还有32bit工具(如uboot用的gcc),要添加32bit支持:
sudo dpkg --add-architecture i386

sudo apt update
sudo apt purge libc6-dev -y
sudo apt install libc6-dev libc6-dev-i386 -y

安装SDK相依的系统程式库

  • 用 apt 安装SDK相依的系统程式库
sudo apt install build-essential make ccache libncurses5 libncurses5-dev  libssl-dev openssl zlibc minizip libidn11-dev libelf-dev bison flex gawk -y

解压缩源码与sdk工具

  • 解压缩sdk与code
tar -xvf /mnt/sourcezip/srcXX.tgz

设定编译环境参数

  • 初始化编译环境:
cd XX
. scripts/XXenv.sh

选择编译项目

  • 编译选项目(2):
make -id 2

修改编译项目的参数设定

  • 编译参数修改:
make menuconfig

编译

  • 编译:
# make all
time make all -j18

大约15~20min 第一次完整编译完成。

real    19m52.255s
user    75m19.688s
sys 10m22.632s

Parallels :

real    21m2.057s
user    74m37.298s
sys 13m30.170s

clean 后重build

make clean
time make all -j16

clean后第二次编译性能

real    5m25.158s
user    13m29.415s
sys 3m29.612s

烧录

TBD。该项目有Windows的烧录工具,没有macOS的。。。


Multipass 对已经存在的实例进行调整

https://zhuanlan.zhihu.com/p/435237515

亡灵之猫

最近上手尝试了 Canonical 家搞出来的跨平台 Ubuntu 轻量虚拟化方案——Multipass。

虽然体验确实不错,但是官方提供的资料确实太粗糙了,很多问题还要靠社区解决。

Multipass 希望能把虚拟机像 docker 一样的使用,他确实也做到了这样的效果;然而虚机毕竟还是虚机,有很多与容器的不同之处,更何况 Multipass 运行的是带有 systemd 的完整发行版 Ubuntu,直接对虚机的调整还是会有需要。

对于启动时,我们可以通过命令行参数给虚拟机分配资源,例如

multipass launch --name myubuntu --cpus 2 --mem 2G --disk 10G

那么等你什么都已经配置好之后,发现资源紧张怎么办?重建明显代价太大了,其实作为虚机,这些重新调整都不难。

这里主要针对 MacOS 进行说明,要能正确配置 multipass 需要想了解它的安装和工作路径,这些方面 multipass 有点不太走寻常路:

  • multipass 程序主要工作在 /Library/Application Support/com.canonical.multipass

  • 如果没有特别处理,multipass 使用 qemu 作为Hypervisor,虚拟盘为 COW2 格式,网络使用虚拟网桥连接

  • 虚拟机的配置文件为 /var/root/Library/Application Support/multipassd/multipassd-vm-instances.json 需要 root 权限

    sudo pico /var/root/Library/Application Support/multipassd/multipassd-vm-instances.json
    
  • multipass 默认会通过 luanchd 随系统启动,启动配置文件在 /Library/LaunchDaemons/com.canonical.multipassd.plist

对于虚机的调整一般都建议先停止 multipass 服务:

sudo launchctl unload /Library/LaunchDaemons/com.canonical.multipassd.plist

启动 multipass 服务:

sudo launchctl load /Library/LaunchDaemons/com.canonical.multipassd.plist

修改实例内存和CPU,需要到虚机目录下寻找对应的实例:

/var/root/Library/Application Support/multipassd/

不同的系统可能情况会有所不同,猫这里是 MacOS 12.0.1 + multipassd 1.8.1,实例配置文件为

/var/root/Library/Application Support/multipassd/multipassd-vm-instances.json

对应实例下主要的配置项目有:

  • disk_space: 虚拟盘大小,单位字节,实例建立后调整该参数无效
  • mac_addr: 虚机 MAC 地址
  • mem_size: 虚机内存大小,单位字节,重启虚机生效
  • metadata: qemu 启动命令行列表
  • mounts: 挂载主机路径信息,挂载路径可以通过命令行实现,不建议在这里调整
  • num_cores: 虚拟 CPU 核心数,重启虚机生效

对于虚机的磁盘进行调整是无法通过配置文件实现的,需要对应的工具进行调整,这里主要针对 qemu 的

虚拟机的虚拟盘位于:

/var/root/Library/Application Support/multipassd/qemu/vault/instances/实例名/ubuntu-版本-server-cloudimg-架构.img

使用 qemu-img 工具可以对其进行调整,multipass 自带的 qemu-img 工具位于

/Library/Application Support/com.canonical.multipass/bin/

可以将其加入到 PATH 环境变量或者软链到 /usr/local/bin 下方便使用,操作虚拟盘时,请先停止虚拟机实例

查看虚拟盘信息

qemu-img check 镜像文件

修改虚拟盘大小(单位字节):

qemu-img resize 镜像文件 size

修改完成后,直接启动虚拟机实例就能看到修改生效

最后,multipass 存在一个默认虚拟机,一般名为 “primary”,直接 multipass shellmultipass start 启动的都是默认虚拟机。

如果希望用自己已经创建好的实例替换默认虚拟机,可以直接用命令行操作修改:

multipass set client.primary-name=自己的实例名

验证修改

multipass get client.primary-name

如何提高Multipass挂载性能

https://blog.csdn.net/sinat_41870148/article/details/125464309

也见: 如何与实例共享数据, mount

Multipass默认使用SSHFS在实例上挂载主机文件夹. 这提供了一个在性能, 安全和功能之间比较好的中和方案, 其他方法也可以手动完成这个任务.

实测:time dd if=FreeRTOSv202112.00.zip of=xxx bs=8k count=1000000

环境 读写速度(MB/s)
macOS原生 SSD(MBP15 2015) 500-730
Parallels Virtual HDD 440-660
multipass虚拟机 Virtual HDD 500
multipass虚拟机 sshfs 挂载主机 SSD硬盘 30
Sftp 连接主机SSD硬盘 6

我们在很多挂载方法上进行了彻头彻尾的测试. 在这里, 我们将简述如何使用我们找到的高效方法在每个系统上如何创建共享, 如何在Multipass实例中挂载他们

内容:

SMB/CIFS挂载 [Windows、macOS、Linux]

在我们的测试中, SMB在Multipass所有搭建中都是性能优良的. Windows和MacOS提供了一个系统SMB服务器, Linux上也是很容易安装的(较新核心版本提供了一个系统服务器, 而我们在这描述的也可以针对于老旧Linux版本).

使用SMB共享文件夹

Windows

首先, 这一部分是可选操作, 我们可以启动在Windows中内置的SMB服务器上的RDMA. 在控制面板中, 我们可以找到Windows功能开关. 在这个窗口, 我们需要启用SMB驱动. Windows可能需要启动.

然后, 我们可以用PowerShell共享文件夹. 看下面的命令:

New-SmbShare -Name "share_name" -Path "C:\my_path"

我们会在主机上创建一个名为\\hostname\share_name的共享. 命令New-SmbShare有很多选项可以控制连接和编码, 但是这不是这篇文章的话题.

MacOS

这些完全可以使用界面操作(GUI)完成, 只是有些步骤从命令行操作比较简单. 如果可以, 我们后面会展示后者.

我们需要按照下面的命令启动共享系统:

$ sudo defaults write /Library/Preferences/SystemConfiguration/com.apple.smb.server.plist EnabledServices -aaray disk
$ sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.smbd.plist

然后, 去共享指定文件夹:

$ sudo sharing -a /Volumes/Work 

最后, 我们需要允许用户通过SMB连接到共享文件夹. 因此, 我们需要导航到系统偏好(System Preferences), 找到共享图标. 在共享菜单有一个选项按钮. 这个按钮会打开一个窗口, 我们可以在其中选择哪些用户能够挂载. 接下来选择想要授权的用户并输入密码.

所有这些步骤会在主机上创建一个名为//hostname/my_path/的挂载点.

Linux

在Ubuntu(或其他任何基于Debian的发行版)中, samba-common 包包含了SMB服务器. 我们可以使用命令安装它

$ sudo apt update && sudp apt install -y samba-common

然后, 编辑文件/etc/samba/smb.conf, 使我们可以添加共享, 新增词条, 如下:

[test_smb_mount]
  comment = smb mount test
  path = /my_path/
  read only = no
  browsable = yes
  kernel oplocks = yes

在实例中使用SMB共享挂载文件夹

一旦主机操作系统可以共享文件夹, 我们就可以在实例中挂载它. 为此, 需要cifs-tools包, 可以用下面命令安装

$ sudo apt upadte && sudo apt install -y cifs-utils

挂载需要下面命令行最终完成

$ sudo mount -t cifs //hostname/my_path_or_share_name mount_folder/ -o user=my_name,uid=1000

my_name是主机上共享文件夹的用户. 在终端中会被要求输入密码, 输入就完成了.

这一步可选. 我们可以在/etc/fstab新增一行, 让操作系统启动时自动挂载文件夹, 或至少不需要指定挂载名称或选项. 命令行应如下:

//hostname/my_path_or_share_name mount_folder/ cifs user=my_name,uid=1000 0 0

这个文件中的词条使用空格或者制表符分隔. 第一个是共享名称或路径, 第二个是要挂载文件夹的目录, 第三个是挂载类型, 第四个是一个逗号分隔的选项列表(添加noatuo避免启动时挂载), 最后两个选项最好保持为0.

假设noauto在选项中被指定了, 文件夹就需要用下面方式挂载

$ sudo mount mount_folder/

virtio-fs挂载 [Linux]

如果在Linux上使用LXD后端, 我们可受益于有一个优良的文件系统挂载, 鉴于系统运行时无法挂载的花销. 使用下面命令在实例上挂载文件夹:

$ lxc --project multipass config device add lxdinstance mount_lxd disk source=/my_path path=//mount_folder

鉴于lxdinstance是实例名称, mount_lxd是一个挂载过于随意的设备名称, source指定了共享路径, path指定了源文件(source)需要挂载的目录. 只需要这个命令, LXD搞定了所有事情: 无需在实例运行命令.

virtio-fs也在qemu和libvirt后端可用, 尽管需要额外安装.

NFS挂载 [Linux、macOS]

Linux和MacOS在系统上提供了NFS服务器.

使用NFS共享文件夹

MacOS

MacOS上的NFS服务器是使用nfsd命令和文件/etc/exports控制. 我们通过新增文件夹到文件中去共享, 使用类似于下面的一行文本:

/my_path -mapall=host_user -network 192.168.0.0 -mask=255.255.0.0

-network-mask控制着共享可以连接到的网络. 然后, 我们使用命令启动服务器

$ sudo nfsd start

(或者服务器已经正在运行则使用restart)

Linux

在Ubuntu(或其他任何基于Debian的发行版), nfs-kernel-server包包含了核心中需要使用NFS服务器的文件. 我们可以用命令安装它

$ sudo apt update && sudo apt install -y nfs-kernel-server

用下面命令共享文件夹:

$ sudo exportfs *:/my_path

*表示”导出任何主机”; 我们在这可以指定主机名或IP地址

在实例中使用NFS共享挂载文件夹

我们首先需要使用下面命令在实例中安装NFS客户端

$ sudo apt update && sudo apt install -y nfs-common

然后, 我们可以用下面命令挂载共享文件夹

$ sudo mount -t nfs HPST_IP:/my_path /mount_folder -o user=host_user, uid=instance_uid,gid=instance_gid

Note: 对于挂载文件系统的性能若有要求,可以参考:
How to improve mounts performance in Multipass

最後修改日期: 2023 年 2 月 4 日

作者

留言

撰寫回覆或留言

發佈留言必須填寫的電子郵件地址不會公開。