使用 Docker 部署 openstf 平台

一、背景

笔者所处业务需要搭建一个云测平台,用于集中管理一批安卓系统板卡,经过方案选择,决定使用 openstf 进行搭建,一来 openstf 开源,二来大部分服务采用nodejs进行编写,方便笔者进行二次开发。

二、主要环境

本地环境为 mac,线上环境为 k8s(docker),连接板卡环境为deepin(linux)。

生产环境为 docker 和 linux,为了测试,会首先在 mac 上搭建,所以以下搭建过程会兼顾 mac 环境。

三、openstf 架构

openstf 架构图.png

官方文档上将一个个服务称为单元。在本次部署中,将 stf-provider 单元部署在直接连接设备的 linux 机器上,其他主单元部署在云端服务器上。具体单元分配如下:

  • 云服务器:
    • rethinkdb
    • stf-storage-temp
    • stf-storage-plugin-apk
    • stf-storage-plugin-image
    • stf-triproxy-app
    • stf-triproxy-dev
    • stf-processor
    • stf-websocket
    • stf-api
    • stf-reaper
    • stf-app
    • stf-auth
  • linux(deepin)机器:
    • adbd
    • stf-provider

mac 无法使用 docker host 模式,但是 stf-provider 需要监听一定范围内的端口,所以无法在mac上使用 stf provider
adbd 需要映射 /dev/bus/usb,mac 上没有该输入。所以这两个服务要部署在本地 linux 机器(windows 自查)。

下面介绍每个单元的作用及提供 docker 启动脚本。以下顺序也是服务启动顺序。
以下实例中,除了 adbdstf-provider 单元,其他单元同一台机器进行部署。所以端口都设置成不冲突的端口,在容器需要访问其他服务 ip 时都使用了 host.docker.internal127.0.0.1,如果部署在不同机器上,需要将其替换成机器地址。

其中,host.docker.internal 在容器内能映射成宿主机 ip,主要是为了兼容不支持 host 的环境(如mac),在支持 host 的环境中(如 linux),也可直接换成 127.0.0.1

四、主服务部署(云服务器)

1、rethinkdb

rethinkdb 为 openstf 服务采用的数据库服务(据说当时作者在开发时选择它是因为作者想学习当时作为新技术的 rethinkdb )。有 RethinkDB 集群的话可以不启动此服务。

docker run -it --rm \
  --name rethinkdb \
  -v $HOME/demo/rethinkdb:/data \
  -p 28015:28015 \
  -p 8080:8080 \
  -p 29015:29015 \
  rethinkdb \
  rethinkdb --bind all \
    --canonical-address host.docker.internal \
    --cache-size 8192 \
    --no-update-check 

参数注释如下:

  • -it 让容器保持在前台运行,此参数在生产环境部署可去除;
  • --rm 在容器退出时自动清理容器内部的文件系统,方便调试,此参数在生产环境部署时可去除;
  • host.docker.internal 在容器内会映射到宿主机 ip,如果 docker 使用 host 模式可以替换成 127.0.0.1
  • -p 为宿主机端口到容器内端口的映射,以上暴露的三个端口,都是连接 rethinkdb 需要用到的。这么处理是为了兼容不支持 docker host 模式的环境(如mac),linux 机器可以直接使用 --net=host 共享宿主机网络。之后没有特殊说明,都采用相同的处理。

2、* stf-migrate

此单元初始化数据库表,创建 stf 需要的各种表格。只需要运行一次。

docker run --rm \
  --name migrate \
  -e RETHINKDB_PORT_28015_TCP=tcp://host.docker.internal:28015 \
  -e "STF_ROOT_GROUP_NAME=STF" \
  -e "STF_ADMIN_NAME=username" \
  -e "STF_ADMIN_EMAIL=username@email.com" \
  openstf/stf:latest \
  stf migrate

3、stf-storage-temp

提供数据持久化的服务(本教程中主要提供给 stf-storage-plugin-imagestf-storage-plugin-apk)。

此单元的实例不能超过一个,因为同时使用了临时文件和内存映射。

docker run --rm \
  --name storage-temp \
  -v $HOME/demo/openstf/mnt/storage:/data \
  -p 3500:3000 \
  openstf/stf:latest \
  stf storage-temp --port 3000 \
    --save-dir /data

4、stf-storage-plugin-apk

该 APK 存储插件从主存储单元加载原始 Blob,并允许对 APK 文件执行其他操作,例如检索 AndroidManifest.xml

docker run --rm -it  \
  --name storage-plugin-apk \
  -p 3300:3000 \
  openstf/stf:latest \
  stf storage-plugin-apk --port 3000 \
    --storage-url http://host.docker.internal:3500/

5、stf-storage-plugin-image

该 image 存储插件从主存储单元加载原始 Blob,并允许使用参数调整图像大小。

docker run --rm -it \
  --name storage-plugin-image \
  -p 3400:3000 \
  openstf/stf:latest \
  stf storage-plugin-image --port 3000 \
    --storage-url http://host.docker.internal:3500/

6、stf-triproxy-app

该单元发送和接收来自 stf-app 单元的请求,并将其分发给 stf-processor 处理。

docker run --rm \
  --name triproxyapp \
  -p 7150:7150 \
  -p 7160:7160 \
  -p 7170:7170 \
  openstf/stf:latest \
  stf triproxy app \
    --bind-pub "tcp://*:7150" \
    --bind-dealer "tcp://*:7160" \
    --bind-pull "tcp://*:7170"

7、stf-triproxy-dev

该单元发送和接收来自 stf-provider 单元的请求,并将其分发给 stf-processor 处理。

docker run --rm \
  --name triproxydev \
  -p 7250:7250 \
  -p 7260:7260 \
  -p 7270:7270 \
  openstf/stf:latest \
  stf triproxy dev \
    --bind-pub "tcp://*:7250" \
    --bind-dealer "tcp://*:7260" \
    --bind-pull "tcp://*:7270"

8、stf-processor

该单元为 stf 服务主力,它充当设备与 stf 程序之间的桥梁,几乎所有通信都通过它进行。

docker run --rm \
  --name processor \
  -e RETHINKDB_PORT_28015_TCP=tcp://host.docker.internal:28015 \
  openstf/stf:latest \
  stf processor processor \
    --connect-app-dealer tcp://host.docker.internal:7160 \
    --connect-dev-dealer tcp://host.docker.internal:7260
  • RETHINKDB_PORT_28015_TCPrethinkdb 地址,由于实例部署在同一台机器上,所以使用了 host.docker.internal,若分布在不同机器,则需要改为对应机器ip地址。
  • -e RETHINKDB_PORT_28015_TCP=tcp://host.docker.internal:28015 可用 --link rethinkdb:rethinkdb 代替,效果相同。
  • connect-app-dealerstf-triproxy-app 地址,connect-dev-dealerstf-triproxy-dev

此处tcp地址不能写域名映射,如 tcp://triproxy-app.openstf.com,会导致服务直接访问到 tcp://triproxy-app.openstf.com:0

9、stf-websocket

该单元提供客户端js脚本和服务器端 ZeroMQ + Protobuf 之间的通信层。STF 中的几乎每个动作都通过此单元进行。

docker run --rm -it \
  --name websocket \
  -e RETHINKDB_PORT_28015_TCP=tcp://host.docker.internal:28015 \
  -e SECRET=YOUR_SESSION_SECRET_HERE \
  -p 3600:3000 \
  openstf/stf:latest \
  stf websocket --port 3000 \
    --storage-url http://host.docker.internal:3500/ \
    --connect-sub tcp://host.docker.internal:7150 \
    --connect-push tcp://host.docker.internal:7170

10、stf-api

该单元为 STF 提供了所有主要的 RESTful API。用户可以从 STF UI 生成其个人访问令牌,并且可以使用该令牌从任何界面访问这些 api。

docker run --rm \
  --name api \
  -e RETHINKDB_PORT_28015_TCP=tcp://host.docker.internal:28015 \
  -e "SECRET=YOUR_SESSION_SECRET_HERE" \
  -p 3700:3000 \
  openstf/stf:latest \
  stf api --port 3000 \
  --connect-sub tcp://host.docker.internal:7150 \
  --connect-push tcp://host.docker.internal:7170 \
  --connect-sub-dev tcp://host.docker.internal:7250 \
  --connect-push-dev tcp://host.docker.internal:7270

11、stf-reaper

该单元监听 device workers 的心跳,并将丢失的设备标记为不存在,直到继续收到心跳信息。目的是确保数据库中存在/不存在标志的完整性,以防 stf-provider 意外关闭或发生另一个意外失败。它在启动时从数据库加载当前状态,并在事件路由到它时继续修补其内部视图。

docker run --rm \
  --name reaper \
  -e RETHINKDB_PORT_28015_TCP=tcp://host.docker.internal:28015 \
  openstf/stf:latest \
  stf reaper dev \
    --connect-push tcp://host.docker.internal:7270 \
    --connect-sub tcp://host.docker.internal:7150 \
    --heartbeat-timeout 30000

12、stf-app

提供用户可访问的网站。

docker run --rm -it \
  --name stf-app \
  -e RETHINKDB_PORT_28015_TCP=tcp://host.docker.internal:28015 \
  -e SECRET=YOUR_SESSION_SECRET_HERE \
  -p 3000:3000 \
  openstf/stf:latest \
  stf app --port 3000 \
    --auth-url http://openstf.test.com/auth/mock/ \
    --websocket-url ws://host.docker.internal:3600/

由于 stf-app 会去 stf-auth 进行用户验证之后返回,所以 stf-app 必须和 stf-auth 处于相同 host 之下,此处实例使用 openstf.test.com,需要配置 nginx 代理。配置见后文。

13、stf-auth

提供用户验证。以下选择 Mock auth,只要用户提供用户名及邮箱即可登录。其他设置可见
stf-auth@.service

docker run --rm -it \
  --name auth-mock \
  -e RETHINKDB_PORT_28015_TCP=tcp://host.docker.internal:28015 \
  -e SECRET=YOUR_SESSION_SECRET_HERE \
  -p 3200:3200 \
  openstf/stf:latest \
  stf auth-mock --port 3200 \
    --app-url http://openstf.test.com/

14、nginx

以上服务启动之后,还不能正常访问,需要添加 nginx 代理连接各个服务。以下为 nginx 配置,是官网nginx配置的自定义删减版。

daemon off;
worker_processes 1;

events {
  worker_connections 1024;
}
#如果nginx与服务器不在一台上将127.0.0.1改为服务器IP
http {
  upstream stf_app {
    server 127.0.0.1:7100 max_fails=0;
  }

  upstream stf_auth {
    server 127.0.0.1:7101 max_fails=0;
  }

  upstream stf_storage_apk {
    server 127.0.0.1:7104 max_fails=0;
  }

  upstream stf_storage_image {
    server 127.0.0.1:7105 max_fails=0;
  }

  upstream stf_storage {
    server 127.0.0.1:7106 max_fails=0;
  }

  upstream stf_websocket {
    server 127.0.0.1:7102 max_fails=0;
  }

  upstream stf_api {
    server 127.0.0.1:7103 max_fails=0;
  }

  types {
    application/javascript  js;
    image/gif               gif;
    image/jpeg              jpg;
    text/css                css;
    text/html               html;
  }

  map $http_upgrade $connection_upgrade {
    default  upgrade;
    ''       close;
  }

  server {
    listen 80;
    
    # 配置的域名
    server_name openstf.test.com;
    keepalive_timeout 70; 


    location /auth/ {
      proxy_pass http://stf_auth/auth/;
    }

    location /api/ {
      proxy_pass http://stf_api/api/;
    }

    location /s/image/ {
      proxy_pass http://stf_storage_image;
    }

    location /s/apk/ {
      proxy_pass http://stf_storage_apk;
    }

    location /s/ {
      client_max_body_size 1024m;
      client_body_buffer_size 128k;
      proxy_pass http://stf_storage;
    }

    location /socket.io/ {
      proxy_pass http://stf_websocket;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection $connection_upgrade;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Real-IP $http_x_real_ip;
    }

    location / {
      proxy_pass http://stf_app;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Real-IP $http_x_real_ip;
    }
  }
}

在本地启动 nginx 容器:

docker run -it --name nginx \
  -p 80:80 \
  -v $HOME/demo/openstf/nginx.conf:/etc/nginx/nginx.conf:ro \
  nginx nginx

注:如果 nginx 服务没生效,需要进入容器内手动启动 nginx :/etc/init.d/nginx start

五、provider 服务部署(linux端)

在 linux 端,需要安装 adbd 用于连接设备,之后启动 stf-provider 服务。

stf-provider 单元主要用于连接 adb,为每个 adb 连接设备开一个 worker 进程。用于发送和接受 stf-processor 的指令。

需要注意的是,stf-provider 需要管理特定范围的端口,这些端口用于内部服务和屏幕截图 WebSocket。所以要求设置 --net host 的。这也是为什么 stf-provider 机器要使用 linux 的原因。

  • 启动 adbd:
docker run -d --name adbd \
  --privileged \
  -v /dev/bus/usb:/dev/bus/usb \
  --net host \
  sorccu/adb:latest
  • 启动 stf-provider
docker run -it --rm --name provider1 --net host openstf/stf \
stf provider --name provider1 \
--min-port=15000 \
--max-port=25000 \
--heartbeat-interval 20000 \
--allow-remote \
--no-cleanup \
--screen-jpeg-quality 80 \
--screen-reset false \
--connect-sub tcp://devside.stf.example.org:7250 \
--connect-push tcp://devside.stf.example.org:7270 \
--storage-url http://openstf.test.seewo.com

devside.stf.example.orgstf-triproxy-dev 地址,stf-provider 将自动与 stf-triproxy-dev 建立连接并交换数据。

至此,openstf 部署完成,通过 openstf.test.com 即可访问网站。
如果在本地部署,其他机器需要配置 hosts:部署机器ip openstf.test.com

参考

openstf DEPLOYMENT
dockerSTF github

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容

  • 最近由于工作需要,异地的研发同学需要远程连接手机进行bug确认、调试等,所以需要安装STF工具完成此项需求。 首先...
    summer雪人阅读 8,743评论 21 7
  • Docker从2013年发布第一个版本以来,已经火遍全球,技术迭代也比较频繁,其周边产品和技术也越来越丰富。Doc...
    归海听雪阅读 12,245评论 7 44
  • 可以分为三种情况: 1. 只有一个Master主机的情况,即只有一台装了STF和ADB的主机,连接了一些设备,通过...
    AllisonWang阅读 16,360评论 0 11
  • 安装STF 本地搭建能访问外网的ubuntu环境安装virturalbox创建ubuntu虚拟机,需要注意的是网络...
    你猜_19ca阅读 3,440评论 0 0
  • 很多人说现在年味越来越淡,再也没有儿时的味道,那时的人们淳朴善良,真性情。春节是欢聚,是期待,是美好。 年,真的变...
    兰子说阅读 560评论 5 13