在安卓手机上原生运行docker

前言

之前的文章(香橙派5plus上跑云手机方案一 redroid(带硬件加速))在Ubuntu的docker里运行安卓,这里说下怎么在安卓手机下运行docker,测试也可以跑Ubuntu。

想在手机上运行docker想的不是一天两天了,其实很久之前就有这个想法了,只是奈何安卓内核一直编译不通过。现在觉得过了那么久,技术应该有点提升了,觉得我又行了,所以又来试试。

测试用的手机是从闲鱼淘的一个一加七Pro(12+256G),使用的系统是Lineageos19.1,后面放出我运行的刷机包和编译的boot文件,你直接刷进手机应该就能运行了。

检查内核配置

首先检查下当前的安卓内核确实哪些运行docker需要的内核配置

先下载https://raw.githubusercontent.com/moby/moby/master/contrib/check-config.sh推送到手机的/data/local/tmp下: adb push check-config.sh /data/local/tmp/check-config.sh

然后使用adb root切换到root(需要再开发者模式里开启允许root调试),接着运行sh /data/local/tmp/check-config.sh查看。缺少的其实挺多

编译内核

要想在手机上原生运行docker,修改内核参数重新编译内核这个是绕不过去的,所以先开始编译内核。lineage的内核编译比较简单,如果下载系统源码来编译的话基本没什么坑,这里就不多说了。有兴趣的可以看之前的文章:

  • 为一加七Pro(LineageOs17.1 4.14内核版本)编译KernelSu
  • wsl2-ubuntu20编译Lineage17(Android10)

运行docker也需要root权限,所以会将kernelsu一起编译进去,这里也不赘述了。

修改内核参数

先说一下修改内核参数的流程:

cd kernel/oneplus/sm8150 进到对应的内核源码根目录

export ARCH=arm64 指定内核编译的平台,不指定默认是x86

export SUBARCH=arm64

export CROSS_COMPILE=aarch64-linux-gnu-

make vendor/sm8150-perf_defconfig 通过这个文件生成.config

make menuconfig 启动内核编辑菜单

make savedefconfig 保存.config文件为defconfig,至于这个和手动修改有什么区别就没细究了,反正都推荐用这个

mv defconfig arch/arm64/configs/vendor/sm8150-perf_defconfig 覆盖原先的内核配置文件,建议先备份一下原先的文件

rm .config

make可能有一个错误提示/bin/sh: 1: aarch64-linux-gnu-gcc: not found,通过搜索看到这个问答[1]说应该是缺少包:sudo apt-get install gcc-aarch64-linux-gnu

配置

这里为了方便直接抄别人的内核配置放到.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在界面上一个一个查看配置的开启情况,发现CONFIG_BRIDGE_VLAN_FILTERING没有开启,查看了下是因为依赖项VLAN_8021Q没有开启

CONFIG_IPVLAN则是依赖项NET_L3_MASTER_DEV没开启

所以在配置文件里再加上这两个配置, 再运行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,但是将这个配置直接加到.config不生效,界面上也不显示具体的开启路径

问了下gpt说是在File systems -> Pseudo filesystems -> HugeTLB file system support,在界面上启用,再在配置文件里加上CONFIG_CGROUP_HUGETLB,再打开界面看到就是启用状态。

准备工作都做完了,然后按照上面的命令保存为defconfig在覆盖原先的内核配置就可以开始编译了

开始编译

这里需要到lineage源码根目录,而不是在内核源码根目录

source build/envsetup.sh breakfast guacamole make bootimage

接着就会出现一个折磨我两周的错误:

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.

虽然他给了一个链接让我们从里面看更多信息,链接里也给了解决方法:

但是试了也是没用,

用谷歌搜索也搜不出什么有效的方法,这两天突然想能不能修改它提到的build/soong/ui/build/paths/config.go文件,问了下gpt,它说在config.go里的Configuration里加一行"aarch64-linux-gnu-ld": Allowed,就可以

试了下确实是可以,有时候gpt就很好用。我开始还以为是将ld改成Allowed,因为前面明显是前缀。然后等待几分钟就编译完成了

将生成的boot.img在fastboot模式下用fastboot flash boot boot.img输入手机后启动手机。

检测结果

编译完的内核还有三个地方是红色(missing)

第一处经测试不是内核参数的问题,需要运行一次这行命令:sudo mount -t tmpfs -o uid=0,gid=0,mode=0755 cgroup /sys/fs/cgroup,下面两个无法解决,因为是非必须项,先不管它了。

补丁

有的提到还需要对net/netfilter/xt_qtaguid.c做补丁,但我这个内核代码里没有这个文件就跳过了。

补充

为了避免内核参数有遗漏,我们把https://github.com/lateautumn233/android_kernel_docker里的提到的内核参数也加到.config里,再重新编译一次。

运行docker

目前看到的运行docker有两种方式:

  • termux
  • 直接运行二进制文件

这里我选择第一种,第一种更成熟一点,很多东西都已经帮我们做好了。

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
证书错误

使用apt安装包时出现下面的证书无效。

Certificate verification failed: The certificate is NOT trusted. The certificate chain uses not yet valid certificate.

发现是手机的系统时间不对,没有在证书的有效时间内,修改下系统时间就好了。这个我是安装了一个via浏览器去访问百度,也跳出了证书不安全的提示,然后点击证书进去就看到证书有效时间是2023-12到2024-12的范围,而手机的时间是2022,就猜测是时间不对。

换apt源

https://mirrors.tuna.tsinghua.edu.cn/help/termux/

将下面的内容先保存为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就好了。

远程

apt install openssh

sshd 启动ssh服务

whoami 查看当前用户

passwd 设置密码

当然也可以通过公私钥的方式配置免密登录,这里我先用密码了。安装openssh的时候看提示应该就已经生成了公钥,目录是$PREFIX/etc/shh,然后就和linux免密登录一样了。

$PREFIX这个变量是termux定义的,它类似于linux的根目录,比如linux的/etc目录在termux里就是指$PREFIX/etc,这在后面的docker换源时会用到。

sshd启动的默认端口是8022,我的用户名是u0_a140,在cmd下使用ssh -p 8022 u0_a140@192.168.31.248就能连接了,也可以使用xshell这些工具连接。

切换pkg源

输入termux-change-repo,选择第二个按空格回车,会蓝屏一会(应该还是网络原因,很慢),等待出现源选择,然后空格勾选阿里的源

先挂载cgroup

需要安装pkg install sudo,并且用kernelsu给termux root权限,不清楚和下面的root-repo包有什么区别

sudo mount -t tmpfs -o uid=0,gid=0,mode=0755 cgroup /sys/fs/cgroup

这个每次重启都需要执行一遍

运行docker

pkg install root-repo && pkg install docker 安装root和docker

这时候需要先配置一下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

将下面的内容加到这个文件里,记得前面要加个英文逗号

"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 运行docker服务

sudo docker run hello-world

这时候启动docker容器会报错,

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.

这里并不清楚什么原因,但偶然记得之前在酷安上看到一个东西,过去翻了翻[2],说是要降级containerd包的版本。先查看下containerd包的版本:

然后下载帖子里这个包,用adb传到手机上(xftp也可以),然后使用dpkg -i containerd_1.6.21-1_aarch64.deb安装

接着查看版本apt show containerd -a就看到已经安装上了

然后重新启动sudo dockerd --iptables=false,在跑hello-world容器就正常了

试了下跑python也可以,那说明可以在手机跑爬虫了:

Ubuntu镜像也是可以的:

刷机包和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/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/47560.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker网络模式和Cgroup资源限制

目录 1、Docker网络 (1)Docker网络实现原理 查看容器的输出和日志信息 2、Docker 的网络模式 查看docker列表 (1)网络模式详解 1)host模式 2)container模式 3)none模式 4)br…

SpringCloud教程 | 第十篇: 读取Nacos的配置

1、nacos服务器选用 2、test.yaml这一个DataId配置如下: config:name: aabb222 spring:application:name: testdatasource:type: com.zaxxer.hikari.HikariDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/hmblogs?useUni…

MongoDB教程(十二):MongoDB数据库索引

💝💝💝首先,欢迎各位来到我的博客,很高兴能够在这里和您见面!希望您在这里不仅可以有所收获,同时也能感受到一份轻松欢乐的氛围,祝你生活愉快! 文章目录 引言一、MongoD…

【鸿蒙OS】【ArkUI】鸿蒙OS UI布局适配终极攻略

鸿蒙OS UI布局适配终极攻略 像素适配大法,此方法也适合Android ArkUI为开发者提供4种像素单位,框架采用vp为基准数据单位。 vp相当于Android里的dp fp相当于Android里的sp 官方是如何定义的呢,如下图 今天我来教大家如何用PX做到ArkUI的终级适配&…

Leetcode 2011. 执行操作后的变量值

问题描述: 存在一种仅支持 4 种操作和 1 个变量 X 的编程语言: X 和 X 使变量 X 的值 加 1--X 和 X-- 使变量 X 的值 减 1 最初,X 的值是 0 给你一个字符串数组 operations ,这是由操作组成的一个列表,返回执行所有…

C++初学者指南-5.标准库(第一部分)--标准库算法介绍

C初学者指南-5.标准库(第一部分)–标准库算法介绍 文章目录 C初学者指南-5.标准库(第一部分)--标准库算法介绍C的标准算法是:第一个示例组织输入范围自定义可调用参数并行执行(C17)迭代器和范围的类别错误消息命名空间std::ranges中的算法 (C20)算法参数图标相关内容…

linux 安装 RocketMQ 4.7

安装介绍 Centos 7RocketMQ 4.7JDK 1.8 (安装JDK参考)RocketMQ的官网地址: http://rocketmq.apache.orgGithub地址是 https://github.com/apach e/rocketmq 安装操作 下载RocketMQ RocketMQ运行版本下载地址: Rocketmq-all-4.7.1-bin-release.zip …

httpx,一个网络请求的 Python 新宠儿

大家好!我是爱摸鱼的小鸿,关注我,收看每期的编程干货。 一个简单的库,也许能够开启我们的智慧之门, 一个普通的方法,也许能在危急时刻挽救我们于水深火热, 一个新颖的思维方式,也许能…

AI大模型新纪元:哪四大趋势引领未来智能革命?

在人工智能热潮持续居高不下背景下,虽然全球AI大模型企业卷参数的激烈程度有所放缓,但大模型仍不断朝着万亿、十万亿参数发展,并推动多模态持续演进以通向AGI。同时,大模型也在朝向轻量化、高效化、垂直多元化发展,进而…

每日复盘-20240718

20240718 六日涨幅最大: ------1--------300713--------- 英可瑞 五日涨幅最大: ------1--------301016--------- 雷尔伟 四日涨幅最大: ------1--------301016--------- 雷尔伟 三日涨幅最大: ------1--------301016--------- 雷尔伟 二日涨幅最大: ------1--------300713----…

Linux LVM扩容方法

问题描述 VMware Centos环境,根分区为LVM,大小50G,现在需要对根分区扩容。我添加了一块500G的虚拟硬盘(/dev/sdb),如何把这500G扩容到根分区? LVM扩容方法 1. 对新磁盘分区 使用fdisk /dev/sdb命令,进…

SpringCloud02_consul概述、功能及下载、服务注册与发现、配置与刷新

文章目录 ①. Euraka为什么被废弃②. consul简介、如何下载③. consul功能及下载④. 服务注册与发现 - 8001改造⑤. 服务注册与发现 - 80改造⑥. 服务配置与刷新Refresh ①. Euraka为什么被废弃 ①. Eureka停更进维 ②. Eureka对初学者不友好,下图为自我保护机制 ③. 阿里巴巴…

linux下JDK的安装

前言: 安装部署java开发的代码都需要java环境,这里记录下linux下JDK的安装过程,仅供学习参考。 JDK的下载 下载地址:https://www.oracle.com/java/technologies/downloads 选择和操作系统匹配的版本进行下载 查看操作系统&…

HarmonyOS NEXT学习——@BuilderParam装饰器

初步理解,相当于VUE的插槽slot Builder function overBuilder() {}Component struct Child {label: string ChildBuilder customBuilder() {}Builder customChangeThisBuilder() {}BuilderParam customBuilderParam: () > void this.customBuilder; // 使用自定…

人工智能未来发展前景将会怎样?

当我们探讨人工智能未来的发展前景时,可以从多个角度来详细说明其可能的影响和趋势: 技术进步与应用扩展 1.深度学习与机器学习: 进一步优化和算法进展:深度学习已经取得了巨大成就,但仍面临挑战,如对小数…

浅说区间dp(下)

文章目录 环形区间dp例题[NOI1995] 石子合并题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示思路 [NOIP2006 提高组] 能量项链题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示思路 [NOIP2001 提高组] 数的划分题目描述输入格式输出格式样例 #1样例输…

你也许不知道,自己可能是一个「热人」

稍微标题党了一下。: ) 今天想跟大家分享的,是一种很少有人了解的人格特质。它非常普遍,许多人都或多或少有一些倾向,但却很少有人意识到它。 不妨看一看,你有没有下面这些特征: 有着极其旺盛的求知欲,对许…

paddleocr icdar2015数据集训练dbnet检测模型

参考:https://github.com/PaddlePaddle/PaddleOCR/blob/main/doc/doc_ch/detection.md 原理 DBNET论文 Real-time Scene Text Detection with Differentiable Binarization 参考:https://blog.csdn.net/qq_35756383/article/details/118679258 Real-T…

【STC89C51单片机】定时器/计数器的理解

目录 定时器/计数器1. 定时器怎么定时简单理解(加1经过了多少时间)什么是时钟周期什么是机器周期 2.如何设置定时基本结构相关寄存器1. TMOD寄存器2. TCON寄存器 代码示例 定时器/计数器 STC89C51单片机的定时器和计数器(Timers and Counter…

【BUG】已解决:NameError: name ‘XXX‘ is not defined

已解决:NameError: name ‘XXX‘ is not defined 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页,我是博主英杰,211科班出身,就职于医疗科技公司,热衷分享知识,武汉城市开发者社…