PhotobyElaineCasaponUnsplash本文核心内容整理自BrianHolt的workshop《Complete-Intro-Containers》。类似于Docker的容器技术并不是操作系统固有的能力,而是结合Linux的一些特性实现进程组隔离的技术。本文将从容器技术的发展介绍入手,然后阐述哪些Linux特性构成了容器技术的核心部分。希望大家通过阅读本文,对Docker等容器技术有更深入的了解。一、为什么需要容器容器技术并不是凭空出现的。它源于时代发展中人们对如何更有效地利用计算机资源的思考和工程实践。在本章中,我将穿越容器技术出现之前的时代,帮助大家理解容器技术解决了什么样的问题。1.1在早期的裸机时代互联网服务中,如果要架设web服务器,需要在某处租用服务器设备来运行程序代码。只要由足够的合格人员维护,服务器性能就可以最大化。裸机时代的问题是扩容服务极其不灵活:如果要增加设备,需要找服务器供应商(Dell或IBM)购买新的物理设备,并指派专业人员安装、调试、维护。开始。两个月。并且,部署服务器集群时,升级操作系统和驱动程序、硬件更换和维修、网络问题修复、布线、机房管理权限设置、数据中心温度控制、支付电费和IPS费用。..等等,这些都需要专业的团队来处理。1.2虚拟机时代于是我们进入了虚拟机时代,虚拟机是用户和硬件设备之间的一层抽象。与当初裸机时代相比,一台计算机服务于单个用户代理,而现在一台计算机允许多个用户代理登录并使用计算资源来运行彼此的服务。只要设备性能足够,用户可以在需要时快速添加新服务。这使我们能够在服务扩展方面获得一些灵活性。但是,这种模式存在一些问题:任何用户都有权获取其他用户服务存储的数据;用户可以通过启动ForkBomb来掠夺服务器资源(见下文);物理设备上的任何租户为了解决这个问题,出现了虚拟机技术:即当用户创建服务时,在计算机的主操作系统上安装一个新的操作系统来调度硬件资源以达到目的的数据隔离。而当一个服务崩溃时,至多是该服务所属的操作系统崩溃,服务器设备上的其他租户不会受到影响。虚拟机技术的缺点是在主操作系统中运行其他操作系统带来的性能损失。但只要计算机有足够的计算能力和内存,这些性能损失是可以接受的。ForkBomb是一种不断产生子进程占用大量系统资源,导致系统无法正常工作甚至停止响应的攻击方式。它通常会在操作系统中创建大量进程,消耗系统内存和处理器资源,导致系统崩溃。1.3公有云时代有了MicrosoftAzure、AmazonWebServices、阿里云等公有云服务商提供的虚拟机服务,用户不再需要管理昂贵复杂的数据中心,只需要管理自己的应用。虽然云服务提供商不会帮助用户更新操作系统,但他们会定期更新服务器设备。但在这种模式下,虚拟机提供商提供给用户的本质上是计算机的硬件设备(CPU和内存),用户仍然需要为整个操作系统的调度和维护付费(如网管)、安装和更新)。软件等),又需要专业的技术人员负责。如果能帮助用户省去维护操作系统的开销,让应用程序直接运行起来,那就太好了。这种需要催生了下一个时代。1.4容器时代容器技术为用户提供了许多虚拟机安全和资源管理功能,同时节省了运行整个操作系统的成本。它通过以下三个Linux命令成功地将进程组相互隔离:chroot:实现目录级别的资源隔离;unshare:实现进程级的资源隔离;cgroup:限制在隔离环境中可以调度的资源大小;介绍这三个命令。2.实现容器技术的三个关键Linux命令2.1chroot命令chroot是一个Linux命令,允许为新进程创建根目录。当为容器设置新的目录时,容器内的进程将无法访问根目录外的任何数据,消除了数据泄露的安全风险。运行以下命令开始:dockerrun-it--namedocker-host--rm--privilegedubuntu:bionic命令分析:dockerrun:在容器中运行一些命令;-it:保持shell交互;创建一个新目录并输入:mkdir/my-new-root&&cd$_;创建一些秘密文件:echo"mysupersecretthing">>/my-new-root/secret.txt;运行命令:chroot/my-new-rootbash;此时程序会报错:chroot:failedtoruncommand'bash':Nosuchfileordirectory这是因为新的根目录/my-new-root中不包含bash程序,执行以下命令修复:mkdir/my-new-root/bin;cp/bin/bash/bin/ls/my-new-root/bin/;chroot/我的新根庆典;这个时候程序还是会报错,因为我们还没有安装bash依赖。(通过ldd命令可见):linux-vdso.so.1(0x00007ffe5705a000)libtinfo.so.5=>/lib/x86_64-linux-gnu/libtinfo.so.5(0x00007fb89f047000)libdl.so.2=>/lib/x86_64-linux-gnu/libdl.so.2(0x00007fb89ee43000)libc.so.6=>/lib/x86_64-linux-gnu/libc.so.6(0x00007fb89ea52000)/lib64/ld-linux-x86-64.so.2(0x00007fb89f58b000)然后运行以下命令:mkdir/my-new-root/lib{,64};将bash依赖项复制到新创建的根目录:cp/lib/x86_64-linux-gnu/libtinfo。so.5/lib/x86_64-linux-gnu/libdl.so.2/lib/x86_64-linux-gnu/libc.so.6/my-new-root/lib;cp/lib64/ld-linux-x86-64.so.2/my-new-root/lib64;同样的方法安装ls的依赖:cp/lib/x86_64-linux-gnu/libselinux.so.1/lib/x86_64-linux-gnu/libpcre.so.3/lib/x86_64-linux-gnu/libpthread。so.0/my-new-root/lib此时运行chroot/my-new-rootbash命令就可以成功运行了。在bashshell中使用pwd命令查看当前根目录为/。至此,我们就完成了目录级别的资源隔离。2.2unshare命令chroot命令可以使操作系统阻止用户访问目录下的文件,但用户仍然可以通过查看系统进程了解计算机的运行状态。通过杀进程、卸载文件系统等方式,恶意用户仍然会对计算机的安全造成威胁。2.2.1chroot命令的问题打开一个新的终端,运行dockerexec-itdocker-hostbash命令进入操作系统;运行tail-f/my-new-root/secret.txt&命令持久化一个后台进程;运行ps命令查看进程ID(PID);在原终端执行kill
