安卓应用apk部署到Docker中,并自动检测容器状态,根据容器的状态(unhealthy、Created、Exited、不在docker ps -a列表等)自动重启容器,并自动完成配置文件的设定,自动安装(安装这一步,在commit时,会自动集成到镜像,创建容器时,自动完成)、自动运行等。
一、基础信息
Docker服务器IP地址:10.11.*.*
登录账号:account
登录密码:*******
apk安装包和相关的数据配置打包成:release.zip
二、自定义镜像
1、拷贝文件到Docker服务器
scp ***/release.zip account@ip:/home/account/
2、登录命令
ssh account@ip
sudo su -
3、拉取镜像创建容器ad1
docker run --privileged -d -p 6001:6080 -e DEVICE="Nexus 7" --name ad1 budtmo/docker-android-x86-7.0
4、拷贝文件到容器
cp /home/account/release.zip ad1:/root/
5、解压release.zip
unzip release.zip
6、安装apk
adb install -r release/networknode1.apk
adb install -r release/networknode2.apk
adb install -r release/networknode3.apk
adb install -r release/networknode4.apk
adb install -r release/networknode5.apk
7、拷贝配置文件到指定目录(如有必要)
cp release/config.ini /sdcard/myconfig/config.ini
8、访问设备,确认权限
在浏览器中访问:ip:6001
找到刚才安装的5个apk,分别为这些apk设置访问权限(打开app,按照弹出框提示,确认授权即可)
9、提交镜像
docker commit ad1 'xhs/7.0'
10、容器量产
docker run --privileged -d -p 6001:6080 -e DEVICE="Nexus 7" --name ad1 xhs/7.0
docker run --privileged -d -p 6002:6080 -e DEVICE="Nexus 7" --name ad2 xhs/7.0
docker run --privileged -d -p 6003:6080 -e DEVICE="Nexus 7" --name ad3 xhs/7.0
docker run --privileged -d -p 6004:6080 -e DEVICE="Nexus 7" --name ad4 xhs/7.0
docker run --privileged -d -p 6005:6080 -e DEVICE="Nexus 7" --name ad5 xhs/7.0
三、自动化监测
1、目标
1、监测坏死、不健康的容器,如果有必要则kill掉非正常状态的容器,并重新自动创建新的容器,并为其自动设置好app需要的数据文件;
2、利用代码自动运行app,并对模拟器中的配置文件进行纠错。
2、创建自动化脚本
将下面代码保存到文件,并将其放到指定目录(按自己需求,如:/home/account/docker/autosh/dockermonitor)
#!/bin/sh
now=`date +%Y%m%d.txt`
logPath="/home/account/docker/logs/log"$now
echo $logPath >> $logPath
containerStartIndx=1 #容器起始编号:ad1
containerEndIndex=5 #容器结束编号: ad5
log() {
echo $1 >> $logPath
}
removeContainer() {
for((i=$1;i<=$2;i++)); do
adn=ad${i}
docker kill $adn
docker rm $adn
done
}
setEnv() {
info=`docker exec -it $adx adb shell "ls /sdcard/myconfig/ | tr '\n' ' '"`
if [[ $info =~ "config$1.ini" ]]; then
log "$adx /sdcard/myconfig/路径下包含config$1.ini"
for((idx=1;idx<=5;idx++)); do
log "docker exec -it $adx adb shell am start -n com.im.datacollect.networknode$idx/com.im.datacollect.networknode$idx.MainActivity"
docker exec -it $adx adb shell am start -n com.im.datacollect.networknode$idx/com.im.datacollect.networknode$idx.MainActivity
done
elif [[ $info =~ ".ini" ]]; then
log "$adx /sdcard/myconfig/路径下包含.ini"
strconf=$(docker exec -it $adx adb shell "ls /sdcard/myconfig/ | tr '\n' ' '")
log $strconf
array=(`echo $strconf` )
for((m=0;m<${#array[@]};m++)) do
config=${array[$m]};
configval="config$1.ini"
if [ $config != $configval ]; then
log "docker exec -it $adx adb shell mv /sdcard/myconfig/$config /sdcard/myconfig/config$1.ini"
docker exec -it $adx adb shell mv /sdcard/myconfig/$config /sdcard/myconfig/config$1.ini
fi
done
for((idx=1;idx<=5;idx++)); do
log "docker exec -it $adx adb shell am start -n com.im.datacollect.networknode$idx/com.im.datacollect.networknode$idx.MainActivity"
docker exec -it $adx adb shell am start -n com.im.datacollect.networknode$idx/com.im.datacollect.networknode$idx.MainActivity
done
else
log "异常"
fi
}
str=$(docker ps -a | sed 's/[ ]\{1,10\}/||/g')
list=(${str/\n/ })
log "list长度:"${#list[@]}
for((j=$containerStartIndx;j<=$containerEndIndex;j++)); do
exist="0"
adx=ad$j
log "adx:"$adx
for(( i=1;i<${#list[@]};i++)) do
item=${list[$i]};
ad=$(echo $item | awk -F\| '{print $NF}')
log "ad:"$ad
if [[ $ad = $adx ]]; then
exist="1"
log "item:"$item;
log "$adx已存在:$ad"
if [[ $item =~ "unhealthy" ]]||[[ $item =~ "Created" ]]; then
log "$adx需要重启,重启中……: docker restart $adx"
rs=`docker restart $adx`
sleep 2m
elif [[ $item =~ "Exited" ]]; then
# 无法重启的报错:Error response from daemon: Cannot restart container
# if [[ $rs =~ "Error response from daemon: Cannot restart container" ]]; then
log "重启失败,即将删除容器,并重建:docker rm $adx"
docker rm $adx
exist="0"
else
log "正常运行中, 或starting 或 healthy"
fi
log "exist1:"$exist
break
fi
done
log "exist2:"$exist
if [ $exist = "0" ]; then
log "$adx没有启动,启动中……"
if (($j<10));then
log "docker run --privileged -d -p 600$j:6080 -e DEVICE='Nexus 5' --name $adx xhs/7.0"
docker run --privileged -d -p 600$j:6080 -e DEVICE='Nexus 5' --name $adx xhs/7.0
else
log "docker run --privileged -d -p 60$j:6080 -e DEVICE='Nexus 5' --name $adx xhs/7.0"
docker run --privileged -d -p 60$j:6080 -e DEVICE='Nexus 5' --name $adx xhs/7.0
fi
sleep 2m
log "重命名完成!"
fi
setEnv $j
done
3、将刚才的自动化脚本放到定时任务队列中,开启循环执行
- 进入循环任何队列(初次进入会出现编辑器选择,按照个人习惯,本人选择的是vi)
crontab -e
- 在顶部加入刚才的自动化脚本,如下
GNU nano 5.2 /tmp/crontab.fGOhnz/crontab
# 每两小时执行一次,文件路径替换成自己的真实路径
0 */2 * * * /bin/sh /home/account/docker/autosh/dockermonitor
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').
#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
- 重启cron,让修改的队列立即生效
sudo service cron restart
- 相关命令:
sudo service cron start
sudo service cron stop
sudo service cron reload
我的Docker服务器是ubantu,对应的是cron,有的系统则是crond,本人没有细究,如果上述命令不行,可以试试:
sudo service crond start # 开启服务
sudo service crond stop # 关闭服务
sudo service crond restart # 重启服务
sudo service crond reload # 重新载入配置
crond报错:
Failed to restart crond.service: Unit crond.service not found.
则换成:sudo service cron restart