[Root] Termux:以原生效能在Android手機上跑Docker (紅米Note 5)

🇺🇸 English version

Docker之所以不能直接在Android配合Termux跑,就是因為Android的kernel(內核)缺乏相關功能,那麼只要自行編譯手機kernel把缺少的功能打開就可以了。另外docker在Termux的repo也可以下載的到。

刷kernel的小常識: Android刷kerenl不會刪除手機資料。不過為避免卡開機,最好用TWRP先備份原廠的boot分區再操作。

  • 手機: 紅米Note 5(whyred),已Root,系統為Lineage OS 18。

如果你的機型跟我一樣,可到Github下載我做好的boot.img直接刷入。此kerenl基於RAD Kernel,以GPL v2授權釋出。僅於LineageOS測試。

1. 檢查運作條件

  1. 手機安裝Termux,下載執行Moby的腳本
1
2
3
4
5
pkg install wget tsu
wget https://raw.githubusercontent.com/moby/moby/master/contrib/check-config.sh
chmod +x check-config.sh
sed -i '1s_.*_#!/data/data/com.termux/files/usr/bin/bash_' check-config.sh
sudo ./check-config.sh
  1. 看看目前手機的kernel缺少哪些功能,把紅字missing部分記錄下來。最主要是General Necessary下的項目要全部開啟。

2. 尋找kernel & 測試編譯

我的思路是這樣: 找一個穩定的第三方kernel專案,確認能順利在自己電腦編譯,刷到手機也正常,再以此為基礎進行進入深入修改。

完整編譯&刷內核步驟,看完這篇再往下看: 如何編譯修改Android kernel

3. 修改kernel

  1. 在用機型defconfig建立.config之後,使用make menuconfig開啟kconfig介面,按照剛剛手機顯示missing的項目,將其一一開啟。

  2. 例如我要開啟CONFIG_OVERLAY_FS這個選項,就在menuconfig的介面按下「/」

  3. 輸入名稱搜尋,menuconfig會告訴你設定值的大約位置。

  4. 鍵盤上下鍵找到該選項,按下y啟用。

  5. 用鍵盤左右鍵,移動到Save,儲存設定值。移動到Exit按下Enter離開。

  6. 根據FreddieOliveira的說明,還要修改kernel專案目錄下的kernel/Makefile

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
diff --git a/kernel/Makefile b/kernel/Makefile
index d5c1115..2dea801 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile

 $(obj)/configs.o: $(obj)/config_data.h
# config_data.h contains the same information as ikconfig.h but gzipped.
# Info from config_data can be extracted from /proc/config*
targets += config_data.gz
-$(obj)/config_data.gz: arch/arm64/configs/lavender_stock-defconfig FORCE
+$(obj)/config_data.gz: $(KCONFIG_CONFIG) FORCE
    $(call if_changed,gzip)

    filechk_ikconfiggz = (echo "static const char kernel_config_data[] __used = MAGIC_START"; cat $< | scripts/basic/bin2c; echo "MAGIC_END;")
  1. 還有修改net/netfilter/xt_qtaguid.c
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
--- orig/net/netfilter/xt_qtaguid.c     2020-05-12 12:13:14.000000000 +0300
+++ my/net/netfilter/xt_qtaguid.c       2019-09-15 23:56:45.000000000 +0300


{
        struct proc_iface_stat_fmt_info *p = m->private;
        struct iface_stat *iface_entry;
-       struct rtnl_link_stats64 dev_stats, *stats;
+       struct rtnl_link_stats64 *stats;
        struct rtnl_link_stats64 no_dev_stats = {0};


        current->pid, current->tgid, from_kuid(&init_user_ns, current_fsuid()));
        iface_entry = list_entry(v, struct iface_stat, list);
+       stats = &no_dev_stats;
-       if (iface_entry->active) {
-               stats = dev_get_stats(iface_entry->net_dev,
-                                     &dev_stats);
-       } else {
-               stats = &no_dev_stats;
-       }
        /*
         * If the meaning of the data changes, then update the fmtX
         * string.
  1. 重新編譯一次kernel。
1
make -j8
  1. 用AIK重新打包檔案,用TWRP刷到手機。開機後會顯示「你的裝置發生內部問題」,屬於正常現象。

  2. 這支紅米Note 5開機後還要再使用以下指令才能正常掛載cgroup:

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

4. 手機安裝docker

  1. 用Moby的腳本再次確認kernel相容性都是綠色的之後,透過Termux的root repo下載docker。
1
pkg install root-repo && pkg install docker
  1. Termux左邊滑出來開第二個終端機,先啟動docker daemon。
1
sudo dockerd --iptables=false
  1. 另一個終端機啟動docker容器,例如Hello World:
1
sudo docker run hello-world
  1. 測試Apache伺服器:
1
sudo docker run -d -p 80:80 --name myapache --net=host --dns=8.8.8.8 httpd
  1. 這樣docker算是正常執行了,一些關於網路的詳細設定請到【參考資料】處查詢。

5. 參考資料

感謝Freddie Oliveira提供詳盡的解釋。

This tutorial shows how to run docker natively on Android, without VMs and chroot.


感謝您的閱讀。歡迎分享Ivon的部落格(ivonblog.com)的文章,引用或轉載請註明文章網址,並遵守創用CC-姓名標示-非商業性-禁止改作 4.0 國際授權條款。如需商業使用請來信告之。

written by human, not by AI

如果本網站文章對您有幫助,歡迎請我喝杯珍珠奶茶。

留言板

點選按鈕,選擇您覺得方便的留言系統。要討論程式碼請用Giscus,匿名討論請用Disqus。

這是Giscus留言板,需要登入Github帳號才能留言。支援markdown語法,方便您張貼程式碼,若要上傳圖片請貼Imgur連結。您的留言會在Github Discussions向所有人公開。

這是Disqus留言板,您可能會看到Disqus投放的廣告。無論有無登入皆可留言。此處留言只有本站參與者看得到。若您選擇以訪客身份匿名留言,就不會收到後續回覆通知。