译者的介绍:在各种容器大量进入我们的生活的背景下,弄清它们是从哪一种技术开始的,这是非常有趣和有用的。 其中一些可以用到今天,但是并不是每个人都记得这样的方法(或者知道在快速发展中是否没有找到它们)。 一种这样的技术是用户模式Linux。 原始内容的作者四处翻阅,弄清楚哪些旧的开发仍然有效,哪些没什么,并收集了有关如何在2k19中自行开发UML的分步说明。 是的,我们邀请了Cadey原始帖子的作者到Habr ,因此,如果您有任何疑问,请在评论中用英语提问。
实际上,Linux用户模式是Linux内核端口本身。 此模式允许您在用户进程中运行成熟的Linux内核,开发人员通常使用它来测试驱动程序。 但是,此模式也可用作通用隔离的工具,其原理类似于虚拟机的操作。 该模式比Docker提供更多的隔离,但比KVM或Virtual Box等成熟的虚拟机少。
通常,用户模式可能看起来很奇怪并且难以使用,但是它仍然具有自己的应用领域。 毕竟,这是一个完整的Linux内核,可以从没有特权的用户那里使用。 此功能使您可以运行潜在不受信任的代码,而不会对主机造成任何威胁。 并且由于这是一个成熟的内核,它的进程与主机是隔离的,也就是说,
在用户模式下运行的进程对主机是
不可见的 。 这与通常的Docker容器不同,在这种情况下,主机始终会看到存储库中的进程。 看一看我的其中一台服务器中的pstree:
containerd─┬─containerd-shim─┬─tini─┬─dnsd───19*[{dnsd}] │ │ └─s6-svscan───s6-supervise │ └─10*[{containerd-shim}] ├─containerd-shim─┬─tini─┬─aerial───21*[{aerial}] │ │ └─s6-svscan───s6-supervise │ └─10*[{containerd-shim}] ├─containerd-shim─┬─tini─┬─s6-svscan───s6-supervise │ │ └─surl │ └─9*[{containerd-shim}] ├─containerd-shim─┬─tini─┬─h───13*[{h}] │ │ └─s6-svscan───s6-supervise │ └─10*[{containerd-shim}] ├─containerd-shim─┬─goproxy───14*[{goproxy}] │ └─9*[{containerd-shim}] └─32*[{containerd}]
并将其与用户模式下的pstree Linux内核进行比较:
linux─┬─5*[linux] └─slirp
使用Docker容器时,我可以从主机看到来宾系统上运行的进程的名称。 对于Linux用户模式,这是不可能的。 这是什么意思? 这意味着通过Linux的审核子系统工作的监视工具
看不到来宾系统上正在运行的进程。 但是在某些情况下,此功能可能会变成一把双刃剑。
总的来说,下面的整个帖子是一系列研究和粗鲁的尝试,以实现所需的结果。 为此,我不得不使用各种古老的工具,阅读内核源代码,在我上小学时就对调试的代码进行密集调试,还必须使用特殊的binar挑选Heroku程序集以寻找所需的工具。 所有这些工作使我IRC中的家伙称呼我为魔术。 我希望这篇文章将成为可靠的文档,以便使用相同的内核,但使用更新的内核和OS版本。
客制化
设置Linux用户模式需要几个步骤:
- 在主机上安装依赖项;
- 下载Linux内核
- 内核程序集设置;
- 内核程序集;
- 二进制安装;
- 设置访客文件系统;
- 选择内核启动参数;
- 访客网络设置;
- 启动来宾内核。
我假设,如果您决定自己动手,很可能您会完成某些Ubuntu或类似Debian的系统中描述的所有操作。 我试图在自己喜欢的发行版Alpine中实现上述所有功能,但显然没有任何结果,因为Linux内核在glibc-isms上紧密绑定了User Mode中的驱动程序。 我最终确定问题后,计划将其报告给上游。
在主机上安装依赖项
Ubuntu至少需要以下软件包才能构建Linux内核(提供全新安装):
- 'build-essential'
- 'flex'
- 'bison'
- 'xz-utils'
- 'wget'
- 'ca-certificates'
- 'bc'
- 'linux-headers'
您可以使用以下命令(具有root特权或使用sudo)安装它们:
apt-get -y install build-essential flex bison xz-utils wget ca-certificates bc \ linux-headers-$(uname -r)
请注意,运行Linux内核的菜单设置程序将需要安装
libncurses-dev
。 请确保使用以下命令(具有root特权或sudo)安装它:
apt-get -y install libncurses-dev
内核下载
确定要加载和随后组装内核的位置。 对于此操作,您将需要分配约1.3 GB的硬盘空间,因此请确保您有一个。
然后转到
kernel.org并获取URL以下载最新的稳定内核版本。 在撰写本文时:
https :
//cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.1.16.tar.xz使用
'wget'
下载此文件:
wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.1.16.tar.xz
并用
'tar'
提取出来:
tar xJf linux-5.1.16.tar.xz
现在,我们进入解压缩tarball时创建的目录:
cd linux-5.1.16
内核构建配置
内核构建系统是
Makefile的集合,其中包含
许多自定义工具和脚本以使过程自动化。 首先,请打开在线安装程序:
make ARCH=um menuconfig
它将部分完成组装并为您显示一个对话框。 当窗口底部显示“
[Select]
”时,您可以使用空格键或Enter键进行配置。 与往常一样,在窗口上导航时,使用键盘的向上和向下箭头,以及元素的选择-“左”或“右”。
视图指针--->表示您位于通过Enter键访问的子菜单中。 解决之道显然是通过“
[Exit]
”。
在“
[Select]
”中包含以下参数,并确保它们旁边有一个“ [*]”符号:
UML-specific Options: - Host filesystem Networking support (enable this to get the submenu to show up): - Networking options: - TCP/IP Networking UML Network devices: - Virtual network device - SLiRP transport
通过依次选择“
[Exit]
”,可以退出此窗口中的所有内容。 只要确保最后提示您保存配置并选择“
[Yes]
”即可。
我建议您阅读本文后,尝试使用内核构建选项。 通过这些实验,您可以在理解底层内核机制的工作以及各种标志对其组装的影响方面学到很多东西。
内核组装
Linux内核是一个很棒的程序,可以完成很多事情。 即使在旧设备上的配置如此之小,组装起来也可能需要花费相当长的时间。 因此,使用以下命令构建内核:
make ARCH=um -j$(nproc)
怎么了 该命令将告诉我们的汇编器在构建过程中使用所有可用的内核和处理器线程。 Build末尾的
$(nproc)
替代
nproc
的输出,该
nproc
是标准Ubuntu构建中
coreutils
一部分。
一段时间后,我们的内核将被编译成可执行的
./linux
文件。
二进制安装
由于Linux上的用户模式会创建常规二进制文件,因此您可以像安装其他任何实用程序一样安装它。 这是我的操作方式:
mkdir -p ~/bin cp linux ~/bin/linux
还值得检查
~/bin
是否在
$PATH
:
export PATH=$PATH:$HOME/bin
设置访客文件系统
为访客文件系统创建目录:
mkdir -p $HOME/prefix/uml-demo cd $HOME/prefix
打开alpinelinux.org,然后在
“下载”部分中找到当前链接以下载
MINI ROOT FILESYSTEM
。 在撰写本文时,它是:
http://dl-cdn.alpinelinux.org/alpine/v3.10/releases/x86_64/alpine-minirootfs-3.10.0-x86_64.tar.gz
使用wget下载此压缩包:
wget -O alpine-rootfs.tgz http://dl-cdn.alpinelinux.org/alpine/v3.10/releases/x86_64/alpine-minirootfs-3.10.0-x86_64.tar.gz
现在输入来宾文件系统的目录并解压缩归档文件:
cd uml-demo tar xf ../alpine-rootfs.tgz
所描述的步骤将创建一个小的文件系统模板。 由于系统的性质,通过Alpine apk管理器安装软件包非常困难。 但是,此财务报表足以评估总体思路。
我们还需要
tini工具来抑制来宾内核的
僵尸进程占用的内存。
wget -O tini https://github.com/krallin/tini/releases/download/v0.18.0/tini-static chmod +x tini
创建内核命令行
与大多数其他程序一样,Linux内核具有命令行参数,可以通过指定
--help
开关进行访问。
山姆-帮助 linux --help User Mode Linux v5.1.16 available at http://user-mode-linux.sourceforge.net/ --showconfig Prints the config file that this UML binary was generated from. iomem=<name>,<file> Configure <file> as an IO memory region named <name>. mem=<Amount of desired ram> This controls how much "physical" memory the kernel allocates for the system. The size is specified as a number followed by one of 'k', 'K', 'm', 'M', which have the obvious meanings. This is not related to the amount of memory in the host. It can be more, and the excess, if it's ever used, will just be swapped out. Example: mem=64M --help Prints this message. debug this flag is not needed to run gdb on UML in skas mode root=<file containing the root fs> This is actually used by the generic kernel in exactly the same way as in any other kernel. If you configure a number of block devices and want to boot off something other than ubd0, you would use something like: root=/dev/ubd5 --version Prints the version number of the kernel. umid=<name> This is used to assign a unique identity to this UML machine and is used for naming the pid file and management console socket. con[0-9]*=<channel description> Attach a console or serial line to a host channel. See http://user-mode-linux.sourceforge.net/old/input.html for a complete description of this switch. eth[0-9]+=<transport>,<options> Configure a network device. aio=2.4 This is used to force UML to use 2.4-style AIO even when 2.6 AIO is available. 2.4 AIO is a single thread that handles one request at a time, synchronously. 2.6 AIO is a thread which uses the 2.6 AIO interface to handle an arbitrary number of pending requests. 2.6 AIO is not available in tt mode, on 2.4 hosts, or when UML is built with /usr/include/linux/aio_abi.h not available. Many distributions don't include aio_abi.h, so you will need to copy it from a kernel tree to your /usr/include/linux in order to build an AIO-capable UML nosysemu Turns off syscall emulation patch for ptrace (SYSEMU). SYSEMU is a performance-patch introduced by Laurent Vivier. It changes behaviour of ptrace() and helps reduce host context switch rates. To make it work, you need a kernel patch for your host, too. See http://perso.wanadoo.fr/laurent.vivier/UML/ for further information. uml_dir=<directory> The location to place the pid and umid files. quiet Turns off information messages during boot. hostfs=<root dir>,<flags>,... This is used to set hostfs parameters. The root directory argument is used to confine all hostfs mounts to within the specified directory tree on the host. If this isn't specified, then a user inside UML can mount anything on the host that's accessible to the user that's running it. The only flag currently supported is 'append', which specifies that all files opened by hostfs will be opened in append mode.
此横幅照亮了主要的启动选项。 让我们以最少的必需选项集运行内核:
linux \ root=/dev/root \ rootfstype=hostfs \ rootflags=$HOME/prefix/uml-demo \ rw \ mem=64M \ init=/bin/sh
上面的几行告诉我们的核心:
- 假设根文件系统是伪设备
/dev/root
。 - 选择hostfs作为根文件系统驱动程序。
- 挂载我们在根设备上创建的来宾文件系统。
- 是的,在读写模式下。
- 仅使用64 MB的RAM(您可以使用更少的内存,具体取决于您计划执行的操作,但64 MB似乎是最佳大小)。
- 内核自动将
/bin/sh
作为init
过程。
运行此命令,您应该得到如下内容:
另一张纸 Core dump limits : soft - 0 hard - NONE Checking that ptrace can change system call numbers...OK Checking syscall emulation patch for ptrace...OK Checking advanced syscall emulation patch for ptrace...OK Checking environment variables for a tempdir...none found Checking if /dev/shm is on tmpfs...OK Checking PROT_EXEC mmap in /dev/shm...OK Adding 32137216 bytes to physical memory to account for exec-shield gap Linux version 5.1.16 (cadey@kahless) (gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)) #30 Sun Jul 7 18:57:19 UTC 2019 Built 1 zonelists, mobility grouping on. Total pages: 23898 Kernel command line: root=/dev/root rootflags=/home/cadey/dl/uml/alpine rootfstype=hostfs rw mem=64M init=/bin/sh Dentry cache hash table entries: 16384 (order: 5, 131072 bytes) Inode-cache hash table entries: 8192 (order: 4, 65536 bytes) Memory: 59584K/96920K available (2692K kernel code, 708K rwdata, 588K rodata, 104K init, 244K bss, 37336K reserved, 0K cma-reserved) SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1 NR_IRQS: 15 clocksource: timer: mask: 0xffffffffffffffff max_cycles: 0x1cd42e205, max_idle_ns: 881590404426 ns Calibrating delay loop... 7479.29 BogoMIPS (lpj=37396480) pid_max: default: 32768 minimum: 301 Mount-cache hash table entries: 512 (order: 0, 4096 bytes) Mountpoint-cache hash table entries: 512 (order: 0, 4096 bytes) Checking that host ptys support output SIGIO...Yes Checking that host ptys support SIGIO on close...No, enabling workaround devtmpfs: initialized random: get_random_bytes called from setup_net+0x48/0x1e0 with crng_init=0 Using 2.6 host AIO clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns futex hash table entries: 256 (order: 0, 6144 bytes) NET: Registered protocol family 16 clocksource: Switched to clocksource timer NET: Registered protocol family 2 tcp_listen_portaddr_hash hash table entries: 256 (order: 0, 4096 bytes) TCP established hash table entries: 1024 (order: 1, 8192 bytes) TCP bind hash table entries: 1024 (order: 1, 8192 bytes) TCP: Hash tables configured (established 1024 bind 1024) UDP hash table entries: 256 (order: 1, 8192 bytes) UDP-Lite hash table entries: 256 (order: 1, 8192 bytes) NET: Registered protocol family 1 console [stderr0] disabled mconsole (version 2) initialized on /home/cadey/.uml/tEwIjm/mconsole Checking host MADV_REMOVE support...OK workingset: timestamp_bits=62 max_order=14 bucket_order=0 Block layer SCSI generic (bsg) driver version 0.4 loaded (major 254) io scheduler noop registered (default) io scheduler bfq registered loop: module loaded NET: Registered protocol family 17 Initialized stdio console driver Using a channel type which is configured out of UML setup_one_line failed for device 1 : Configuration failed Using a channel type which is configured out of UML setup_one_line failed for device 2 : Configuration failed Using a channel type which is configured out of UML setup_one_line failed for device 3 : Configuration failed Using a channel type which is configured out of UML setup_one_line failed for device 4 : Configuration failed Using a channel type which is configured out of UML setup_one_line failed for device 5 : Configuration failed Using a channel type which is configured out of UML setup_one_line failed for device 6 : Configuration failed Using a channel type which is configured out of UML setup_one_line failed for device 7 : Configuration failed Using a channel type which is configured out of UML setup_one_line failed for device 8 : Configuration failed Using a channel type which is configured out of UML setup_one_line failed for device 9 : Configuration failed Using a channel type which is configured out of UML setup_one_line failed for device 10 : Configuration failed Using a channel type which is configured out of UML setup_one_line failed for device 11 : Configuration failed Using a channel type which is configured out of UML setup_one_line failed for device 12 : Configuration failed Using a channel type which is configured out of UML setup_one_line failed for device 13 : Configuration failed Using a channel type which is configured out of UML setup_one_line failed for device 14 : Configuration failed Using a channel type which is configured out of UML setup_one_line failed for device 15 : Configuration failed Console initialized on /dev/tty0 console [tty0] enabled console [mc-1] enabled Failed to initialize ubd device 0 :Couldn't determine size of device's file VFS: Mounted root (hostfs filesystem) on device 0:11. devtmpfs: mounted This architecture does not have kernel memory protection. Run /bin/sh as init process /bin/sh: can't access tty; job control turned off random: fast init done / #
进行上述操作将使我们的
来宾系统最少 ,没有
/proc
或分配的主机名之类的东西。 例如,尝试以下命令:
- uname -av
- cat /proc/self/pid
- hostname
要退出来宾系统,请键入
exit
或按Ctrl-d。 这将导致外壳崩溃,随后出现内核崩溃:
/ # exit Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000000 fish: “./linux root=/dev/root rootflag…” terminated by signal SIGABRT (Abort)
我们之所以对此内核感到恐慌,是因为Linux内核认为初始化过程一直在运行。 没有它,系统将无法运行并关闭。 但是,由于这是一个用户模式过程,因此结果将自身发送到
SIGABRT
,从而导致退出。
访客网络设置
而在我们这里,一切都不按照计划进行。 在用户模式Linux中,有限的“用户模式”的整个概念开始瓦解。 毕竟,出于我们所有人清楚的原因,通常在系统级别,网络仅限于
特权执行模式。
注意事项 trans .:有关在UML中使用网络的不同选项的更多信息,请参见此处 。到slirp旅行
但是,有一个古老且几乎不受支持的工具叫做
Slirp ,用户模式Linux可以使用它与网络交互。 它在用户级别大致类似于TCP / IP堆栈,并且不需要任何系统许可即可运行。 该工具
于1995年
发布,最新更新可追溯到
2006年 。 Slirp非常老。 一段时间以来,没有支持和更新,编译器已经走得很远,以至于现在只能将此工具描述为
“代码腐烂” 。
因此,让我们从Ubuntu存储库中推出Slirp并尝试运行它:
sudo apt-get install slirp /usr/bin/slirp Slirp v1.0.17 (BETA) Copyright (c) 1995,1996 Danny Gasparovski and others. All rights reserved. This program is copyrighted, free software. Please read the file COPYRIGHT that came with the Slirp package for the terms and conditions of the copyright. IP address of Slirp host: 127.0.0.1 IP address of your DNS(s): 1.1.1.1, 10.77.0.7 Your address is 10.0.2.15 (or anything else you want) Type five zeroes (0) to exit. [autodetect SLIP/CSLIP, MTU 1500, MRU 1500, 115200 baud] SLiRP Ready ... fish: “/usr/bin/slirp” terminated by signal SIGSEGV (Address boundary error)
天哪 让我们为Slirp安装调试器,看看是否可以弄清楚这里发生了什么:
sudo apt-get install gdb slirp-dbgsym gdb /usr/bin/slirp GNU gdb (Ubuntu 8.1-0ubuntu3) 8.1.0.20180409-git Copyright (C) 2018 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from /usr/bin/slirp...Reading symbols from /usr/lib/debug/.build-id/c6/2e75b69581a1ad85f72ac32c0d7af913d4861f.debug...done. done. (gdb) run Starting program: /usr/bin/slirp Slirp v1.0.17 (BETA) Copyright (c) 1995,1996 Danny Gasparovski and others. All rights reserved. This program is copyrighted, free software. Please read the file COPYRIGHT that came with the Slirp package for the terms and conditions of the copyright. IP address of Slirp host: 127.0.0.1 IP address of your DNS(s): 1.1.1.1, 10.77.0.7 Your address is 10.0.2.15 (or anything else you want) Type five zeroes (0) to exit. [autodetect SLIP/CSLIP, MTU 1500, MRU 1500, 115200 baud] SLiRP Ready ... Program received signal SIGSEGV, Segmentation fault. ip_slowtimo () at ip_input.c:457 457 ip_input.c: No such file or directory.
错误在
这一行跳动。 让我们看一下堆栈跟踪,也许有什么对我们有帮助:
(gdb) bt full #0 ip_slowtimo () at ip_input.c:457 fp = 0x55784a40 #1 0x000055555556a57c in main_loop () at ./main.c:980 so = <optimized out> so_next = <optimized out> timeout = {tv_sec = 0, tv_usec = 0} ret = 0 nfds = 0 ttyp = <optimized out> ttyp2 = <optimized out> best_time = <optimized out> tmp_time = <optimized out> #2 0x000055555555b116 in main (argc=1, argv=0x7fffffffdc58) at ./main.c:95 No locals.
在这里,我们看到当slirp尝试检查超时时,在主循环开始期间发生了故障。 在这一点上,我不得不放弃尝试调试。 但是,让我们看看从排序编译的Slirp是否有效。 我直接从
Sourceforge网站重新加载了档案,因为通过命令行从那里拖东西是很痛苦的:
cd ~/dl wget https://xena.greedo.xeserv.us/files/slirp-1.0.16.tar.gz tar xf slirp-1.0.16.tar.gz cd slirp-1.0.16/src ./configure --prefix=$HOME/prefix/slirp make
在这里,我们看到有关未定义的内置函数的警告,即有关链接生成的二进制文件的可能性的警报。 在2006年到这一刻之间,gcc似乎停止创建中间编译文件的内置函数中使用的字符。 让我们尝试用一个空的注释替换
inline
,然后看一下结果:
vi slirp.h :6 a <enter> #define inline /**/ <escape> :wq make
不行 这也不起作用。 您仍然找不到这些功能的字符。
此时,我放弃了,开始在Github上寻找
Heroku构建包 。 我的理论基于以下事实:某些Heroku构建软件包将包含我需要的二进制文件。 结果,搜索把我
引到了这里 。 我下载并解压缩了
uml.tar.gz
,发现以下内容:
total 6136 -rwxr-xr-x 1 cadey cadey 79744 Dec 10 2017 ifconfig* -rwxr-xr-x 1 cadey cadey 373 Dec 13 2017 init* -rwxr-xr-x 1 cadey cadey 149688 Dec 10 2017 insmod* -rwxr-xr-x 1 cadey cadey 66600 Dec 10 2017 route* -rwxr-xr-x 1 cadey cadey 181056 Jun 26 2015 slirp* -rwxr-xr-x 1 cadey cadey 5786592 Dec 15 2017 uml* -rwxr-xr-x 1 cadey cadey 211 Dec 13 2017 uml_run*
这是一个二进制的slirp文件! 他工作吗?
./slirp Slirp v1.0.17 (BETA) FULL_BOLT Copyright (c) 1995,1996 Danny Gasparovski and others. All rights reserved. This program is copyrighted, free software. Please read the file COPYRIGHT that came with the Slirp package for the terms and conditions of the copyright. IP address of Slirp host: 127.0.0.1 IP address of your DNS(s): 1.1.1.1, 10.77.0.7 Your address is 10.0.2.15 (or anything else you want) Type five zeroes (0) to exit. [autodetect SLIP/CSLIP, MTU 1500, MRU 1500] SLiRP Ready ...
不会崩溃-因此应该可以使用! 让我们将此二进制文件挂接到
~/bin/slirp
:
cp slirp ~/bin/slirp
万一包的创建者删除了它,我
做了一个镜子 。
网络设置
现在,让我们在来宾核心上建立网络。
更新启动选项 :
linux \ root=/dev/root \ rootfstype=hostfs \ rootflags=$HOME/prefix/uml-demo \ rw \ mem=64M \ eth0=slirp,,$HOME/bin/slirp \ init=/bin/sh
现在让我们打开网络:
mount -t proc proc proc/ mount -t sysfs sys sys/ ifconfig eth0 10.0.2.14 netmask 255.255.255.240 broadcast 10.0.2.15 route add default gw 10.0.2.2
ifconfig
起作用,需要前两个配置命令
/proc
和
/sys
,这将设置网络接口以与Slirp通信。
route
命令设置内核路由表以强制所有流量通过Slirp隧道。 让我们通过DNS查询来验证这一点:
nslookup google.com 8.8.8.8 Server: 8.8.8.8 Address 1: 8.8.8.8 dns.google Name: google.com Address 1: 172.217.12.206 lga25s63-in-f14.1e100.net Address 2: 2607:f8b0:4006:81b::200e lga25s63-in-x0e.1e100.net
有效!
注意:显然,原始帖子是使用有线网卡或不需要其他驱动程序的其他配置写在桌面上的。 在配备Intel WiFi 8265的笔记本电脑上,启动网络时发生错误 /
显然,内核无法与网络驱动程序通信。 不幸的是,尝试将固件编译到内核中并没有解决问题。 在发布时,无法在此特定配置中找到解决方案。 在较简单的配置上(例如,在Virtualbox中),接口会正确显示。让我们使用以下shell脚本自动化重定向:
#!/bin/sh # init.sh mount -t proc proc proc/ mount -t sysfs sys sys/ ifconfig eth0 10.0.2.14 netmask 255.255.255.240 broadcast 10.0.2.15 route add default gw 10.0.2.2 echo "networking set up" exec /tini /bin/sh
并将其标记为可执行文件:
chmod +x init.sh
然后对内核命令行进行更改:
linux \ root=/dev/root \ rootfstype=hostfs \ rootflags=$HOME/prefix/uml-demo \ rw \ mem=64M \ eth0=slirp,,$HOME/bin/slirp \ init=/init.sh
并重复:
SLiRP Ready ... networking set up /bin/sh: can't access tty; job control turned off nslookup google.com 8.8.8.8 Server: 8.8.8.8 Address 1: 8.8.8.8 dns.google Name: google.com Address 1: 172.217.12.206 lga25s63-in-f14.1e100.net Address 2: 2607:f8b0:4004:800::200e iad30s09-in-x0e.1e100.net
网络稳定!
-
,
Dockerfile , .
, , . , .
, , . - , , User Mode Linux . . Docker — tar-,
docker export
, . , shell-.
Rkeene #lobsters Freenode. Slirp . , Slackware slirp, Ubuntu Alpine slirp Rkeene . , -.