前言
之前的文章(香橙派5plus上跑云手機(jī)方案一 redroid(帶硬件加速))在Ubuntu的docker里運(yùn)行安卓,這里說(shuō)下怎么在安卓手機(jī)下運(yùn)行docker贰逾,測(cè)試也可以跑Ubuntu。
想在手機(jī)上運(yùn)行docker想的不是一天兩天了,其實(shí)很久之前就有這個(gè)想法了置鼻,只是奈何安卓?jī)?nèi)核一直編譯不通過(guò)∩┍現(xiàn)在覺(jué)得過(guò)了那么久顶伞,技術(shù)應(yīng)該有點(diǎn)提升了,覺(jué)得我又行了惠险,所以又來(lái)試試。
測(cè)試用的手機(jī)是從閑魚(yú)淘的一個(gè)一加七Pro(12+256G)抒线,使用的系統(tǒng)是Lineageos19.1班巩,后面放出我運(yùn)行的刷機(jī)包和編譯的boot文件,你直接刷進(jìn)手機(jī)應(yīng)該就能運(yùn)行了嘶炭。
檢查內(nèi)核配置
首先檢查下當(dāng)前的安卓?jī)?nèi)核確實(shí)哪些運(yùn)行docker需要的內(nèi)核配置
先下載https://raw.githubusercontent.com/moby/moby/master/contrib/check-config.sh
推送到手機(jī)的/data/local/tmp
下: adb push check-config.sh /data/local/tmp/check-config.sh
然后使用adb root
切換到root(需要再開(kāi)發(fā)者模式里開(kāi)啟允許root調(diào)試)抱慌,接著運(yùn)行sh /data/local/tmp/check-config.sh
查看。缺少的其實(shí)挺多
編譯內(nèi)核
要想在手機(jī)上原生運(yùn)行docker眨猎,修改內(nèi)核參數(shù)重新編譯內(nèi)核這個(gè)是繞不過(guò)去的遥缕,所以先開(kāi)始編譯內(nèi)核。lineage的內(nèi)核編譯比較簡(jiǎn)單宵呛,如果下載系統(tǒng)源碼來(lái)編譯的話基本沒(méi)什么坑单匣,這里就不多說(shuō)了。有興趣的可以看之前的文章:
運(yùn)行docker也需要root權(quán)限,所以會(huì)將kernelsu一起編譯進(jìn)去户秤,這里也不贅述了码秉。
修改內(nèi)核參數(shù)
先說(shuō)一下修改內(nèi)核參數(shù)的流程:
cd kernel/oneplus/sm8150
進(jìn)到對(duì)應(yīng)的內(nèi)核源碼根目錄
export ARCH=arm64
指定內(nèi)核編譯的平臺(tái),不指定默認(rèn)是x86
export SUBARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
make vendor/sm8150-perf_defconfig
通過(guò)這個(gè)文件生成.config
make menuconfig
啟動(dòng)內(nèi)核編輯菜單
make savedefconfig
保存.config
文件為defconfig
鸡号,至于這個(gè)和手動(dòng)修改有什么區(qū)別就沒(méi)細(xì)究了转砖,反正都推薦用這個(gè)
mv defconfig arch/arm64/configs/vendor/sm8150-perf_defconfig
覆蓋原先的內(nèi)核配置文件,建議先備份一下原先的文件
rm .config
make可能有一個(gè)錯(cuò)誤提示/bin/sh: 1: aarch64-linux-gnu-gcc: not found
鲸伴,通過(guò)搜索看到這個(gè)問(wèn)答[1]說(shuō)應(yīng)該是缺少包:sudo apt-get install gcc-aarch64-linux-gnu
配置
這里為了方便直接抄別人的內(nèi)核配置放到.config
文件里: https://yzddmr6.com/posts/android-run-docker/
CONFIG_NAMESPACES=y
CONFIG_NET_NS=y
CONFIG_PID_NS=y
CONFIG_IPC_NS=y
CONFIG_UTS_NS=y
CONFIG_CGROUPS=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_SCHED=y
CONFIG_CPUSETS=y
CONFIG_MEMCG=y
CONFIG_KEYS=y
CONFIG_VETH=y
CONFIG_BRIDGE=y
CONFIG_BRIDGE_NETFILTER=y
CONFIG_IP_NF_FILTER=y
CONFIG_IP_NF_TARGET_MASQUERADE=y
CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=y
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
CONFIG_NETFILTER_XT_MATCH_IPVS=y
CONFIG_NETFILTER_XT_MARK=y
CONFIG_IP_NF_NAT=y
CONFIG_NF_NAT=y
CONFIG_POSIX_MQUEUE=y
CONFIG_NF_NAT_IPV4=y
CONFIG_NF_NAT_NEEDED=y
CONFIG_CGROUP_BPF=y
CONFIG_USER_NS=y
CONFIG_SECCOMP=y
CONFIG_SECCOMP_FILTER=y
CONFIG_CGROUP_PIDS=y
CONFIG_MEMCG_SWAP=y
CONFIG_MEMCG_SWAP_ENABLED=y
CONFIG_IOSCHED_CFQ=y
CONFIG_CFQ_GROUP_IOSCHED=y
CONFIG_BLK_CGROUP=y
CONFIG_BLK_DEV_THROTTLING=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_NET_CLS_CGROUP=y
CONFIG_CGROUP_NET_PRIO=y
CONFIG_CFS_BANDWIDTH=y
CONFIG_FAIR_GROUP_SCHED=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_IP_NF_TARGET_REDIRECT=y
CONFIG_IP_VS=y
CONFIG_IP_VS_NFCT=y
CONFIG_IP_VS_PROTO_TCP=y
CONFIG_IP_VS_PROTO_UDP=y
CONFIG_IP_VS_RR=y
CONFIG_SECURITY_SELINUX=y
CONFIG_SECURITY_APPARMOR=y
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
CONFIG_VXLAN=y
CONFIG_BRIDGE_VLAN_FILTERING=y
CONFIG_CRYPTO=y
CONFIG_CRYPTO_AEAD=y
CONFIG_CRYPTO_GCM=y
CONFIG_CRYPTO_SEQIV=y
CONFIG_CRYPTO_GHASH=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=y
CONFIG_XFRM_ALGO=y
CONFIG_INET_ESP=y
CONFIG_INET_XFRM_MODE_TRANSPORT=y
CONFIG_IPVLAN=y
CONFIG_MACVLAN=y
CONFIG_DUMMY=y
CONFIG_NF_NAT_FTP=y
CONFIG_NF_CONNTRACK_FTP=y
CONFIG_NF_NAT_TFTP=y
CONFIG_NF_CONNTRACK_TFTP=y
CONFIG_AUFS_FS=y
CONFIG_BTRFS_FS=y
CONFIG_BTRFS_FS_POSIX_ACL=y
CONFIG_BLK_DEV_DM=y
CONFIG_DM_THIN_PROVISIONING=y
CONFIG_OVERLAY_FS=y
然后使用make menuconfig
在界面上一個(gè)一個(gè)查看配置的開(kāi)啟情況府蔗,發(fā)現(xiàn)CONFIG_BRIDGE_VLAN_FILTERING
沒(méi)有開(kāi)啟,查看了下是因?yàn)橐蕾図?xiàng)VLAN_8021Q
沒(méi)有開(kāi)啟
而CONFIG_IPVLAN
則是依賴項(xiàng)NET_L3_MASTER_DEV
沒(méi)開(kāi)啟
所以在配置文件里再加上這兩個(gè)配置汞窗, 再運(yùn)行make menuconfig
保存
CONFIG_VLAN_8021Q=y
CONFIG_BRIDGE_VLAN_FILTERING=y
CONFIG_NET_L3_MASTER_DEV=y
CONFIG_IPVLAN=y
CONFIG_CGROUP_HUGETLB
依賴于HUGETLB_PAGE
姓赤,但是將這個(gè)配置直接加到.config
不生效,界面上也不顯示具體的開(kāi)啟路徑
問(wèn)了下gpt說(shuō)是在File systems
-> Pseudo filesystems
-> HugeTLB file system support
仲吏,在界面上啟用不铆,再在配置文件里加上CONFIG_CGROUP_HUGETLB
,再打開(kāi)界面看到就是啟用狀態(tài)裹唆。
準(zhǔn)備工作都做完了誓斥,然后按照上面的命令保存為defconfig在覆蓋原先的內(nèi)核配置就可以開(kāi)始編譯了
開(kāi)始編譯
這里需要到lineage源碼根目錄,而不是在內(nèi)核源碼根目錄
source build/envsetup.sh
breakfast guacamole
make bootimage
接著就會(huì)出現(xiàn)一個(gè)折磨我兩周的錯(cuò)誤:
aarch64-linux-gnu-ld is not allowed to be used. See https://android.googlesource.com/platform/build/+/master/Changes.md#PATH_Tools for more information.
雖然他給了一個(gè)鏈接讓我們從里面看更多信息许帐,鏈接里也給了解決方法:
但是試了也是沒(méi)用劳坑,
用谷歌搜索也搜不出什么有效的方法,這兩天突然想能不能修改它提到的build/soong/ui/build/paths/config.go
文件成畦,問(wèn)了下gpt泡垃,它說(shuō)在config.go里的Configuration里加一行"aarch64-linux-gnu-ld": Allowed,
就可以
試了下確實(shí)是可以,有時(shí)候gpt就很好用羡鸥。我開(kāi)始還以為是將ld
改成Allowed蔑穴,因?yàn)榍懊婷黠@是前綴。然后等待幾分鐘就編譯完成了
將生成的boot.img在fastboot模式下用fastboot flash boot boot.img
輸入手機(jī)后啟動(dòng)手機(jī)惧浴。
檢測(cè)結(jié)果
編譯完的內(nèi)核還有三個(gè)地方是紅色(missing)
第一處經(jīng)測(cè)試不是內(nèi)核參數(shù)的問(wèn)題存和,需要運(yùn)行一次這行命令:sudo mount -t tmpfs -o uid=0,gid=0,mode=0755 cgroup /sys/fs/cgroup
,下面兩個(gè)無(wú)法解決衷旅,因?yàn)槭欠潜仨氻?xiàng)捐腿,先不管它了。
補(bǔ)丁
有的提到還需要對(duì)net/netfilter/xt_qtaguid.c
做補(bǔ)丁柿顶,但我這個(gè)內(nèi)核代碼里沒(méi)有這個(gè)文件就跳過(guò)了茄袖。
補(bǔ)充
為了避免內(nèi)核參數(shù)有遺漏,我們把https://github.com/lateautumn233/android_kernel_docker
里的提到的內(nèi)核參數(shù)也加到.config
里嘁锯,再重新編譯一次宪祥。
運(yùn)行docker
目前看到的運(yùn)行docker有兩種方式:
這里我選擇第一種聂薪,第一種更成熟一點(diǎn),很多東西都已經(jīng)幫我們做好了蝗羊。
termux
# The main termux repository, with cloudflare cache
deb https://packages-cf.termux.dev/apt/termux-main/ stable main
# The main termux repository, without cloudflare cache
# deb https://packages.termux.dev/apt/termux-main/ stable main
證書(shū)錯(cuò)誤
使用apt安裝包時(shí)出現(xiàn)下面的證書(shū)無(wú)效藏澳。
Certificate verification failed: The certificate is NOT trusted. The certificate chain uses not yet valid certificate.
發(fā)現(xiàn)是手機(jī)的系統(tǒng)時(shí)間不對(duì),沒(méi)有在證書(shū)的有效時(shí)間內(nèi)耀找,修改下系統(tǒng)時(shí)間就好了翔悠。這個(gè)我是安裝了一個(gè)via
瀏覽器去訪問(wèn)百度,也跳出了證書(shū)不安全的提示野芒,然后點(diǎn)擊證書(shū)進(jìn)去就看到證書(shū)有效時(shí)間是2023-12到2024-12的范圍蓄愁,而手機(jī)的時(shí)間是2022,就猜測(cè)是時(shí)間不對(duì)狞悲。
換apt源
https://mirrors.tuna.tsinghua.edu.cn/help/termux/
將下面的內(nèi)容先保存為a.sh
撮抓,然后用adb push a.sh /data/local/tmp/a.sh
sed -i 's@^\(deb.*stable main\)$@#\1\ndeb https://mirrors.tuna.tsinghua.edu.cn/termux/apt/termux-main stable main@' $PREFIX/etc/apt/sources.list
apt update && apt upgrade
接著在termux終端輸入sh /data/local/tmp/a.sh
就好了。
遠(yuǎn)程
apt install openssh
sshd
啟動(dòng)ssh服務(wù)
whoami
查看當(dāng)前用戶
passwd
設(shè)置密碼
當(dāng)然也可以通過(guò)公私鑰的方式配置免密登錄效诅,這里我先用密碼了胀滚。安裝openssh的時(shí)候看提示應(yīng)該就已經(jīng)生成了公鑰趟济,目錄是$PREFIX/etc/shh
乱投,然后就和linux免密登錄一樣了。
$PREFIX
這個(gè)變量是termux定義的顷编,它類似于linux的根目錄戚炫,比如linux的/etc
目錄在termux里就是指$PREFIX/etc
,這在后面的docker換源時(shí)會(huì)用到媳纬。
sshd啟動(dòng)的默認(rèn)端口是8022双肤,我的用戶名是u0_a140
,在cmd下使用ssh -p 8022 u0_a140@192.168.31.248
就能連接了钮惠,也可以使用xshell這些工具連接茅糜。
切換pkg源
輸入termux-change-repo
,選擇第二個(gè)按空格回車素挽,會(huì)藍(lán)屏一會(huì)(應(yīng)該還是網(wǎng)絡(luò)原因蔑赘,很慢),等待出現(xiàn)源選擇,然后空格勾選阿里的源
先掛載cgroup
需要安裝pkg install sudo
预明,并且用kernelsu給termux root權(quán)限缩赛,不清楚和下面的root-repo包有什么區(qū)別
sudo mount -t tmpfs -o uid=0,gid=0,mode=0755 cgroup /sys/fs/cgroup
這個(gè)每次重啟都需要執(zhí)行一遍
運(yùn)行docker
pkg install root-repo && pkg install docker
安裝root和docker
這時(shí)候需要先配置一下docker源,不然拉取不了鏡像
pkg install vim
mkdir -p /data/data/com.termux/files/usr/etc/docker
vim /data/data/com.termux/files/usr/etc/docker/daemon.json
將下面的內(nèi)容加到這個(gè)文件里撰糠,記得前面要加個(gè)英文逗號(hào)
"registry-mirrors": [
"https://hub.uuuadc.top",
"https://docker.anyhub.us.kg",
"https://dockerhub.jobcher.com",
"https://dockerhub.icu",
"https://docker.ckyl.me",
"https://docker.awsl9527.cn"
]
sudo dockerd --iptables=false
運(yùn)行docker服務(wù)
sudo docker run hello-world
這時(shí)候啟動(dòng)docker容器會(huì)報(bào)錯(cuò)酥馍,
docker: Error response from daemon: failed to create task for container: failed to start shim: start failed: io.containerd.runc.v2: create new shim socket: listen unix /data/data/com.termux/files/usr/var/run/containerd/s/fca432b16f1e32bdfce67923b7e94f3ab7f741783e5032a938bd6869d8b6d3af: bind: invalid argument: exit status 1: unknown.
這里并不清楚什么原因,但偶然記得之前在酷安上看到一個(gè)東西阅酪,過(guò)去翻了翻[2]旨袒,說(shuō)是要降級(jí)containerd
包的版本汁针。先查看下containerd
包的版本:
然后下載帖子里這個(gè)包,用adb傳到手機(jī)上(xftp也可以)峦失,然后使用dpkg -i containerd_1.6.21-1_aarch64.deb
安裝
接著查看版本apt show containerd -a
就看到已經(jīng)安裝上了
然后重新啟動(dòng)sudo dockerd --iptables=false
扇丛,在跑hello-world
容器就正常了
試了下跑python也可以,那說(shuō)明可以在手機(jī)跑爬蟲(chóng)了:
Ubuntu鏡像也是可以的:
刷機(jī)包和boot
https://github.com/kanadeblisst00/docker-in-guacamole
引用鏈接
- [1]
https://stackoverflow.com/questions/28565640/build-kernel-with-aarch64-linux-gnu-gcc
- [2]
https://www.coolapk.com/feed/51581431?shareKey=MmRlNTgxOTVmNjliNjY5M2QwMGU~&shareUid=4285440&shareFrom=com.coolapk.market_14.2.3
參考鏈接
https://gist.github.com/FreddieOliveira/efe850df7ff3951cb62d74bd770dce27
https://ivonblog.com/posts/run-docker-natively-on-android/
https://yzddmr6.com/posts/android-run-docker/