构建自己的云模拟器

本文介绍如何将 AAOS 模拟器作为网络服务运行,并在网络浏览器中运行它,以供用户远程访问。这样一来,可以通过 Google Cloud Compute Engine 提供最低可行的端到端参考。 也就是说,您可以在您选择的任何公共云或私有云平台上使用此服务。

目的

通过这种集中式配置和设置,AAOS 模拟器可供整个公司、供应商和在家办公的开发者访问。这样做,可以更高效地管理 AAOS 模拟器并将其升级到新版本,以及消除为各个用户设置和管理本地机器所需的时间。此解决方案优化了硬件资源的使用,并实现了成本更低的应用开发环境。例如,它可用于以下目的:

  • 用户调查、用户体验审核、客户服务和培训。
  • 面向潜在客户以及在销售渠道进行演示。
  • 大规模测试、验证甚至调试应用(包括每日 OEM HMI build)。考虑使用此模拟器来替代用于开发应用的测试台。
  • OEM 客户呼叫中心代理拥有一个统一且易于访问的 HU 界面。

使用 AAOS 模拟器有诸多优势:

  • 使用设置脚本创建基于云的自定义 AAOS 模拟器(云模拟器)。
  • 为虚拟机实例构建自定义 AAOS 云模拟器映像:
    • 针对基于云的模拟器提供现成设置。
    • 向服务创建者提供公共 AAOS AVD 映像,以使用命令启动 AAOS AVD。例如,将公共 OEM AVD 映像用作一个示例,供合作伙伴调整和应用。

架构

云模拟器架构的示例如下图所示。通过添加自己的 OEM AVD 映像,您的第一个最简可行的服务即可正常运行。

图 1. 云 AVD 架构

模拟器的主要构建块包括:

项目 用途
Android 模拟器 模拟器实例可托管 AVD 映像
Goldfish-webrtc bridge 此 Linux 应用在 React 应用与 AAOS 模拟器之间提供通信
android-emulator-webrtc React 应用在网络浏览器中显示模拟器界面,还会捕获用户输入事件并将其发送回服务器。
Android 模拟器容器脚本 这些 Python 脚本用于管理和创建上述软件模块的 Docker 映像和容器。
JWT 服务(JSON 网络令牌服务) 生成令牌来管理模拟器的访问权限。
turn 服务器 在客户端和服务器之间建立一个 WebRTC 直接连接。只有在此模拟器服务在防火墙或代理环境下运行时,才需要使用 turn 服务器。
Envoy

此代理服务用于:

  • 使用自签名证书提供 HTTPS 服务。
  • 将端口 80 (http) 上的流量重定向到端口 443 (https)。
  • 充当此模拟器的 gRPC 代理。
  • 验证令牌以允许访问模拟器 gRPC 端点。
  • 将其他请求重定向到托管 React 应用的 Nginx 组件。

在云虚拟机上设置模拟器

如需创建 GCP 项目,请执行以下操作:

  1. 转到 Google Cloud 控制台并选择一个项目
  2. 如需确认是否已为您的 Google Cloud 项目启用结算功能,请参阅为项目启用、停用或更改结算功能
  3. 启用 API

在 GCE 中创建 Linux 虚拟机

1. 启用嵌套虚拟化

默认情况下,系统允许在项目、文件夹或组织级别使用嵌套虚拟化。除非您组织中的某个人停用了嵌套虚拟化,否则您不需要执行任何操作来启用嵌套虚拟化。

  1. 使用 gcloud 命令行工具确认是否启用了嵌套嵌套:
    gcloud beta resource-manager org-policies describe   \
      constraints/compute.disableNestedVirtualization  --effective --project=[PROJECT_ID]
    

2. 创建 Ubuntu-1804-lts 可启动磁盘

  1. 转到 Cloud Console
  2. 选择 GCP 项目。
  3. 依次转到:导航菜单 > Compute Engine > 磁盘 > 创建磁盘。
    1. 提供一个磁盘名称。例如:ubuntu1804lts
    2. 选择区域和可用区。如需支持嵌套虚拟化,请确保您选择的区域和可用区支持 Haswell(或更高版本)处理器。如需了解详情,请参阅区域和可用区
    3. 选择 ubuntu-1804-bionic-v20210211 的来源映像
    4. 设置适当的磁盘大小(建议设置为 100GB 或更大)。

图 1. 创建 Ubuntu 可启动磁盘

3. 使用特殊许可密钥创建自定义映像以启用 VMX

  1. 转到 Cloud Console
  2. 打开 Cloud Shell 并使用以下命令:
    gcloud compute images create [IMAGE NAME] --source-disk-zone [DISK ZONE] --source-disk [DISK NAME] \
      --licenses "https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx"
    
    • 输入映像名称。例如:aaos-emulator-image
    • 将磁盘可用区设置为您创建磁盘所在的可用区。
    • 将磁盘名称设置为您用于创建磁盘的名称。

    例如:

    gcloud compute images create aaos-emulator-image --source-disk-zone us-central1-a \
        --source-disk ubuntu1804lts \
        --licenses \
        "https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx"
    

如需了解详情,请参阅嵌套虚拟化虚拟机实例

4. 使用自定义映像创建虚拟机实例

  1. 转到 Cloud Console
  2. 选择 GCP 项目。
  3. 依次转到:导航菜单 > Compute Engine > 虚拟机实例。

    图 1. 创建虚拟机实例

  4. 输入实例名称。例如:aaosemulator
  5. 选择所需的机器系列和类型。确保机器包含四个 vCPU 和 16 GB(或更多)内存。
  6. 对于 CPU 平台,选择 Intel Cascade Lake(或更高版本)。
  7. 将启动磁盘更改为上一步中创建的映像。
  8. 为以下各项启用防火墙:
    • 允许 HTTP 流量
    • 允许 HTTPS 流量

5. 将防火墙配置为打开端口 80 和 443

  1. 转到 Cloud Console
  2. 选择 GCP 项目。
  3. 依次转到:导航菜单 > Compute Engine > 虚拟机实例 > 创建防火墙规则。

在虚拟机上安装所需的软件

  1. 安装 Python 3 和 Python3-env:
    sudo apt update
    sudo apt install python3
    sudo apt-get install python3-venv
    
  2. 安装该路径上可用的 Android SDK 和 ADB。
    sudo apt install android-sdk
    

    如需安装 Docker 和 Docker-compose,请参阅 DockerDocker-compose。确保您能以非根用户身份运行这些文件。

  3. 如需确认 CPU 可以支持硬件虚拟化,请运行以下命令(该命令应生成非零数字):
    egrep -c '(vmx|svm)' /proc/cpuinfo
    
  4. 安装内核虚拟机 (KVM)。如需安装 KVM,请运行以下命令:
    sudo apt-get install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils
    
  5. 如需验证 KVM 是否正常工作,请运行以下命令:
    sudo apt install cpu-checker
    kvm-ok
    
    输出应如下所示:
    INFO: /dev/kvm exists
    KVM acceleration can be used
    
  6. 如需安装 Node.js 和 Node Packet Manager (NPM),请运行以下命令:
    sudo apt install nodejs npm
    

启动托管的容器

  1. 如需验证安装情况,请从公开代码库运行托管的 Android 模拟器容器。您可以在此处查看有关此容器的详细信息。现在,您无需构建这些容器即可运行它们。例如:
    docker run \
      -e ADBKEY="$(cat ~/.android/adbkey)" \
      --device /dev/kvm \
      --publish 8554:8554/tcp \
      --publish 5555:5555/tcp  \
      us-docker.pkg.dev/android-emulator-268719/images/30-google-x64:30.1.2
    

    此操作会将容器提取到本地(如果本地未提供此容器),并启动容器。

  2. 启动容器后,按照在本地主机上连接 AVD 的方式对 ADB 进行配置,以连接到设备。例如:
    adb connect localhost:5555
    adb devices
    
    输出应如下所示:
    List of devices attached
    localhost:5555 device
    

设置 AAOS 模拟器服务

如需设置模拟器服务,请执行以下操作:

  1. 安装 Android 模拟器 Docker 容器脚本:
    git clone https://github.com/google/android-emulator-container-scripts.git
    
    cd android-emulator-container-script
    source ./configure.sh
    
  2. 这将激活虚拟环境并使可执行的 emu-docker 可用。 如需获取有关其使用情况的详细信息,请启动它:
    emu-docker -h
    
  3. 如需创建 Docker 容器,请接受许可协议。
  4. 构建 AAOS 模拟器 Docker 容器。
  5. 下载版本高于 7154743 的模拟器 build。例如:
    sdk-repo-linux-emulator-7154743.zip
    
  6. 下载 AAOS 模拟器系统映像。例如 sdk-repo-linux-system-images-7115454.zip
    emu-docker create <emulator-zip> <system-image-zip>
    
  7. 创建网络容器并设置用于远程访问的用户名和密码。
    ./create_web_container.sh -p user1,passwd1
    
  8. 启动 AAOS 模拟器网络服务:
    docker-compose -f js/docker/docker-compose-build.yaml -f js/docker/development.yaml up
    

您已成功启动 AAOS 模拟器网络服务!请在网络浏览器中使用以下网址进行访问:

https://<VM_External__IP>

问题排查

如果虚拟机外部 IP 出现连接错误,请确保将虚拟机设置为允许 HTTP 流量 HTTPS 流量。如需验证这一点,请参阅运行基本的 Apache 网络服务器

设置 turn 服务器

您可以始终使用自己的 turn 服务器。下面提供了 Google Cloud 虚拟机实例的示例。

注意:如需让 turn 服务器在 Google Cloud 虚拟机实例上正常运行,请确保将虚拟机防火墙规则配置为允许通过 TCP 和 UDP 端口 3478 和 3479 传输流量。

  1. 安装 coturn 服务器:
    sudo apt install coturn
    systemctl stop coturn
    echo "TURNSERVER_ENABLED=1"|sudo tee -a /etc/default/coturn
    
  2. 通过添加以下命令行来修改 /etc/turnserver.conf
    lt-cred-mech
    #set your realm name
    realm=test
    #coturn username and password
    user=test:test123
    # external-ip=<VM-Public-IP>/<VM-Private-IP>
    external-ip=34.193.52.134/10.128.0.2
    
    systemctl start coturn
    
  3. 修改 Docker Compose YAML 文件以包含 TURN 配置:
    cd android-emulator-container-script
    nano  js/docker/docker-compose-build.yaml
    
  4. 在模拟器部分中添加以下两行 environment 代码:
         shm_size: 128M
         expose:
           - "8554"
    +    environment:
    +       - TURN=printf $SNIPPET
    
  5. 使用 turn 配置重启 AAOS 模拟器服务。 请务必使用您自己的 turn 服务器 IP、用户名和凭据替换下面的相应项:
    export SNIPPET="{\"iceServers\":[{\"urls\":\"turn:35.193.52.134:3478\",\"username\":\"test\",\"credential\":\"test123\"}]}"
    docker-compose -f js/docker/docker-compose-build.yaml up