前言
相信绝大多数人在安卓上使用容器都是从proot–chroot这么一个过程。那么,在这段经历中,我们也许会对chroot/unshare以外更强的容器技术而感到好奇。
那么,就来看看如何在Android上使用LXC吧。
前期准备
编译内核
这个我帮不了你,你只能靠着网上的教程来自行编译一个支持LXC的内核。
安装LXC
pkg up -y pkg i root-repo -y pkg i tsu lxc -y
|
在国内你可能需要换源。这里不再详细说,网上都是教程。
检查配置
通过 lxc-checkconfig
检查配置:
确保它是全绿的。如果不是 那你编译的内核可能要返工了。
配置
配置 cgroup
每次运行 LXC 前执行:
mount -t tmpfs -o mode=755 tmpfs /sys/fs/cgroup mkdir -p /sys/fs/cgroup/devices mount -t cgroup -o devices cgroup /sys/fs/cgroup/devices mkdir -p /sys/fs/cgroup/systemd mount -t cgroup cgroup -o none,name=systemd /sys/fs/cgroup/systemd
lxc-setup-cgroups
|
配置网络
本小章(配置网络)内所有的命令只需执行一次。不要重复执行。
运行:
注意 /sys/fs/cgroup
的挂载选项:
echo "lxc.init.cmd = /sbin/init systemd.unified_cgroup_hierarchy=0" >> $PREFIX/share/lxc/config/common.conf
|
echo "lxc.init.cmd = /sbin/init systemd.unified_cgroup_hierarchy" >>; $PREFIX/share/lxc/config/common.conf
|
完成后,运行:
sed -i 's/lxc\.net\.0\.type = empty/lxc.net.0.type = none/g' /data/data/com.termux/files/usr/etc/lxc/default.conf
|
其他配置
每个容器有一份单独的配置文件。他们的位置一般在 $PREFIX/var/lib/lxc/{NAME}/config
,NAME 为你容器的名称。
lxc.environment = TERM="xterm-256color"
|
lxc.cgroup.memory.limit_in_bytes = 2G # 限制为2G
|
lxc.hook.pre-start = bash -c "if ! mountpoint -q /sys/fs/cgroup &>/dev/null; then mkdir -p /sys/fs/cgroup; mount -t cgroup2 -o rw,nosuid,nodev,noexec,relatime cgroup /sys/fs/cgroup; fi; for cg in blkio cpu cpuacct cpuset devices freezer memory pids; do; if ! mountpoint -q /sys/fs/cgroup/${cg} &>/dev/null; then; mkdir -p /sys/fs/cgroup/${cg}; mount -t cgroup2 -o rw,nosuid,nodev,noexec,relatime ${cg} /sys/fs/cgroup/${cg}; fi; mkdir -p /sys/fs/cgroup/systemd; mount -t cgroup -o none,name=systemd systemd /sys/fs/cgroup/systemd; umount -Rl /sys/fs/cgroup/cg2_bpf; umount -Rl /sys/fs/cgroup/schedtune; umount -Rl '${LXC_ROOTFS_PATH}'; sed -i -E 's/^( *# *DNS=.*|DNS=.*)/DNS=223.5.5.5/g' '${LXC_ROOTFS_PATH}/etc/systemd/resolved.conf'; mount -B '${LXC_ROOTFS_PATH}' '${LXC_ROOTFS_PATH}'; mount -i -o remount,suid '${LXC_ROOTFS_PATH}'; if [ ! -e '${LXC_ROOTFS_PATH}/usr/bin/udevadm.' ]; then mv -f '${LXC_ROOTFS_PATH}/usr/bin/udevadm' '${LXC_ROOTFS_PATH}/usr/bin/udevadm.'; fi; echo -e '#!/usr/bin/bash\n/usr/bin/udevadm. \"\$@\" || true' > '${LXC_ROOTFS_PATH}/usr/bin/udevadm'; chmod +x '${LXC_ROOTFS_PATH}/usr/bin/udevadm'; true;"
|
启动
通过 lxc-create
创建容器:
lxc-create -t download -n {NAME} -- --no-validate -d {DISTRIBUTION} -a {ARCH}
|
你还可以通过 --server
选项来指定镜像站:
lxc-create -t download -n {NAME} -- --server mirrors.bfsu.edu.cn/lxc-images --no-validate -d {DISTRIBUTION} -a {ARCH}
|
记得把 {NAME}
{DISTRIBUTION}
{ARCH}
换成你自己需要的。
这之后,输入:
lxc-start -n {NAME} -F -d
|
即可进入容器。
常见问题
容器内没有网络
进入容器:
groupadd -g 3003 aid_inet usermod -g aid_inet 用户名
|
添加至 aid_inet
组即可。
普通用户无法使用 sudo
容器内重新挂载 /
即可。
mount -n -o remount,suid /
|
注意,每次打开容器都需要这么做。
或者启动自动挂载:
[Unit] Description=/etc/rc.local Compatibility ConditionPathExists=/etc/rc.local
[Service] Type=forking ExecStart=/etc/rc.local start TimeoutSec=0 StandardOutput=tty RemainAfterExit=yes SysVStartPriority=99
[Install] WantedBy=multi-user.target
mount -n -o remount,suid /
|
如何运行 Docker
就目前而言,Termux root-repo 中的 Docker 是烂掉的,有很大可能会出现 shim 错误。更建议在 LXC 容器中运行 Docker。