艰难的集装箱:Gocker:用Go编写的迷你码头

2020-06-23 12:19:57

它是一组Linux操作系统原语,提供了容器的错觉。一个进程或一组进程可以脱离它们的环境或名称空间,生活在它们自己的新名称空间中,独立于主机的默认名称空间。像Docker这样的容器管理系统使您可以非常轻松地管理机器上的容器。但是这些集装箱是如何建造的呢?它只是一个Linux系统调用序列(主要涉及名称空间和cgroup),在最基本的级别上,同时也利用其他现有的Linux技术来实现容器文件系统、网络等。

Gocker是在Go编程语言中从头开始实现Docker的核心功能。这里的主要目的是了解容器在Linux系统调用级别的确切工作方式。Gocker允许您创建容器、管理容器映像、在现有容器中执行进程等。

Unixism博客在Linux系统调用级别解释了Gocker及其工作原理。如果您对该级别的详细信息感兴趣,请阅读它。

当我遇到Bocker时,它是用Bash shell脚本编写的类似Docker的容器管理系统,我发现它有两个问题:

Bocker使用各种Linux实用程序。虽然您明白了这一点,但命令行实用程序是不透明的,您无法理解它们在Linux系统调用级别上所做的事情。此外,单个命令有时可以发出多个相关的系统调用。

Bocker的上一次承诺是在5年多以前,现在已经不起作用了。Docker Hub API的更改似乎破坏了它。

另一方面,Gocker是纯Go源代码,它允许您查看Linux系统调用级别到底发生了什么。这应该会让您更好地理解容器的实际工作方式。

别在这误会我的意思。Bocker仍然是一个非常棒的、非常有创意的编写工具。如果你想了解容器是如何工作的,你仍然应该看一看,我相信你会从它中学到一两样东西,就像我一样。

Gocker可以模拟Docker的核心,允许您管理Docker镜像(从Docker Hub获取)、运行容器、列出正在运行的容器或在已经运行的容器中执行进程:

Gocker使用覆盖文件系统快速创建容器,无需复制整个文件系统,同时还可以在多个容器实例之间共享相同的容器镜像。

Gocker容器拥有自己的网络名称空间,并且能够访问互联网。请参阅下面的限制。

您可以控制CPU百分比、RAM大小和进程数等系统资源。Gocker通过利用cgroup实现了这一点。

虽然创建了限制以下内容的cgroup,但除非您在gocker run命令中指定了--mem、--cpu或--pid选项,否则大洲可以使用无限的资源。这些标志分别限制容器可以使用的最大RAM、CPU核心和PID。

➜sudo./gocker image 2020/06/12 08:32:23 cmd参数:[./gocker image]image tag idcentos最新的470671670 cacredis最新的c349430fd524ubuntu 18.04 c3c304cb4f22最新的1d622ef86b13➜sudo./gocker run alpine/bin/sh2020/06/12 08:33:33 cmd args:[./gocker。请稍候.2020/06/12 08:33:36 ImageHash:a24bb40132962020/06/12 08:33:36正在检查是否存在另一个名称下的映像.2020/06/12 08:33:36 Image Nodes';不存在。正在下载.2020/06/12 08:33:38已成功下载alpine2020/06/12 08:33:38解压缩图层至:/var/lib/gocker/images/a24bb4013296/fe8bebfdf212/fs 2020/06/12 08:33:38要覆盖的镜像挂载:a24bb40132962020/06/12 08:33:38 cmd args:[/proc/self/exe setup-netns 7bfe9b0f1c2e]2020/06/12 08:33:38 cmd args:[/proc。:38命令参数:[/proc/self/exe子模式--img=a24bb4013296 7bfe9b0f1c2e/bin/sh]/#ifconfig lo链路封装:本地环回inet地址:127.0.0.1掩码:255.0.0.0 inet6地址:1/128作用域:主机上环回运行mtu:65536度量:1接收数据包:0错误:0丢弃:0溢出:0。0 B)传输字节:0(0.0B)veth1_7bfe9b链路封装:以太网HWaddr 02:42:6E:e8:fc:06 inet地址:172.29.41.13 bcast:172.29.255.255掩码:255.255.0.0 inet6地址:fe80::42:6eff:fe8:fc06/64作用域:链路连接广播运行多播MTU:1500度量:1 RX数据包:22错误:0丢弃:0过。冲突:0 txqueue elen:1000RX字节:2328(2.2KiB)Tx字节:586(586.0 B)/#ps aux PID用户时间命令1根0:00/proc/self/exe子模式--img=a24bb4013296 7bfe9b0f1c2e/bin/sh 7根0:00/bin/sh 9根0:00ps aux/#apk add python3Fetch http://dl-cdn.alpinelinux.org/alpine/v3.12/main/x86_64/APKINDEX.tar.gzfetch http://dl-cdn.alpinelinux.org/alpine。/v3.12/Community/x86_64/APKINDEX.tar.gz(1/10)安装libbz2(1.0.8-r1)(2/10)安装expat(2.2.9-r1)(3/10)安装libffi(3.3-r2)(4/10)安装gdbm(1.13-r1)(5/10)安装xz-libs(5.2.5-r0)(6/10)安装ncurses-Terfo-base(6.2_p0。ncurses-libs(6.2_p20200523-r0)(8/10)安装readline(8.0.4-r0)(9/10)安装sqlite-libs(3.32.1-r0)(10/10)安装python3(3.8.3-r0)执行busybox-1.31.1-r16.riggerOK:24个包中的53 MiB/#python3Python 3.8.3(默认情况下,2020-05-15 01:53:50)[GCC 9.3.0]linuxType";帮助";,";版权所有&34;,&34;信用&34;或";许可证&34;有关详细信息,&>;退出()/#exit2020/06/12 08:34:34:34容器完成。➜sudo./gocker运行ubuntu/bin/bash2020/06/12 08:35:13 cmd参数:[./gocker run ubuntu/bin/b./gocker run ubuntu/bin/bash2020/06/12 08:35:13 cmd args:[./gocker run ubuntu/bin/b./gocker run ubuntu/bin/b./gocker run ubuntu/bin/b。未下载。2020/06/12 08:35:13要覆盖装载的映像:1d622ef86b132020/06/12 08:35:13命令参数:[/proc/self/exe setup-netns c7eb7bab7e4c]2020/06/12 08:35:13命令参数:[/proc/self/exe setup-veth c7eb7bab7e4c]2020/06/12 08:35:13。

➜sudo./gocker ps[sudo]Shuveb的密码:2020/06/12 08:36:19 cmd参数:[./gocker ps]容器ID镜像COMMANDc7eb7bab7e4c ubuntu:最新的/usr/bin/bash➜sudo。/gocker exec c7eb7bab7e4c/bin/bash2020/06/12 08:37:15 cmd参数:[./gocc。SL 03:05 0:00/proc/self/exe子模式--img=1d622ef86b13 root 8 0.0 0.0 4116 3236?s+03:05 0:00/bin/bashroot 11 0.0 0.0 4116 3376?s 03:07 0:00/bin/bashroot 14 0.0 0.0 5888 2956?r+03:07 0:00 ps aux root@c7eb7bab7e4c:/#。

Gocker当前不支持暴露主机上的容器端口。每当Docker容器需要公开主机上的端口时,Docker都会使用程序docker-proxy作为ge的代理

Gocker的错误处理做得不好。如果出现问题,特别是在尝试运行容器时,Gocker可能无法彻底卸载某些文件系统。

当您第一次运行Gocker时,会创建一个新的网桥gocker0。由于所有容器网络接口都连接到此网桥,因此它们可以相互通信,而无需您执行任何操作。但是,要使容器能够到达互联网,您需要在主机上启用数据包转发。为此,提供了一个方便的脚本enable_interet.sh。在运行它之前,您可能需要更改它以反映您的Internet连接接口的名称。脚本中有说明。运行此程序后,Gocker容器应该能够访问互联网并安装软件包等。

NetLink来配置Linux网络接口,而不必陷入Netlink套接字编程的泥潭。

Gocker以root身份运行。自费使用。这是我的第一个超过合理行数的围棋程序,我相信有更好的方法来编写围棋程序,而且可能仍然有很多错误在这里徘徊。下面是Gocker对您的系统执行的一些操作,以便您了解:

为此,运行Gocker最安全的方式可能是在虚拟机中运行。

我在基于Arch Linux的日常计算机上开发了Gocker。我还在Ubuntu20.04虚拟机上测试了Gocker。效果很好。

克隆存储库后(假设您已在计算机上安装了GO),请切换到Gocker目录并使用以下命令检索依赖项:

我的名字是Shuveb Hussain,我是Linux博客Unixism.net的作者。你可以在Twitter上关注我,我在Twitter上发布了与技术相关的内容,主要集中在Linux、性能、可伸缩性和云技术上。