Anbox 安装过程分析

Anbox 是在像 Ubuntu 这样的普通 GNU/Linux 系统上,基于容器启动完整 Android 系统的方案。

当前安装过程由多个步骤组成,这些步骤将向主机系统中添加额外的组件,这些组件包括:

  • 由于没有发行版内核同时启用 binder 和 ashmem,因此需要它们的源码树之外的内核模块
  • /dev/binder/dev/ashmem 设置正确权限的 udev 规则
  • upstart 或 systemd 任务,用于作为用户会话的一部分启动 Anbox 会话管理器。

为了使 Anbox 的安装过程尽可能简单,Anbox 官方已经在一个 snap (参考 https://snapcraft.io) 中打包了必须的步骤,称为 “anbox-installer”。这个安装器将执行所有必须的步骤。可以通过运行如下命令,在系统上安装 Anbox 提供对 snaps 的支持:

$ snap install --classic anbox-installer

另外,还可以通过如下命令获得安装器脚本:

$ wget https://raw.githubusercontent.com/anbox/anbox-installer/master/installer.sh -O anbox-installer

要通过 Anbox 的安装器脚本安装 Anbox 的话,简单地调用即可:

$ anbox-installer

这将指导我们完成安装过程。

anbox-installer 安装器脚本的实现是这样的:

#!/bin/bash

echo "Anbox (Android in a Box) - Installer"
echo
echo
echo "IMPORTANT: THIS IS ALPHA LEVEL SOFTWARE. EXPECT INSTABILITY AND"
echo "           BUGS !!!!!"
echo
echo "IMPORTANT: ALSO PLEASE BE AWARE THAT WE DON'T PROVIDE FULL"
echo "           CONFINEMENT FOR THE SNAP YET !!!!"
echo
echo
echo "PLEASE NOTE: This script will require root access on your system"
echo "to install all necessary things. It will prompt you to enter your"
echo "password when required."
echo
echoif [ "$(id -u)" -eq 0 ] ; thenecho "ERROR: Don't run the anbox-installer as root or via sudo. Simply"echo "       invoke it with your regular user. The script will use sudo"echo "       on its own when needed."exit 1
fiif ! uname -a | grep -q x86_64 ; thenecho "ERROR: We only have support for x86 64 bit devices today. As"echo "       your system has a different architecture we can't"echo "       support it yet."exit 1
fiSUPPORTED_DISTROS=("Ubuntu" "LinuxMint" "neon" "elementary" "Zorin")
DISTRIB_ID="$(lsb_release -i -s)"function contains() {local n=$#local value=${!n}for ((i=1;i < $#;i++)) {if [ "${!i}" == "${value}" ]; thenecho "y"return 0fi}return 1
}if [ "$(contains "${SUPPORTED_DISTROS[@]}" "$DISTRIB_ID")" != "y" ]; thenecho "ERROR: You are running the installer on an unsupported distribution."echo "       At the moment we only support the following distributions:" echoprintf "%s, " "${SUPPORTED_DISTROS[@]}" | cut -d "," -f 1-${#SUPPORTED_DISTROS[@]}echoecho "If your distribution is in the list but you still see this message, open"echo "an issue here: https://github.com/anbox/anbox-installer"exit 1
fiecho
echo "What do you want to do?"
echo
echo " 1. Install Anbox"
echo " 2. Uninstall Anbox"
echo
echo "Please enter your choice [1-2]: "
read -r action
echo
echo[[ -n "$(which snap)" ]] || {echo "ERROR: Your system does not support snaps. Please have a look"echo "       at https://snapcraft.io/ to find out how you can add"echo "       support for snaps on your system."exit 1
}uninstall() {set -xsudo snap remove anboxif [ -e /etc/apt/sources.list.d/morphis-ubuntu-anbox-support-xenial.list ]; thenppa_purged_installed=0if ! dpkg --get-selections | grep -q ppa-purge ; thensudo apt install -y ppa-purgeppa_purged_installed=1fisudo apt install -y ppa-purgesudo ppa-purge -y ppa:morphis/anbox-supportif [ "$ppa_purged_installed" -eq 1 ]; thensudo apt purge ppa-purgefifiset +x
}if [ "$action" == "2" ]; thenecho "This will now remove the Android in a Box runtime environment"echo "from your device. Do you really want this?"echoecho "Please be aware that this will also remove any user data"echo "stored inside the runtime environment."echoecho "Please type 'I AGREE' followed by pressing ENTER to continue"echo "or type anything else to abort:"read -r inputif [ "$input" != "I AGREE" ]; thenexit 1fiechouninstallechoecho "Successfully removed anbox!"echoexit 0
fiif [ "$action" != "1" ]; thenecho "ERROR: Invalid option selected!"exit 1
fiecho "This is the installer for the anbox runtime environment. It will"
echo "install certain things on your system to ensure all requirements"
echo "are available for anbox to work correctly."
echo
echo "In summary we will install the following things:"
echo
echo " * Add the anbox-support ppa ppa:morphis/anbox-support to the"
echo "   host system"
echo " * Install the anbox-modules-dkms deb package from the ppa"
echo "   which will add kernel modules for ashmem and binder which are"
echo "   required for the Android container to work."
echo " * Configure binder and ashmem kernel modules to be loaded"
echo "   automatically on boot."
echo " * Install the anbox-common package from the ppa which will"
echo "   - Add an upstart job for the current user $USER which will"
echo "     start the anbox runtime on login."
echo "   - Add a X11 session configuration file to allow the system"
echo "     application launcher (Unity7, Gnome Shell, ..) to find"
echo "     available Android applications."
echo
echo "Please type 'I AGREE' followed by pressing ENTER to continue"
echo "or type anything else to abort:"
read -r input
if [ "$input" != "I AGREE" ]; thenexit 1
fi
echo
echoecho "Starting installation process ..."
echocleanup() {local err=$?trap - EXITecho "ERROR: Installation failed. Removing all parts of Anbox again."uninstallexit $err
}trap cleanup HUP PIPE INT QUIT TERM EXITset -exsudo add-apt-repository -y 'ppa:morphis/anbox-support'
# Users tend to have APT repositories installed which are not properly
# authenticated and because of that `apt update` will fail. We ignore
# this and proceed with the package installation. If the installation
# of a specific package fails this will indicate our point of abort.
sudo apt update || true
sudo apt install -y anbox-common# Install kernel drivers only if necessary and let the user use the
# ones build into his kernel otherwise.
if [ -c /dev/binder ] && [ -c /dev/ashmem ]; thenecho "Android binder and ashmem seems to be already enabled in kernel.";
elsesudo apt install -y linux-headers-generic anbox-modules-dkmssudo modprobe binder_linuxsudo modprobe ashmem_linux
fiif snap info anbox | grep -q "installed:" ; thensudo snap refresh --edge anbox || true
elsesudo snap install --edge --devmode anbox
fiset +xecho
echo "Done!"
echo
echo "To ensure all changes made to your system you should now reboot"
echo "your system. If you don't do this no Android applications will"
echo "show up in the system application launcher."
trap - EXIT

anbox-installer 安装器脚本中的 echo 打印输出有点多,同时这个脚本还提供了移除 anbox 的功能。安装 Anbox 的工作主要由如下这几行代码完成:

sudo add-apt-repository -y 'ppa:morphis/anbox-support'
. . . . . .
sudo apt update || true
sudo apt install -y anbox-common# Install kernel drivers only if necessary and let the user use the
# ones build into his kernel otherwise.
if [ -c /dev/binder ] && [ -c /dev/ashmem ]; thenecho "Android binder and ashmem seems to be already enabled in kernel.";
elsesudo apt install -y linux-headers-generic anbox-modules-dkmssudo modprobe binder_linuxsudo modprobe ashmem_linux
fiif snap info anbox | grep -q "installed:" ; thensudo snap refresh --edge anbox || true
elsesudo snap install --edge --devmode anbox
fiset +x
. . . . . .
trap - EXIT

这段代码,通过三个步骤完成 Anbox 的安装。

第一步,安装 anbox-common

sudo add-apt-repository -y 'ppa:morphis/anbox-support'
. . . . . .
sudo apt update || true
sudo apt install -y anbox-common

anbox-common 包的安装的文件如下:

$ dpkg -L anbox-common
/.
/etc
/etc/X11
/etc/X11/Xsession.d
/etc/X11/Xsession.d/68anbox
/usr
/usr/share
/usr/share/doc
/usr/share/doc/anbox-common
/usr/share/doc/anbox-common/README.Debian
/usr/share/doc/anbox-common/changelog.gz
/usr/share/doc/anbox-common/copyright
/usr/src

第二步,安装 binder 和 ashmem 驱动

    sudo apt install -y linux-headers-generic anbox-modules-dkmssudo modprobe binder_linuxsudo modprobe ashmem_linux

第三步,通过 snap 的方式安装 anbox 包

     sudo snap install --edge --devmode anbox

anbox 包通过 snap 的方式进行安装。

Anbox 容器管理服务

整体看来,Anbox 的安装过程安装了两个组件,一是 binder 和 ashmem 内核驱动;二是 Anbox,Anbox 又由 anbox-common 和 anbox snap 组成。

通过如下命令可以看到 anbox snap 的信息:

$ snap info anbox
name:      anbox
summary:   Android in a Box
publisher: morphis
description: |Runtime for Android applications which runs a full Android systemin a container using Linux namespaces (user, ipc, net, mount) toseparate the Android system fully from the host.
snap-id: Nr9K6UJaIOD8wHpDEQl16nabFFt9LLEQ
commands:- anbox- anbox.collect-bug-info
services:anbox.container-manager: simple, enabled, inactive
tracking:                  edge
installed:                 3-7266fe2 (65) 361MB devmode
refreshed:                 2017-11-17 21:37:23 +0800 CST
channels:                                 stable:                  –                    candidate:               –                    beta:                    1-dev     (15) 357MB devmodeedge:                    3-7266fe2 (65) 361MB devmode

anbox 向主机系统中安装了 2 个命令,anboxanbox.collect-bug-info,以及一个 service,anbox.container-manager,即 Anbox 的容器管理器服务。

通过 Anbox 安装器安装 Anbox 之后,service 会自动启动。通过如下命令可以查看这个服务的当前状态:

$ sudo systemctl status snap.anbox.container-manager
● snap.anbox.container-manager.service - Service for snap application anbox.container-managerLoaded: loaded (/etc/systemd/system/snap.anbox.container-manager.service; enabled; vendor preset: enabled)Active: active (running) since 五 2017-12-01 09:55:46 CST; 3min 54s agoProcess: 25619 ExecStop=/usr/bin/snap run --command=stop anbox.container-manager (code=exited, status=0/SUCCESS)Main PID: 30438 (anbox)Tasks: 10Memory: 1.8MCPU: 74msCGroup: /system.slice/snap.anbox.container-manager.service├─30438 /snap/anbox/65/usr/bin/anbox container-manager --data-path=/var/snap/anbox/common/ --android-image=/snap/anbox/└─30644 [lxc monitor] /var/snap/anbox/common/containers default12月 01 09:55:46 ThundeRobot anbox.container-manager[30438]: + [ ! -e /snap/anbox/65/android.img ]
12月 01 09:55:46 ThundeRobot anbox.container-manager[30438]: + start
12月 01 09:55:46 ThundeRobot anbox.container-manager[30438]: + mkdir -p /var/snap/anbox/common/lxc
12月 01 09:55:46 ThundeRobot anbox.container-manager[30438]: + /snap/anbox/65/bin/anbox-bridge.sh start
12月 01 09:55:46 ThundeRobot anbox.container-manager[30438]: + echo Y
12月 01 09:55:46 ThundeRobot anbox.container-manager[30438]: + tee /sys/module/fuse/parameters/userns_mounts
12月 01 09:55:46 ThundeRobot anbox.container-manager[30438]: Y
12月 01 09:55:46 ThundeRobot anbox.container-manager[30438]: + AA_EXEC=/snap/anbox/65/usr/sbin/aa-exec -p unconfined --
12月 01 09:55:46 ThundeRobot anbox.container-manager[30438]: + [ ! -d /sys/kernel/security/apparmor ]
12月 01 09:55:46 ThundeRobot anbox.container-manager[30438]: + exec /snap/anbox/65/usr/sbin/aa-exec -p unconfined -- /snap/anbox/65

当 Anbox 的容器管理服务正常运行时,通过在应用列表中,点击 Anbox 应用,如下图这样:

可以启动 Anbox 会话。

当 Anbox 的容器管理服务起动时,它会监听一个 Unix 域 Socket,/run/anbox-container.socket。(这个地址在 anbox/src/anbox/container/service.cpp 文件的 Service::create() 函数中,从 anbox::SystemConfiguration::container_socket_path() 获得)。

当启动 Anbox 应用,即会话管理器时,它会通过 Unix 域 Socket 与容器管理服务建立连接。容器管理服务接收到连接,且容器还没有启动时,它会挂载 Android 系统镜像,起动 LXC 容器,并在容器内起动 Android 系统。

同时会话管理器与主机系统上的 ADB 服务建立连接。如:

$ ps -aux | grep anbox
hanpfei+ 15883  3.3  1.0 3024640 175500 ?      Sl   19:01   0:34 /usr/bin/python3 /usr/bin/remarkable /home/hanpfei0306/data/MyProjects/hanpfei-documents/source/_posts/anbox_container_manager_service.md
root     16732  0.1  0.0 569980 12288 ?        Ssl  19:17   0:00 /snap/anbox/x1/usr/bin/anbox container-manager --data-path=/var/snap/anbox/common/ --android-image=/snap/anbox/x1/android.img --daemon
hanpfei+ 16765  4.5  0.2 335372 44676 ?        Sl   19:17   0:00 /snap/anbox/x1/usr/bin/anbox launch --package=org.anbox.appmgr --component=org.anbox.appmgr.AppViewActivity
root     16794  0.0  0.0  36776  3692 ?        Ss   19:17   0:00 /snap/anbox/current/libexec/lxc/lxc-monitord /var/snap/anbox/common/containers 14
hanpfei+ 16917  0.0  0.2 1281208 42556 ?       Sl   19:18   0:00 /snap/anbox/x1/usr/bin/anbox session-manager
root     16931  0.0  0.0 576280  8216 ?        Ss   19:18   0:00 [lxc monitor] /var/snap/anbox/common/containers default
100000   16940  0.0  0.0   7920  2540 ?        Ss   19:18   0:00 /system/bin/sh /anbox-init.sh
100000   16999  0.0  0.0  16472  4068 ?        Sl   19:18   0:00 /system/bin/anboxd
hanpfei+ 17087  0.0  0.0  19300   936 pts/2    R+   19:18   0:00 grep --color=auto anbox
$ adb devices
List of devices attached
emulator-5558   device$ lsof -i | grep adb
adb       30288 hanpfei0306    6u  IPv4 23788668      0t0  TCP localhost:5037 (LISTEN)
adb       30288 hanpfei0306    7u  IPv4 27391368      0t0  TCP localhost:42048->localhost:5559 (ESTABLISHED)
$ lsof -i | grep 42048
anbox     16917 hanpfei0306   29u  IPv4 27385836      0t0  TCP localhost:5559->localhost:42048 (ESTABLISHED)
adb       30288 hanpfei0306    7u  IPv4 27391368      0t0  TCP localhost:42048->localhost:5559 (ESTABLISHED)

此时可以通过 adb 命令查看 Anbox 起动的 Android 系统的状况,如下面这样:

$ adb devices
List of devices attached
emulator-5558   device$ adb logcat
--------- beginning of system
12-01 01:57:25.245    16    16 I vold    : Vold 3.0 (the awakening) firing up
12-01 01:57:25.245    16    16 V vold    : Detected support for: ext4 vfat
12-01 01:57:25.260    16    16 E vold    : Failed to open default fstab /fstab.goldfish: Operation not permitted
12-01 01:57:25.260    16    16 E vold    : Error reading configuration... continuing anyways: Operation not permitted
12-01 01:57:25.264    16    25 D vold    : e4crypt_init_user0
12-01 01:57:25.264    16    25 D vold    : e4crypt_prepare_user_storage for volume null, user 0, serial 0, flags 1
12-01 01:57:25.264    16    25 D vold    : Preparing: /data/system/users/0
12-01 01:57:25.264    16    25 D vold    : Preparing: /data/misc/profiles/cur/0
12-01 01:57:25.264    16    25 D vold    : Preparing: /data/misc/profiles/cur/0/foreign-dex
12-01 01:57:25.264    16    25 D vold    : Preparing: /data/system_de/0
12-01 01:57:25.264    16    25 D vold    : Preparing: /data/misc_de/0
12-01 01:57:25.264    16    25 D vold    : Preparing: /data/user_de/0

当 Anbox 起动的 Android 系统内所需的应用程序都启动完毕时,通过 Anbox 应用将可以看到 Android 系统的桌面,可以看到 Android 系统中的应用,如下图:

Anbox 项目写了一个名为 org.anbox.appmgr 的 Java 应用程序,用以替代原始 Android 系统中的 Launcher,以展示已安装应用列表。随后就可以像操作普通的桌面 Linux 系统中的应用那样操作 Android 内的应用了。

此时,查看主机 Linux 系统中与 Anbox 有关的进程,可以看到如下这些:

$ ps -aux | grep anbox
root     30438  0.0  0.0 373372 12144 ?        Ssl  09:55   0:00 /snap/anbox/65/usr/bin/anbox container-manager --data-path=/var/snap/anbox/common/ --android-image=/snap/anbox/65/android.img --daemon
hanpfei+ 30630  0.6  1.7 2770120 280580 ?      Sl   09:57   0:07 /snap/anbox/65/usr/bin/anbox session-manager
root     30644  0.0  0.0 379672  8016 ?        Ss   09:57   0:00 [lxc monitor] /var/snap/anbox/common/containers default
100000   30652  0.0  0.0   7920  6516 ?        Ss   09:57   0:00 /system/bin/sh /anbox-init.sh
100000   30711  0.0  0.0  16728  9240 ?        Sl   09:57   0:00 /system/bin/anboxd
110000   31209  0.0  0.7 1074676 116412 ?      Sl   09:57   0:00 org.anbox.appmgr

进程号为 30438 和 30644 的两个进程组成了容器管理器服务。进程号为 30630 的进程为我们启动的 Anbox 应用。进程号为 30652,30711,和 31209 的几个进程,实际为 Anbox 启动的容器中运行的 Android 系统的进程。Anbox 的整体设计可以参考 Anbox 一文。

Anbox snap

Anbox 应用通过 snap 方式打包,下载 anbox 的源码,并在源码目录下执行 snapcraft,可以生成 anbox 的 .snap 文件:

$ mkdir android-images
$ cp /path/to/android.img android-images/android.img
$ snapcraft

生成的 .snap 文件还可以通过如下命令进行安装:

$ snap install --dangerous --devmode anbox_3-7266fe2_amd64.snap

通过 Anbox 的 snapcraft.yaml 文件,可以对 Anbox 运行时、命令和服务有更深入的了解。Anbox 的 snapcraft.yaml 文件长这样:

name: anbox
version: 3
version-script: |if [ "$SNAPCRAFT_GRADE" = "stable" ]; thenecho $SNAPCRAFT_PROJECT_VERSIONelseecho $SNAPCRAFT_PROJECT_VERSION-$(git rev-parse --short HEAD)fi
summary: Android in a Box
description: |Runtime for Android applications which runs a full Android systemin a container using Linux namespaces (user, ipc, net, mount) toseparate the Android system fully from the host.
confinement: devmode
grade: develslots:# Depending on in which environment we're running we either need# to use the system or session DBus so we also need to have one# slot for each.dbus-session:interface: dbusbus: systemname: org.anboxdbus-system:interface: dbusbus: systemname: org.anboxapps:anbox:command: bin/anbox-wrapper.shcontainer-manager:command: bin/container-manager.sh startstop-command: bin/container-manager.sh stopdaemon: simplecollect-bug-info:command: bin/collect-bug-info.shparts:android-images:plugin: dump# This needs to be any directory but not the root one as if we use# it we get superious permissions errors with the copied .git treesource: databuild-packages:- wget
    install: |LOCAL_IMAGE=$SNAPCRAFT_PART_INSTALL/../../../android-images/android.imgif [ -f $LOCAL_IMAGE ]; thenecho "Using local image $LOCAL_IMAGE"cp $LOCAL_IMAGE $SNAPCRAFT_PART_INSTALL/android.imgelseIMAGE_PATH=IMAGE_NAME=ARCH=$(uname -m)case "$ARCH" inx86_64)IMAGE_PATH="2017/07/13"IMAGE_NAME="android_3_amd64.img";;arm*)IMAGE_PATH="2017/06/12"IMAGE_NAME="android_1_armhf.img";;*)echo "ERROR: Unknown architecture $ARCH"exit 1;;esac# FIXME: downloading with a source: field doesn't work as snapcraft# expects the downloaded file to be an archive it can extract.echo "Downloading image..."wget http://build.anbox.io/android-images/$IMAGE_PATH/$IMAGE_NAMEmv $IMAGE_NAME $SNAPCRAFT_PART_INSTALL/android.imgfiprime:- android.img
  anbox-common:plugin: dumpsource: scriptsorganize:snap-wrapper.sh: bin/anbox-wrapper.shcontainer-manager.sh: bin/container-manager.shanbox-bridge.sh: bin/anbox-bridge.shcollect-bug-info.sh: bin/collect-bug-info.shprime:- bin/anbox-bridge.sh
      - bin/anbox-wrapper.sh
      - bin/container-manager.sh
      - bin/collect-bug-info.sh
  apparmor:plugin: nilstage-packages:- apparmor
  lxc:source: https://github.com/lxc/lxcsource-type: gitsource-tag: lxc-2.0.7build-packages:- libapparmor-dev
      - libcap-dev
      - libgnutls28-dev
      - libseccomp-dev
      - pkg-config
    plugin: autotoolsconfigflags:- --disable-selinux
      - --disable-python
      - --disable-lua
      - --disable-tests
      - --disable-examples
      - --disable-doc
      - --disable-api-docs
      - --disable-bash
      - --disable-cgmanager
      - --disable-apparmor
      - --disable-seccomp
      - --enable-capabilities
      - --with-rootfs-path=/var/snap/anbox/common/lxc/
      - --libexecdir=/snap/anbox/current/libexec/
    organize:snap/anbox/current/libexec: libexecprime:- lib/liblxc.so.1
      - lib/liblxc.so.1.2.0
      - libexec/lxc/lxc-monitord
      - bin/lxc-start
      - bin/lxc-stop
      - bin/lxc-info
      - bin/lxc-attach
      - bin/lxc-ls
      - bin/lxc-top
  anbox:plugin: cmakeafter:- lxc
    source: .configflags:# FIXME: Anbox currently has some paths with hard coded prefixes. Once# that is fixed we can avoid using a prefix here.- -DCMAKE_INSTALL_PREFIX:PATH=/usr
      - -DANBOX_VERSION=$SNAPCRAFT_PROJECT_VERSION
    build-packages:- build-essential
      - cmake
      - cmake-data
      - cmake-extras
      - debhelper
      - dbus
      - google-mock
      - libboost-dev
      - libboost-filesystem-dev
      - libboost-log-dev
      - libboost-iostreams-dev
      - libboost-program-options-dev
      - libboost-system-dev
      - libboost-test-dev
      - libboost-thread-dev
      - libcap-dev
      - libdbus-1-dev
      - libdbus-cpp-dev
      - libegl1-mesa-dev
      - libgles2-mesa-dev
      - libglib2.0-dev
      - libglm-dev
      - libgtest-dev
      - libprotobuf-dev
      - libproperties-cpp-dev
      - libsdl2-dev
      - libsdl2-image-dev
      - pkg-config
      - protobuf-compiler
    stage-packages:- libegl1-mesa
      - libgles2-mesa
      - libgl1-mesa-glx
      - libsdl2-2.0-0
      - libsdl2-gfx-1.0-0
    install: |make testprime:- usr/bin/anbox
      - usr/share/anbox
      - usr/lib/*-linux-*/

从 Anbox 的 snapcraft.yaml 文件中可以看到,Anbox snap 安装的几个命令和服务,是一些脚本:

apps:anbox:command: bin/anbox-wrapper.shcontainer-manager:command: bin/container-manager.sh startstop-command: bin/container-manager.sh stopdaemon: simplecollect-bug-info:command: bin/collect-bug-info.sh

Anbox snap 主要由这几部分组成:
* Android 系统镜像,先找本地的 android-images/android.img,如果找不到,就根据主机系统的 CPU 架构,从远端下载
* anbox-common,主要是一些脚本,提供 Anbox snap 的命令和服务,由 source: 行可以看到这些脚本都位于源码目录的 scripts 子目录下
* apparmor,从 Ubuntu 的 APT 源获得
* lxc,用于做容器管理,从 GitHub 获得源码,并由 tag 为 lxc-2.0.7 的版本编译生成
* anbox 二进制可执行程序,通过 cmake 编译生成,如:

$ git clone https://github.com/anbox/anbox.git
$ cd anbox
$ mkdir build
$ cd build
$ cmake ..
$ make

还可以通过如下命令编译带符号的 Debug 版 anbox 二进制可执行程序:

$ mkdir Debug
$ cd Debug
$ cmake -DCMAKE_BUILD_TYPE=Debug ..
$ make

或 Release 版:

$ mkdir Release
$ cd Release
$ cmake -DCMAKE_BUILD_TYPE=Release ..
$ make

这里来看一下 Anbox snap 的主要命令和服务,也就是几个脚本的实现。container-manager.sh 脚本,用于起动容器管理服务,其内容如下:

#!/bin/sh
set -x# We need to put the rootfs somewhere where we can modify some
# parts of the content on first boot (namely file permissions).
# Other than that nothing should ever modify the content of the
# rootfs.DATA_PATH=$SNAP_COMMON/
ROOTFS_PATH=$DATA_PATH/rootfs
ANDROID_IMG=$SNAP/android.imgif [ ! -e $ANDROID_IMG ]; thenecho "ERROR: android image does not exist"exit 1
fistart() {# Make sure our setup path for the container rootfs# is present as lxc is statically configured for# this path.mkdir -p $SNAP_COMMON/lxc# We start the bridge here as long as a oneshot service unit is not# possible. See snapcraft.yaml for further details.$SNAP/bin/anbox-bridge.sh start# Ensure FUSE support for user namespaces is enabledecho Y | tee /sys/module/fuse/parameters/userns_mounts || echo "WARNING: kernel doesn't support fuse in user namespaces"# Only try to use AppArmor when the kernel has support for itAA_EXEC="$SNAP/usr/sbin/aa-exec -p unconfined --"if [ ! -d /sys/kernel/security/apparmor ]; thenecho "WARNING: AppArmor support is not available!"AA_EXEC=""fiexec $AA_EXEC $SNAP/bin/anbox-wrapper.sh container-manager \--data-path=$DATA_PATH \--android-image=$ANDROID_IMG \--daemon
}stop() {$SNAP/bin/anbox-bridge.sh stop
}case "$1" instart)start;;stop)stop;;*)echo "ERROR: Unknown command '$1'"exit 1;;
esac

在这个脚本中,启动容器管理服务时,调用 anbox-bridge.sh start 脚本为 Anbox 创建虚拟网卡,并调用 anbox-wrapper.sh 启动 anbox 二进制可执行程序。脚本的执行依赖几个环境变量的设置。在脚本执行时,环境变量 SNAP 指向 /snap/anbox/current,环境变量 SNAP_COMMON 指向 /var/snap/anbox/common

anbox-wrapper.sh 也就是 anbox 源码库中的 scripts/snap-wrapper.sh,其内容如下:

#!/bin/bash

if [ "$SNAP_ARCH" == "amd64" ]; thenARCH="x86_64-linux-gnu"
elif [ "$SNAP_ARCH" == "armhf" ]; thenARCH="arm-linux-gnueabihf"
elseARCH="$SNAP_ARCH-linux-gnu"
fiexport LD_LIBRARY_PATH=$SNAP/usr/lib/$ARCH:$LD_LIBRARY_PATH# Mesa Libs
export LD_LIBRARY_PATH=$SNAP/usr/lib/$ARCH/mesa:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=$SNAP/usr/lib/$ARCH/mesa-egl:$LD_LIBRARY_PATH# XDG Config
export XDG_CONFIG_DIRS=$SNAP/etc/xdg:$XDG_CONFIG_DIRS
export XDG_CONFIG_DIRS=$SNAP/usr/xdg:$XDG_CONFIG_DIRS# Note: this doesn't seem to work, QML's LocalStorage either ignores
# or fails to use $SNAP_USER_DATA if defined here
export XDG_DATA_DIRS=$SNAP_USER_DATA:$XDG_DATA_DIRS
export XDG_DATA_DIRS=$SNAP/usr/share:$XDG_DATA_DIRS# Tell libGL where to find the drivers
export LIBGL_DRIVERS_PATH=$SNAP/usr/lib/$ARCH/dri# ensure the snappy gl libs win
export LD_LIBRARY_PATH="$SNAP_LIBRARY_PATH:$LD_LIBRARY_PATH"# Workaround in snapd for proprietary nVidia drivers mounts the drivers in
# /var/lib/snapd/lib/gl that needs to be in LD_LIBRARY_PATH
# Without that OpenGL using apps do not work with the nVidia drivers.
# Ref.: https://bugs.launchpad.net/snappy/+bug/1588192
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/var/lib/snapd/lib/gl# We set XDG_DATA_HOME to SNAP_USER_COMMON here as this will be the location we will
# create all our application launchers in. The system application launcher will
# be configured by our installer to look into this directory for available
# launchers.
export XDG_DATA_HOME="$SNAP_USER_COMMON/app-data"exec $SNAP/usr/bin/anbox $@

在这个脚本中,主要导出了一些环境变量,LD_LIBRARY_PATHXDG_CONFIG_DIRSXDG_DATA_DIRSLIBGL_DRIVERS_PATHXDG_DATA_HOME,以使 anbox 二进制可执行程序在启动之后,可以找到所需的动态链接库等。

打赏

参考文档:
Upstart
浅析 Linux 初始化 init 系统,Systemd
Debug vs Release in CMAKE

Anbox 容器管理服务相关推荐

  1. Kubernetes复杂吗?Cube-新的容器管理服务产品

    <介绍Calico eBPF数据平面:Linux内核网络.安全性和跟踪(Kubernetes.kube-proxy)> <在CentOS 7上安装使用Kubernetes:管理云平台 ...

  2. 容器管理大战:Kubernetes vs.Docker Swarm与Amazon ECS

    Container Orchestration: 快速入门 自20世纪70年代以来,容器技术就已经出现,但直到2013年Docker首次亮相后才开始发挥作用.从那时起,容器已经流行起来:它们正在显著地 ...

  3. 腾讯蓝鲸智云社区版V6.0.3携手容器管理平台正式发布!

    2020年11月,我们正式推出了蓝鲸智云社区版V6.0 Beta版,4款新产品的亮相 + 7款产品的重大更新.今天我们为大家带来了社区版V6.0.3正式版以及期待已久的容器管理平台(BCS),快来部署 ...

  4. AWS Fargate告诉你:什么是容器即服务

    本文翻译自:Freecodecamp, 原文地址:An intro to Amazon Fargate: what it is, why it's awesome (and not), and whe ...

  5. Anbox 实现分析 3:会话管理器与容器管理器的通信

    Anbox 通过一个可执行文件,实现多个不同的应该用逻辑.在启动 Anbox 可执行文件时,通过为它提供不同的命令行参数来确定具体执行哪个命令.Anbox 中这些不同的命令实例之间,整体的通信架构如下 ...

  6. 下一代云原生应用制品管理平台,容器镜像服务企业版优惠进行时

    随着越来越多的企业拥抱容器.拥抱云原生技术,享受技术带来的弹性.敏捷.可移植的便利,但是在实现容器技术生产落地时,很难规避以下痛点问题: 1. 运维复杂度:需要自建一个高可用的镜像服务去面对峰值流量等 ...

  7. 49学习容器管理平台 Docker Swarm 的基本概念和应用,包括节点管理、服务编排

    Docker Swarm 是 Docker 官方提供的容器编排工具,可以管理多个 Docker 节点,并支持自动化扩展.负载均衡等功能.下面是 Docker Swarm 的基本概念和使用方法,包括节点 ...

  8. 云容器实例服务入门必读

    云容器实例服务入门必读 华为云容器实例(Cloud Container Instance)服务是基于Kubernetes的Serverless Container(无服务器容器)引擎,兼容Kubern ...

  9. 阿里云宣布进入 Serverless 容器时代,推出弹性容器实例服务 ECI

    2019独角兽企业重金招聘Python工程师标准>>> 为了应对业务高峰,打算提前多久执行ECS扩展? 买了ECS虚拟机,容器规格不能完美装箱怎么办? OS又出patch了,什么时候 ...

最新文章

  1. Android Studio 新建项目的R文件丢失的解决方法
  2. python大学课程-利用python完成大学刷课(从0到完成的思路)
  3. oss客户端工具_干货 | 基于Go SDK操作京东云对象存储OSS的入门指南
  4. ubuntu安装chrome driver
  5. jQuery页面滚动图片等元素动态加载实现
  6. mysql1241 错误,[Err] 1241 - Operand should contain 1 column(s)错误解析
  7. VC编写程序在debug下正常,在release下错误
  8. Google是如何识别原创文章的,以及外链建设意见
  9. [spoj694spoj705]New Distinct Substrings(后缀数组)
  10. linux 系统日志 驱动,linux下安装显卡驱动求救(内附安装日志文件)
  11. java将pdf,word,excel转成图片
  12. 支持wmv、mpg、mov、avi格式的网页视频播放代码
  13. 多个jdk配置环境变量
  14. mysql now()函数调用系统时间不对修正方法
  15. 计算机鼠标老跳动,鼠标跳动是什么原因 鼠标经常抖动的解决方法
  16. 北京航空航天大学夏令营机试题
  17. AES与RSA混合加密完整实例
  18. 荣耀手机怎么使用鸿蒙系统,荣耀供应链6月全面恢复,安卓系统依然是第一选择,鸿蒙只是备选...
  19. PS 之AD命令之Get-ADuser!
  20. python 多线程采集amac

热门文章

  1. 图解复盘总结和报告模板实例
  2. 【办公-excel】Excel批量翻译
  3. Java利用接口计算立体图形的表面积和体积
  4. Lab3 Attack Lab
  5. Unicode码和ASCII码及其转换
  6. 一次培训机构的Java面试
  7. 为什么选择高防DNS云解析?(二)
  8. 超出预算,他的处理的方式对吗? | 每天成就更大成功
  9. 漫画:国内都有哪些程序员大牛?
  10. IDEA使用database时,连接MySQL后schemas不显示数据库名的情况