独自のクラウド エミュレータを作成する

この記事では、ウェブサービスとして AAOS エミュレータを実行し、ウェブブラウザでリモートからアクセスできるようにする方法を説明します。それにより、Google Cloud Compute Engine を通じて、エンドツーエンドかつ最小限の実行可能なリファレンスを配信できるようになります。そのサービスは、任意のパブリックまたはプライベートのクラウド プラットフォーム上で使用できます。

目的

構成と設定を一元化することで、会社全体、サプライヤー、在宅勤務の開発者が AAOS エミュレータにアクセスできるようにします。それにより、AAOS エミュレータを効率的に管理およびアップグレードできるようになり、個々のユーザーが使用するローカルマシンをセットアップおよび管理する時間を排除できます。また、このソリューションにより、ハードウェア リソースの使用を最適化し、低コストのアプリ開発環境を実現できます。たとえば、次のような用途にこのソリューションを活用できます。

  • ユーザー調査、ユーザー エクスペリエンス レビュー、カスタマー サポート、トレーニング。
  • 見込み顧客に対するデモ、販売チャネルでのデモ。
  • アプリの大規模なテスト、検証、デバッグ(毎日の OEM HMI ビルドを含む)。アプリ開発に使用するテストベンチの代わりとしてエミュレータを使用できます。
  • OEM コールセンターのエージェントが簡単に使用できる統一 HU UI

AAOS エミュレータを使用するメリットには、次のようなものがあります。

  • セットアップ スクリプトを使用して、クラウドベースの AAOS エミュレータ(クラウド エミュレータ)を作成し、カスタマイズできる。
  • AAOS クラウド エミュレータ イメージをビルドして、VM インスタンスごとにカスタマイズできる。
    • クラウドベースのエミュレータを即座にセットアップできる
    • サービス作成者が公開されている AAOS AVD イメージ使用して、コマンドで AAOS AVD を起動できる。たとえば、サンプルとして公開されている OEM AVD イメージをパートナーが修正して使用できます。

アーキテクチャ

クラウド エミュレータのサンプルのアーキテクチャを以下に示します。独自の OEM AVD イメージを追加することで、最低限の実行可能なサービスが動作します。

図 1. クラウド AVD のアーキテクチャ

エミュレータの主な構成要素は次のとおりです。

構成要素 目的
Android Emulator AVD イメージをホストするエミュレータ インスタンス。
Goldfish - WebRTC ブリッジ React アプリと AAOS エミュレータの間で通信できるようにする Linux アプリケーション。
android-emulator-webrtc ウェブブラウザにエミュレータの UI を表示する React アプリケーション。また、React はユーザー入力イベントを受け取り、サーバーに送り返します。
Android Emulator コンテナ スクリプト 上記のソフトウェア モジュールの Docker イメージとコンテナの管理や作成を行うための Python スクリプト。
JWT サービス(JSON Web Token サービス) エミュレータのアクセス権限を管理するためのトークンを生成。
TURN サーバー クライアントとサーバーの間で WebRTC の直接接続を確立します。エミュレータ サービスがファイアウォールまたはプロキシの背後で実行されている場合にのみ、TURN サーバーが必要になります。
Envoy

以下を行うプロキシ サービス。

  • 自己署名証明書を使用して HTTPS を提供する。
  • ポート 80(http)のトラフィックをポート 443(https)にリダイレクトする。
  • エミュレータの gRPC プロキシとして機能する。
  • トークンを確認して、エミュレータの gRPC エンドポイントへのアクセスを許可する。
  • その他のリクエストを、React アプリケーションをホストする Nginx コンポーネントにリダイレクトする。

クラウド VM にエミュレータをセットアップする

次の手順に沿って GCP プロジェクトを作成します。

  1. Google Cloud Console に移動して、プロジェクトを選択します。
  2. Google Cloud プロジェクトに対して課金が有効になっていることを確認するには、プロジェクトの課金の有効化、無効化、変更をご覧ください。
  3. API を有効化します。

GCE に Linux VM を作成する

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(または Haswell 以降)のプロセッサをサポートしているリージョンとゾーンを選択してください。詳細については、リージョンとゾーンをご覧ください。
    3. ubuntu-1804-bionic-v20210211 のソースイメージを選択します。
    4. 適切なディスクサイズを設定します(100 GB 以上をおすすめします)。

図 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"
    

詳しくは、ネストされた仮想化の VM インスタンスをご覧ください。

4. カスタマイズしたイメージを使用して VM インスタンスを作成する

  1. Cloud Console に移動します。
  2. GCP プロジェクトを選択します。
  3. ナビゲーション メニュー > [Compute Engine] > [VM インスタンス] の順に移動します。

    図 1. VM インスタンスを作成する

  4. インスタンス名を入力します。例: aaosemulator
  5. 希望のマシン ファミリーとマシンタイプを選択します。最低でも 4 つの vCPU と 16 GB のメモリを搭載したマシンを選択してください。
  6. CPU プラットフォームには Intel Cascade Lake(またはそれ以降)を選択します。
  7. ブートディスクを前の手順で作成したイメージに変更します。
  8. ファイアウォールを以下のように設定します。
    • HTTP トラフィックを許可する
    • HTTPS トラフィックを許可する

5. ファイアウォールを設定してポート 80 と 443 を開く

  1. Cloud Console に移動します。
  2. GCP プロジェクトを選択します。
  3. ナビゲーション メニュー > [Compute Engine] > [VM インスタンス] の順に移動して、ファイアウォール ルールをセットアップします。

必要なソフトウェアを VM にインストールする

  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 をご覧ください。これらを root 以外のユーザーも実行できるようにしておいてください。

  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 Emulator コンテナを公開リポジトリから実行します。コンテナの詳細については、こちらをご覧ください。これらのコンテナをビルドせずに実行できるようになりました。次に例を示します。
    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
    

    これにより、コンテナが(ローカルにない場合は)pull されて、起動します。

  2. コンテナが起動したら、ローカルホスト上の AVD を接続するのと同じ方法で ADB を設定し、デバイスに接続します。次に例を示します。
    adb connect localhost:5555
    adb devices
    
    出力は次のようになります。
    List of devices attached
    localhost:5555 device
    

AAOS エミュレータ サービスをセットアップする

次の手順に沿ってエミュレータ サービスをセットアップします。

  1. Android Emulator 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 の使用と起動に関する詳細情報を確認するには、以下のコマンドを使用します。
    emu-docker -h
    
  3. Docker コンテナを作成するために、使用許諾に同意します。
  4. AAOS エミュレータ Docker コンテナをビルドします。
  5. バージョン 7154743 以降のエミュレータ ビルドをダウンロードします。次に例を示します。
    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>

トラブルシューティング

VM の外部 IP への接続でエラーが発生した場合は、VM が HTTP トラフィックと HTTPS トラフィックの両方を許可するように設定されていることを確認します。これを確認するには、基本的な Apache ウェブサーバーの実行をご覧ください。

TURN サーバーをセットアップする

いつでも独自の TURN サーバーを使用できます。以下に、Google Cloud VM インスタンスのサンプルを示します。

注: Google Cloud VM インスタンスで TURN サーバーを機能させるには、VM ファイアウォール ルールを設定して 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. エミュレータ セクションに環境に関する次の 2 行を追加します。
         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