1 Star 1 Fork 0

yuebiao/docker-Android

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

使用手册

./android_ctl.sh [指令] [附加参数]

具体指令及附加参数请执行 ./android_ctl.sh --help 查看

整体实现逻辑

image-20231129171717210

  • .env中包含了脚本和compose file的配置信息,作为配置持久化文件
  • 脚本调用docker compose的CLI进行安卓容器的控制
  • docker compose 会读取 docker-compose.yml文件中的容器配置启动容器
  • docker-compose.yml中的变量会被.env中的环境变量替换
  • 脚本中的某些不能依靠docker compose实现的实务,如:分辨率、磁盘、网速等配置也会从.env文件中进行读取

.env 分析

配置项有两种

  • 所有容器公用的配置
  • 每个容器私有的配置

compose file分析

在compose file中,描述了n个服务,每个服务中都放了安卓容器的详细配置信息,还有一个自定义的网桥

version: "3.8"
services:
  "android_0":
    # android_0的配置信息
  "android_1":
    # ...
  "android_2":
    # ...
  "android_3":
  "android_4":
 networks:
  android-bri:
    ipam:
      driver: default
      config:
        - subnet: "172.20.0.0/16"
    name: android-bri
    driver_opts:
      com.docker.network.bridge.name: android-bri

默认放了5台的配置,也就是说此时使用create最多只能创建五台安卓

后面可以通过在 docker-compose.yml拷贝上面的内容,并修改id进行扩展

细节分析:

如下是对android_0的所有配置,其他与这个基本一致,仅仅换了id

services:
  "android_0":
    container_name: ${CONTAINER_NAME_PRE}0
    image: ${IMAGE_0}
    restart: unless-stopped
    privileged: true
    volumes:
      - "${ANDROID_DATA_DIR}/data_0:/data"
      - "${ANDROID_CONF_DIR}/container_common.conf:/vendor/etc/container/container_common.conf"
      - "${ANDROID_CONF_DIR}/container_0.conf:/vendor/etc/container/container.conf"
      - "./sh/health_check.sh:/health_check.sh"

    ports:
      - "1100:5555"

    healthcheck:
      test: sh /health.sh
      interval: 1s
      timeout: 2s
      retries: 10
      start_period: 5s
      start_interval: 1s
    deploy:
      resources:
        limits:
          memory: ${MEM_UPPER_LIMIT_0}
          cpus: '${CPUS_0}'
        reservations:
          memory: ${MEM_LOWER_LIMIT_0}
    networks:
      android-bri:
        ipv4_address: 172.20.0.2

分析:

  • 容器名前缀可以通过在.env文件配置CONTAINER_NAME_PRE变量实现,一般用默认的android_即可,尽量不要修改

  • .env文件中有一个IMAGE_BASE表示基础镜像,容器初始化会使用这个值覆盖IMAGE_0,compose创建容器时会把这个值替换到compose-file中

  • 默认开启

    • restart: unless-stopped:容器可以由用户手动停止,但在守护进程重启时总是自动重新启动。
    • privileged: 容器享有和宿主机同级权限(必须开启)
  • 绑定的存储卷:

    • 安卓的/data目录
    • 安卓公用配置文件
    • 安卓私有配置文件
    • 健康检查脚本:用于健康检查
    • tc_in_container脚本:容器的外部上行网速需要进入容器通过调用此脚本进行
  • 端口绑定:1100:5555,表示外部可以通过宿主机ip:1100访问到容器的5555端口,此时5555端口对应的是安卓的adbd服务,后面需要根据需求修改

  • 健康检查:每1秒调一次健康检查脚本,如果超过2秒没有返回则表示此次检查超时,再等1秒开始下一次检查,循环10次,如果10次之后脚本还没有返回0,则表示容器不健康,其中启动时间设置为5s,启动时间内如果脚本返回0,则表示为健康,且启动时间内的重试次数不计入10次之中,如下是理解图

    docker compose health check 时间流程图

    health_check脚本如下

    if ! ping -c 1 www.baidu.com; then
        exit 1
    fi
    
    if ! setprop vendor.dump true; then
        exit 1
    fi
    if ! setprop abcdef "/data/dev"; then
        exit 1
    fi
    exit 0
    
  • 内存和CPU限制可以通过compose-file完成,具体值存在.env文件中,调用脚本是会有两步操作

    • 以不重启安卓的方式进行限制,docker可以完成
    • 再.env文件中进行持久化,以供docker compose下次重启时自动限制
  • 网络使用自定义的网桥,且ip会为每个容器进行静态分配

部分脚本函数分析

脚本分为三种

  • 主脚本:android_ctl.sh
  • 需要被主脚本include 的脚本:usage.sh , util.sh
  • 被调用脚本,在程序运行过程中会被调用

工具集

即util.sh脚本

log()

打印日志

调用方式:

log LOGLEVAL MESSAGE
  • LOGLEVAL:当前日志的等级,分三级
    • DEBUG:调试,此日志不会写入日志文件,仅标准输出可见
    • INFO
    • DERROR

主脚本

init_device

  • 安装必要的工具如:fping、quota、docker
  • 创建用户数据目录的镜像挂载,后续待Linux系统完善之后次步操作会去除
  • 将安卓的配置文件从当前目录拷贝到/userdata/container下
  • 通过.env文件中指定的SUPER_IMAGE文件创建docker镜像

tc.sh

可以限制四种方向的网速:

  • 外部上行
  • 外部下行
  • 内部上行
  • 内部下行

全部使用tc工具进行限速

tc工具的特性:只能捕获从网卡出去的报文,无法捕获从网卡进来的报文

tc通过三个部分完成限速:

  • qdisc:最根部,所有要从网卡发出的数据帧首先会经过这里
  • class:其中标注了限速
  • filter:过滤器,其中标注了过滤规则和流向class,数据帧从qdisc出来会被filter筛选,然后进入某个class

虽然tc只能限制网卡的出口速度,但是我们使用的是网桥,

  • 所有容器的数据帧都会发向网关网卡(虚机的上传),再由网关网卡经由NAT转发到宿主机的物理网卡,此时可以数据帧中的源ip区分,从而进行限速

  • 网关网卡会向虚机发送数据帧(虚机的下载),此时数据帧的目的ip就是容器的ip,通过此进行过滤限速

但实际测试中只有下载速度可限制,上传速度不可限,可能是由于网络命名空间以及docker虚拟网桥的实现原理,由容器网卡发出的数据帧不会进入宿主机对网关网卡设置的qdisc,从而无法限速

所以只能在容器内部对其网卡添加qdisc队列对所有数据帧进行限制,从而限制上传速度

内部限制就是过滤源ip或者目的ip为内网网段,然后进行速率限制

存在的问题

  • 当前由于Linux文件系统暂时不支持quota限额,为了模拟,手动开辟了一块空间并格式化文件系统挂载到/userdata/container/android_data目录下,此目录下的子目录将可以完成quota限额

    但是宿主机重启后,镜像不会自动挂载,需要手动挂载

  • 宿主机重启后,物理网卡和网桥的tc限制会清空,安卓内部的tc限制还在

  • tc限制外部上传速度的时候需要再安卓手机的命名空间内进行,如果用户有root权限,可能会解除此限制

空文件

简介

使用docker在Linux物理主机操作安卓容器的shell脚本 展开 收起
取消

发行版

暂无发行版

贡献者 (5)

全部

语言

近期动态

4个月前推送了新的 main 分支
1年多前推送了新的提交到 master 分支,bbea641...736b0ce
1年多前推送了新的提交到 master 分支,8c3452d...bbea641
1年多前推送了新的提交到 master 分支,6d65e61...8c3452d
1年多前推送了新的提交到 master 分支,8cfe1b8...6d65e61
加载更多
不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/Y_future/docker-android.git
git@gitee.com:Y_future/docker-android.git
Y_future
docker-android
docker-Android
main

搜索帮助