拆封容器:深入探讨虚拟容器技术

梅丽莎·麦凯
开发人员主

容器已经成为应用程序开发生命周期中每个阶段不可或缺的一部分。生产级编排工具(如Kubernetes)已经被构建来管理它们,容器平台(如Docker)在测试和开发中变得越来越普遍。关于如何构建和管理的Web教程简单Docker映像比比皆是!但什么是容器为什么它们对DevOps生态系统如此重要?这个演讲是为那些好奇的人准备的,他们想要深入了解一种技术的机制,这种技术的存在时间比你想象的要长。Docker从哪里来?那么容器生态系统中的其他项目呢——有替代方案吗?Docker映像在文件系统上的实际样子是什么?Docker镜像层是如何工作的?什么是组?系统资源是如何分配和管理的,是2022世界杯阿根廷预选赛赛程否存在您应该注意的问题?安全方面呢?怎么能JFrog容器注册表帮助我管理我的Docker映像?在这次演讲之后,您将对虚拟化容器技术的内容、方式和原因有一个扎实的理解。

视频记录

大家好,欢迎来到swampUP,欢迎来到这个关于集装箱开箱的演讲。我想快速开始,因为我很高兴能与你们分享我所学到的关于容器的一些东西,当然,这些东西现在仍然很流行。我希望通过这次演讲,您能够更好地理解容器是如何在您的系统上工作的,以及容器背后真正发生的一些事情。本次会议的问答将同时在聊天中进行。所以利用接下来的30分钟,把你的问题提出来。如果我在治疗期间找不到他们。我以后一定会跟你联系的。简单介绍一下我,我叫Melissa McKay。

今年2月,我刚以开发者倡导者的身份加入JFrog。我有开发人员的背景,在过去的20年里,我以某种方式或形式成为了一名开发人员。我的大部分经验都是在服务器端开发和Java方面,但多年来我有幸在许多不同的团队中工作过,使用过各种不同的技术、语言和差异集。我想你们大多数人都知道,现在只使用一种语言并不容易。所以,掌握多语言对我来说是一段疯狂的旅程。我在大团队,小团队,大公司,小公司工作过。我经历过挫折和成功,一路走来,我发现了一种深入了解事物的激情,分享我学到的东西,并希望在此过程中改进流程。几年前我开始演讲,我决定这是我想做更多的事情。所以,我毅然决然地成为了JFrog的开发者倡导者。很明显,这一切都成功了,今天我和你们一起来到了swamp。 So I feel privileged to be here with you and I’m super excited to talk with all of you today about virtual containers. So, let’s go ahead and get started. I’ll start out with a brief history to give some background context. Hopefully, it won’t be too boring. But there’s definitely some Milestones that have happened in the past that we should go over. So it better explains how we got to where we are today, then we’ll take a look at the container market, that’s interesting to see what’s been going on over the past few years, and it’ll be interesting to see what the next few years brings us. Then we’ll move into getting a real understanding of what Docker actually is. Docker is a very overloaded word term that is used and thrown around quite a bit. So we’ll clear that up. After that, we’ll be in an excellent place to talk about what a container actually is, and then we’ll review a few common container gotchas just a few simple things to avoid, stuff that I experienced right away when I started. Finally, I’ll leave you with an option for managing your images. So without further ado. Let’s jump in and start learning about containers. Now I know some of you are already wondering if you’re in the right place because that’s not the picture that you were expecting I’m sure. I know the classic shipping container photo is a pretty much expected, but there’s actually a couple reasons I chose to show bananas here. First and foremost, I’m tired of seeing shipping containers on every presentation about Docker, or containerization in general. So, I started a rebellion. You’re not going to see any shipping containers in this presentation.
其次,这确实是一个关于我们的行业如何适应处理有限资源的故事,香蕉让我想起了我祖父在我成长过程中反复告诉我的一个故事,它是这样的:他小时候的事情和我小时候的事情有很大的不同。2022世界杯阿根廷预选赛赛程我想每一代人都会对下一代说,他继续分享,当他还是个孩子的时候,他每年圣诞节都会得到一根香蕉。这一定是在20年代和30年代,香蕉在当时是一种享受,香蕉不会被浪费。他和他的兄弟姐妹们会拿起叉子刮香蕉皮,把最后一点香蕉都刮掉,因为明年可能才会有香蕉。也许这不是最好的类比,但我喜欢用这个故事来比喻20世纪60年代和70年代的计算资源。2022世界杯阿根廷预选赛赛程
我知道这是可行的,但是非常有限而且非常昂贵,最重要的是要花很长时间才能完成工作。通常一台计算机会在很长一段时间内专门为单个用户执行单个任务。显然,时间和资源的限制造成了瓶颈和效率低下。2022世界杯阿根廷预选赛赛程仅仅能够分享是不够的,还需要一种不妨碍彼此的分享方式,或者一个人无意中导致所有人的整个系统崩溃。所以,再一次,需求是发明之母,需要更好的战略和共享计算资源,实际上,开启了创新之路,我们从今天看到了巨大的好处。2022世界杯阿根廷预选赛赛程有一些关键的时间点把我们带到了今天的状态。我将从Chroot开始这节课。所以Chroot诞生于1979年,在Unix第7版的开发期间,并于1982年被添加到BSD中,能够更改进程及其子进程的表面根目录,导致了一些隔离,以便为测试不同的发行版提供一个环境,例如。所以Chroot是个好主意,解决了一些具体问题,但还需要更多。因此在2000年,FreeBSD引入了jail命令。
Jail比Chroot更复杂一些,它包含额外的功能,可以帮助进一步隔离文件系统、用户和网络,并能够为每个Jail分配IP地址。2004年,Solaris Zones通过提供应用程序、完整的用户进程和文件系统空间以及对系统硬件的访问,使我们更进一步。Solaris Zones还引入了能够快照文件系统的概念,您将看到这一点非常重要。2006年,Google推出了他们的进程容器。这些组后来被重命名为cgroups,其核心是隔离和限制进程的资源使用。这是巨大的。在2008年,cgroups被合并到Linux内核中,它与Linux命名空间一起导致了IBM Linux容器的开发。
2013年是重要的一年。Docker的出现带来了打包容器并将其从一个环境移动到另一个环境的能力。同年,Google开源了他们的“let me container that for you”项目,该项目为应用程序提供了创建和管理自己的子容器的能力。从这里开始,我们看到容器的使用,特别是Docker的使用,绝对是爆炸性的。2014年,Docker选择放弃LXE工具集,用lidcontainer启动容器,转而使用原生Golang解决方案。我一开始不知道的是Docker实际上是用Go写的。
这节历史课差不多讲完了,因为从这里开始,你会开始看到大量的项目名称、组织规范等。如果您没有更好地理解容器的工作原理,那么这只会使您感到困惑,而这正是本课程的重点。2015年6月的最后一件事非常重要,因为它可以让你了解市场变化背后的一些活动和动机。建立了开放容器项目/倡议。这是Linux基金会下的一个组织,它包括来自许多主要利益相关者的成员。包括Docker,它的目标是为容器运行时和映像规范创建开放标准,这非常重要。这就是历史课的全部内容。让我们来看看最近市场上关于容器运行时发生了什么。所以,我做了一些调查,我发现在过去的三年里Sysdig公司为Linux提供了一个非常强大的监控和故障排除工具;已经拿出了一份基于自身用户分析的容器报告。 Part of the report includes data on container runtimes that are in use. In 2017, they analyzed data from 45,000 containers. There’s no graph available for that because 99% of those were Docker. So, they didn’t feel the need to split up the results. In 2018, however, they doubled their sample size to 90,000 containers.
你可以看到83%是Docker, 12%是CoreOS RKT容器,4%是Mesos containerizer,还有1%是LXC。看起来其他容器运行时可能正在蚕食Docker。接下来是2019年。这是最新的Sysdig容器报告,其中包括超过200万个容器的统计数据。他们确实说明了来自SaaS和本地用户的包含数据。我不太确定过去两年,是否只是内部部署,或者为什么他们觉得有必要把这些信息放在那里。但两百万是个很大的数字,所以我们开始吧。Docker仍然保持相对强势,占79%,container-d占18%。但值得注意的是,container-d实际上是Docker构建的运行时。稍后我会告诉你更多关于那个的事情。 and the last 4% is Cri-o. So, I don’t know that there’s enough data here to determine whether Docker is going to stay on top in the future, or something completely different will prevail that remains to be seen. But it’s interesting especially because of what’s been happening over the last few years, which we’ll get to that later. But now that I’ve introduced a few of these other container runtimes that exist out there besides Docker; it’s time to start talking about what a container actually is, and what Docker actually provides in order to appreciate the differences between them. So, what exactly is Docker anyway? This is key. What Docker had over the players, the other players in the container game was this steadfast focus on commoditizing a complete solution, complete end-to-end solution that made it easy for developers to package, and deploy their applications.
一旦容器变得易于使用,我们都目睹了围绕容器的工具和资源的爆炸式增长,Docker映像格式也成为了市场上事实上的标准。2022世界杯阿根廷预选赛赛程我从Sysdig向您展示的统计数据是特定于容器运行时的,记住这个术语很重要。我将解释使用容器所涉及的各个部分,您将立即理解Docker如此迅速地占领市场的原因。作为用户,让我们想想我们到底需要什么才能让我们的应用运行起来。这个领域产生的每一项创新都是基于用户的需求。不管背后的动机是什么。如果用户非常需要或想要某些东西,那么解决方案提供商就有巨大的机会。这似乎是一件常识性的事情,这可能不值得说,但我们经常会发现自己过于深入到基本细节中,而忽略了我们试图解决的实际问题。这当然会导致大量的错失和忽视的机会。所以,这里有一个需求列表,分解成离散的特征。
首先,我们需要容器本身,有些人现在可能会问关于虚拟机的问题。这些已经在那里了,讨论结果超出了这节课的范围。因此,我不打算深入讨论虚拟机和容器之间的差异,也不打算讨论为什么要使用其中一个而不是另一个。我要说的是,虚拟机不是容器的同义词;最大的区别在于VM包含一个完整的操作系统,而容器共享它们运行的系统操作系统。容器的关键在于轻量级,并且能够无缝、快速地从一个环境迁移到另一个环境。我知道在虚拟机领域有发展,但那是另一个话题了。
因此,这个列表的其余部分我们需要一个图像格式来定义容器。我们需要一种方法来构建容器的映像,一种方法来管理映像,一种方法来分发和共享容器映像,一种方法来创建、启动和运行容器环境,以及一种方法来管理正在运行的容器的生命周期。我还没讲到编曲什么的但这足以证明我的观点了。所以,Docker已经准备好了所有问题的答案。如果你想开始使用容器,那就使用Docker引擎。哦,你需要一个图像格式,这是Docker图像格式。您需要一种方法来构建映像,使用Docker文件并调用Docker build。如果你想管理镜像,调用Docker images或Docker remove;如果你想共享镜像或使用别人的镜像,调用Docker push或Docker pull。哦,顺便说一下,我们有Docker Hub,你可以在那里存储和分享你的图像。你需要一个公共的,你需要一种方式来启动,运行和管理你的容器和它们的生活方式。 You can call Docker run, Docker stop Docker ps.
Docker成功地迅速满足了容器市场的迫切需求,此外,Docker提供的工具集使这一切变得如此简单。这足以让我们在整个销售过程中获得巨大的市场份额。
顺便说一下,为这张幻灯片找到一个相关的香蕉图片真的很困难。所以,我希望你能欣赏这个。还记得我在历史课上讲过的开放集装箱计划吗。在我们刚刚谈到的所有这些特征中,有两个是由OCI提出的。映像格式和容器运行时。Docker对他们的代码库进行了相当多的重组,开发了抽象,推出了非常棒的功能。他们是OCI的重要贡献者。将Docker V2镜像规范作为OCI镜像规范和runC的基础,runC作为OCI运行时规范的完整实现的参考。还有相当多的其他容器运行时正在流行,包括containerd, rkt, cri-o和Kata,它们都具有针对特定用例的不同级别的功能。值得指出的是,containerd实际上是由Docker贡献给CNCF原生云的,并且在内部使用runC。Containerd也被集成到Docker中,从1.11版开始就一直在使用,所以到现在已经有一段时间了。 So, the next few years will be interesting to observe what happens with these specs and how the OCI moves forward. It doesn’t seem that they’re done yet.
对于容器运行时的标准应该包含什么,不应该包含什么,有很多不同的观点。很多人都在讨论这个问题。我在这里添加了几个非常好的链接,如果您感兴趣,可以从这些链接开始了解更多关于容器运行时的知识。第二篇是伊恩·刘易斯系列博客的开头。他是一名谷歌开发倡导者。该博客的第一个副标题是,为什么容器运行时如此令人困惑?我也附和了,是的,是的。为什么呢?不管怎样,他在解释一些问题上做得很好。那么,现在我们了解了Docker所需要的一切,以及市场上正在发生的一些事情。 Let’s focus on just the container itself and what that actually looks like on your system. I’ll show you how it’s stored and what is actually happening under the covers. You’ll discover pretty quickly that images and containers aren’t really all that magical. So, my first experience with containers was as a new developer on a project with a tight deadline.
当然,我认为大多数项目的描述都是病态的。对我来说,最好的做法是直接开始在我的本地机器上启动和运行一些东西。我在实践中学习得最好,Docker文档实际上非常好。所以,如果你发现自己处于类似的位置,我建议你去看看他们的入门文档,我在这里分享了一个链接。我将通过该指南让您对您将需要的许多Docker命令有所了解。首先要注意的是,Docker映像只是一个完整文件系统的压缩包。当映像在系统上实际解压缩时,它只是被扔到它自己的目录中,该目录成为它的根文件系统。第二,运行容器所涉及的进程只是常规的Linux进程。
它们真的没什么特别的。您知道,从技术上讲,您可以创建和运行容器,而不需要调用适当的Linux命令。因此,名称空间是值得指出的。这是一个非常重要的组成部分,因为它用于在容器之间提供虚拟分离。这就是进程在容器内的方式,不要干扰另一个容器内的进程。在这里,您可以看到为我的机器上运行的postgres容器设置的一些名称。cgroups功能对于限制容器可以使用多少东西是不可或缺的,比如CPU、内存、网络带宽等,我可以在启动镜像时通过在Docker run命令中包含选项来设置这些限制。你可以从这个例子中看到。
我在其中一个容器上限制了内存使用限制。这不是用来表示正确的东西,正确的极限。看起来这个问题在Docker的新版本中已经被修复了。因此,我想快速地介绍一些文件系统细节,容器和映像实际上存储在文件系统中。首先,在你安装完Docker之后,运行命令Docker info会显示出一系列关于你的安装的信息,包括你的Docker根目录,我在这里已经注意到了。这是您将关心的有关Docker映像和容器的大多数内容的存储位置。
请注意,如果您使用的是Mac,那么您的容器实际上是在一个很小的Linux VM中运行的。因此,你需要使用屏幕,或者其他东西来进入那里,并实际进入Docker根目录来检查它。如果你不熟悉如何使用屏幕命令,一定要谷歌一下,先熟悉一下。如果你没有以正确的方式进入和退出屏幕,它会把你的文本显示弄得一团糟。如果你以前没做过,会有点沮丧。这张幻灯片展示了如何获取关于存储在系统上的映像的信息。首先,我使用Docker images命令列出了可用的镜像。我实际上已经安装了几个,但我只列出第一对在这里显示。使用Docker inspect命令。我可以检查任意图像,使用图像ID。
原谅我。这将产生大量的信息。但我想在这里强调的是图形驱动程序部分,它包含了属于该图像的所有图层所在目录的路径。因此,Docker镜像是由层组成的,层代表Docker文件中最初用于构建镜像的指令。这些层实际上可以转换为目录,为了节省空间,这些层可以跨图像共享。lowerdir、mergedir和upperdir部分很重要。lowerdir包含用于构建原始映像的所有目录或层。这些都是只读的。上层目录包含容器运行时修改的所有内容。重要的是要记住,这是短暂的数据,并且只在容器存在的时候存在。 In fact if you have data that you intend to keep you should utilize the volume features of Docker, and mount a location that will stick around after the container dies.
这是大多数运行数据库的容器的运行方式。mergedir就像一个虚拟目录,它结合了lowerdir、upperdir和workdir的所有内容。工作目录类似于内部目录。这张幻灯片显示,我的系统上运行了几个容器,其中两个是我本地的JFrog容器注册表安装,包括Artifactory的容器,和postgres数据库的另一个容器。另一个是我正在摆弄的一个简单的测试容器。实际上,我清理了我的系统,这样我就能得到一些干净的屏幕截图。在此之前,我有大量的图像和容器在运行。无论如何,请注意,正在运行的容器的容器id与容器子目录名相匹配,这里还需要记住一些其他内容。
哦,如果你停止一个容器,相应的目录不会消失,直到容器被真正删除。使用Docker remove命令。所以,如果你停了下来,如果你停了那些永远不会清理的容器,你可能会看到你的可用空间开始减少。有一个Docker修剪命令,你可以时不时地使用它来帮助清理东西。因此,围绕构建和运行映像和容器的工具集使事情变得如此简单,以至于在某些地方也很容易搬起石头砸自己的脚。以下是我遇到的3个最常见的陷阱,当我第一次开始使用容器时,我几乎立刻就遇到了这些陷阱。
第一种是,以根用户身份运行容器化的应用程序。在这里,我将诚实地说,当我最初启动并运行容器时。我对它的工作效果感到非常兴奋,所以我没有把它当回事。我听到了,但我没有,你知道,它没有着陆。现在您知道进程在运行的容器中,就像系统上的任何其他进程一样。我会遇到一些约束条件。现在在容器中以root身份运行是很可怕的。这样做就有可能使进程脱离容器的预期范围,并获得对主机资源的访问权。2022世界杯阿根廷预选赛赛程这正是我们不希望发生的事。最好的方法是创建一个用户,并在构建容器时在Docker文件中使用user命令,以便运行该用户的进程。
当使用Docker run命令时,有一种方法可以指定用户,但这留下了忘记这样做的可能性。如果映像是默认设置的,而不是作为根运行,那就更好了。还要注意从Docker Hub提取的官方图像,它们是否以root身份运行,或者是否由您自己决定。因此,尽管Docker提供了在容器上设置资源限制的能力。它不会自动为你做这件事。事实上,默认设置是免费的,没有任何限制。因此,请确保了解应用程序的资源需求,太少的容器会饿死,太多的容器会使系统上的其他容器窒息。容器的资源使用情况也是需要长期监控并根据需要进行调整的。这是一种很好的方法,可以确定是否出现了问题,或者系统上的负载是否由于某种原因发生了变化。所以,这是一个相当大的安全问题。
在构建映像时,很容易自满,而不注意实际导入的内容。您不仅需要注意您在Docker文件中指定的过时版本,还需要注意基本映像中的内容来自哪里。不更新容器中的库中的包可能会导致一些令人尴尬的结果,特别是当发现特定工件存在安全问题时,现在有可用的工具可以提醒您。说到帮助管理图像的工具。JFrog Artifactory支持Docker注册表和镜像。您可以像使用其他类型的工件一样使用它,既可以作为基于第三方的图像的现金,也可以作为您自己的内部注册表。上传Docker图像后,您可以收集统计数据,甚至可以深入到图像的每一层以获取更多信息。如果您已经集成了一个CICD解决方案,您还可以确定哪个构建生成了一个特定的映像,或者哪个构建使用了它。我们在前面讨论了不定期更新映像的问题,JFrog Xray是一种安全扫描工具,如果您的工件存在任何已知的安全漏洞,甚至是许可问题,它会提醒您。对于Docker映像,它特别有用,因为它能够深入到映像的各个层中,以准确地找出哪些库或包被标记为问题。 You have control over how sensitive to make these alerts, and what actions to take when they’re triggered Whether to fill a build, prevent a download, or simply send a notification about the problem. All right. We’ve come to the end of our time here.
谢谢大家的到来。我希望你喜欢这次会议,你从中得到了一些东西,可以带回你的团队,如果你有任何问题,请随时与我联系。享受剩下的沼泽在线。

免费试用JFrog !