使用 Docker 部署 openstf 平臺

一、背景

筆者所處業(yè)務(wù)需要搭建一個云測平臺,用于集中管理一批安卓系統(tǒng)板卡,經(jīng)過方案選擇,決定使用 openstf 進(jìn)行搭建,一來 openstf 開源,二來大部分服務(wù)采用nodejs進(jìn)行編寫,方便筆者進(jìn)行二次開發(fā)。

二、主要環(huán)境

本地環(huán)境為 mac,線上環(huán)境為 k8s(docker),連接板卡環(huán)境為deepin(linux)。

生產(chǎn)環(huán)境為 docker 和 linux,為了測試,會首先在 mac 上搭建,所以以下搭建過程會兼顧 mac 環(huán)境。

三、openstf 架構(gòu)

openstf 架構(gòu)圖.png

官方文檔上將一個個服務(wù)稱為單元。在本次部署中,將 stf-provider 單元部署在直接連接設(shè)備的 linux 機(jī)器上,其他主單元部署在云端服務(wù)器上。具體單元分配如下:

  • 云服務(wù)器:
    • 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)機(jī)器:
    • adbd
    • stf-provider

mac 無法使用 docker host 模式,但是 stf-provider 需要監(jiān)聽一定范圍內(nèi)的端口,所以無法在mac上使用 stf provider。
adbd 需要映射 /dev/bus/usb,mac 上沒有該輸入。所以這兩個服務(wù)要部署在本地 linux 機(jī)器(windows 自查)。

下面介紹每個單元的作用及提供 docker 啟動腳本。以下順序也是服務(wù)啟動順序。
以下實(shí)例中,除了 adbdstf-provider 單元,其他單元同一臺機(jī)器進(jìn)行部署。所以端口都設(shè)置成不沖突的端口,在容器需要訪問其他服務(wù) ip 時都使用了 host.docker.internal127.0.0.1,如果部署在不同機(jī)器上,需要將其替換成機(jī)器地址。

其中,host.docker.internal 在容器內(nèi)能映射成宿主機(jī) ip,主要是為了兼容不支持 host 的環(huán)境(如mac),在支持 host 的環(huán)境中(如 linux),也可直接換成 127.0.0.1。

四、主服務(wù)部署(云服務(wù)器)

1、rethinkdb

rethinkdb 為 openstf 服務(wù)采用的數(shù)據(jù)庫服務(wù)(據(jù)說當(dāng)時作者在開發(fā)時選擇它是因?yàn)樽髡呦雽W(xué)習(xí)當(dāng)時作為新技術(shù)的 rethinkdb )。有 RethinkDB 集群的話可以不啟動此服務(wù)。

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 

參數(shù)注釋如下:

  • -it 讓容器保持在前臺運(yùn)行,此參數(shù)在生產(chǎn)環(huán)境部署可去除;
  • --rm 在容器退出時自動清理容器內(nèi)部的文件系統(tǒng),方便調(diào)試,此參數(shù)在生產(chǎn)環(huán)境部署時可去除;
  • host.docker.internal 在容器內(nèi)會映射到宿主機(jī) ip,如果 docker 使用 host 模式可以替換成 127.0.0.1;
  • -p 為宿主機(jī)端口到容器內(nèi)端口的映射,以上暴露的三個端口,都是連接 rethinkdb 需要用到的。這么處理是為了兼容不支持 docker host 模式的環(huán)境(如mac),linux 機(jī)器可以直接使用 --net=host 共享宿主機(jī)網(wǎng)絡(luò)。之后沒有特殊說明,都采用相同的處理。

2、* stf-migrate

此單元初始化數(shù)據(jù)庫表,創(chuàng)建 stf 需要的各種表格。只需要運(yùn)行一次。

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

提供數(shù)據(jù)持久化的服務(wù)(本教程中主要提供給 stf-storage-plugin-imagestf-storage-plugin-apk)。

此單元的實(shí)例不能超過一個,因?yàn)橥瑫r使用了臨時文件和內(nèi)存映射。

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 文件執(zhí)行其他操作,例如檢索 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,并允許使用參數(shù)調(diào)整圖像大小。

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

該單元發(fā)送和接收來自 stf-app 單元的請求,并將其分發(fā)給 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

該單元發(fā)送和接收來自 stf-provider 單元的請求,并將其分發(fā)給 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 服務(wù)主力,它充當(dāng)設(shè)備與 stf 程序之間的橋梁,幾乎所有通信都通過它進(jìn)行。

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 地址,由于實(shí)例部署在同一臺機(jī)器上,所以使用了 host.docker.internal,若分布在不同機(jī)器,則需要改為對應(yīng)機(jī)器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,會導(dǎo)致服務(wù)直接訪問到 tcp://triproxy-app.openstf.com:0

9、stf-websocket

該單元提供客戶端js腳本和服務(wù)器端 ZeroMQ + Protobuf 之間的通信層。STF 中的幾乎每個動作都通過此單元進(jìn)行。

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

該單元監(jiān)聽 device workers 的心跳,并將丟失的設(shè)備標(biāo)記為不存在,直到繼續(xù)收到心跳信息。目的是確保數(shù)據(jù)庫中存在/不存在標(biāo)志的完整性,以防 stf-provider 意外關(guān)閉或發(fā)生另一個意外失敗。它在啟動時從數(shù)據(jù)庫加載當(dāng)前狀態(tài),并在事件路由到它時繼續(xù)修補(bǔ)其內(nèi)部視圖。

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

提供用戶可訪問的網(wǎng)站。

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 進(jìn)行用戶驗(yàn)證之后返回,所以 stf-app 必須和 stf-auth 處于相同 host 之下,此處實(shí)例使用 openstf.test.com,需要配置 nginx 代理。配置見后文。

13、stf-auth

提供用戶驗(yàn)證。以下選擇 Mock auth,只要用戶提供用戶名及郵箱即可登錄。其他設(shè)置可見
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

以上服務(wù)啟動之后,還不能正常訪問,需要添加 nginx 代理連接各個服務(wù)。以下為 nginx 配置,是官網(wǎng)nginx配置的自定義刪減版。

daemon off;
worker_processes 1;

events {
  worker_connections 1024;
}
#如果nginx與服務(wù)器不在一臺上將127.0.0.1改為服務(wù)器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 服務(wù)沒生效,需要進(jìn)入容器內(nèi)手動啟動 nginx :/etc/init.d/nginx start

五、provider 服務(wù)部署(linux端)

在 linux 端,需要安裝 adbd 用于連接設(shè)備,之后啟動 stf-provider 服務(wù)。

stf-provider 單元主要用于連接 adb,為每個 adb 連接設(shè)備開一個 worker 進(jìn)程。用于發(fā)送和接受 stf-processor 的指令。

需要注意的是,stf-provider 需要管理特定范圍的端口,這些端口用于內(nèi)部服務(wù)和屏幕截圖 WebSocket。所以要求設(shè)置 --net host 的。這也是為什么 stf-provider 機(jī)器要使用 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 建立連接并交換數(shù)據(jù)。

至此,openstf 部署完成,通過 openstf.test.com 即可訪問網(wǎng)站。
如果在本地部署,其他機(jī)器需要配置 hosts:部署機(jī)器ip openstf.test.com

參考

openstf DEPLOYMENT
dockerSTF github

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 最近由于工作需要,異地的研發(fā)同學(xué)需要遠(yuǎn)程連接手機(jī)進(jìn)行bug確認(rèn)、調(diào)試等,所以需要安裝STF工具完成此項(xiàng)需求。 首先...
    summer雪人閱讀 9,020評論 21 7
  • 可以分為三種情況: 1. 只有一個Master主機(jī)的情況,即只有一臺裝了STF和ADB的主機(jī),連接了一些設(shè)備,通過...
    AllisonWang閱讀 16,712評論 0 11
  • 安裝STF 本地搭建能訪問外網(wǎng)的ubuntu環(huán)境安裝virturalbox創(chuàng)建ubuntu虛擬機(jī),需要注意的是網(wǎng)絡(luò)...
    你猜_19ca閱讀 3,555評論 0 0
  • 很多人說現(xiàn)在年味越來越淡,再也沒有兒時的味道,那時的人們淳樸善良,真性情。春節(jié)是歡聚,是期待,是美好。 年,真的變...
    蘭子說閱讀 638評論 5 13
  • #幸福是需要修出來的~每天進(jìn)步1%~幸福實(shí)修11班~08賈春芬-杭州#20170911(14/30) 【幸福三朵玫...
    chfenj閱讀 181評論 2 2

友情鏈接更多精彩內(nèi)容