自下而上学习容器

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我从2015年开始使用容器,我对容器最初的理解就是把它们看成是轻量级的虚拟机,只是启动时间比虚拟机快了很多。脑子里有了这样的概念,就很容易看懂网上那些关于如何将Python或Node应用程序装入容器的教程。但很快,我意识到仅仅将容器看成是轻量级的虚拟机有点跳过简单化了,这导致我无法对以下这些问题做出判断:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"容器可以做什么以及不可以做什么;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"哪些是使用容器的最佳实践以及哪些不是;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"哪些东西放在容器是安全的以及哪些不是。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"既然“容器就是虚拟机”这种理解有失偏颇,我就开始深入探究,看看容器到底是什么,而Docker无疑是最好的切入点。问题是,Docker是一个可以用来做各种各样事情的庞然大物,而运行它的命令又如此简单(比如docker run nginx),很容易就蒙蔽了我们。与Docker相关的资料有很多,它们要么是太过浅显的教程,要么太多艰深,新手根本就看不懂。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"于是,我花了一些时间,为读者铺平了学习容器的道路。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"多年来,我尝试从不同的角度探究,终于找到了一条适合我的学习路径。不久前,我在推特上分享了我的学习路径,引起了很多人的共鸣。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本文并不打算一次性解释完所有有关容器的东西。相反,它是我多年来对这个领域探究的一道“前菜”。它介绍了我的学习路径,你可以顺着这条路径,再去阅读其他更加深入介绍容器的文章。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"掌握容器知识不是一项简单的任务,所以慢慢来,不要跳过实操的部分!"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"容器学习路径"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我发现按照下面这样的顺序来学习容器非常有效:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Linux容器——学习底层的实现细节;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"容器镜像——了解什么是镜像以及为什么需要镜像;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"容器管理器——了解Docker是如何管理单台主机上的容器的;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"容器编配器——了解Kubernetes是如何管理集群里的容器的;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"非Linux容器——了解其他容器实现,打开更大的视野。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"容器不是虚拟机"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"容器是一种隔离(命名空间)且受约束(通过cgroups、capabilities、seccomp)的进程。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上面的这个解释非常有助于我理解什么是容器。当然,这个解释并非绝对准确,当你读到这篇文章的末尾你就会知道,但在刚开始学习容器时,这样的解释是很合适的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/b5\/7c\/b5bba821b3ac2bac74c6e4a55474f17c.png","alt":null,"title":"","style":[{"key":"width","value":"100%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"要在Linux上启动一个进程,需要fork\/exec它。但要启动一个容器化的进程,要先创建命名空间、配置cgroups,等等。或者,换句话说,为进程准备一个箱子,让进程在箱子里运行。容器运行时就是一种用来创建这种箱子的工具。容器运行时知道怎样准备好箱子,然后在箱子里启动一个容器化的进程。又因为大多数运行时都遵循常用的规范,容器就成为一种标准的工作负载单元。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用最广的容器运行时是runc。runc是一种普通的命令行工具,所以可以在没有Docker或其他高级容器软件的情况下直接使用它。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/c3\/2d\/c36813e4c0bcfce0da1c5282c90cf52d.png","alt":null,"title":"","style":[{"key":"width","value":"100%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"runc启动一个容器化进程的过程"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我对此感到兴奋万分,甚至还写了一系列关于"},{"type":"link","attrs":{"href":"https:\/\/iximiuz.com\/en\/categories\/?category=Container%20Runtime%20Shim&accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhY2Nlc3NfcmVzb3VyY2UiLCJleHAiOjE2MzkxMTg1NjUsImciOiJqV3lnUHlDZDNjUGczNkg5IiwiaWF0IjoxNjM5MTE4MjY1LCJ1c2VySWQiOjcwMDUxODA5fQ.hS4YtRu-vD6UN_s5o3S9DbHAbW3g50WiID1nP4x-0ag","title":null,"type":null},"content":[{"type":"text","text":"容器运行时垫片"}]},{"type":"text","text":"(shim)的文章。垫片是指底层容器运行时(如runc)和高级容器管理器(如containerd)之间的一种软件。要做好垫片,需要对运行时了如指掌,所以这一系列文章先从"},{"type":"link","attrs":{"href":"https:\/\/iximiuz.com\/en\/posts\/implementing-container-runtime-shim?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhY2Nlc3NfcmVzb3VyY2UiLCJleHAiOjE2MzkxMTg1NjUsImciOiJqV3lnUHlDZDNjUGczNkg5IiwiaWF0IjoxNjM5MTE4MjY1LCJ1c2VySWQiOjcwMDUxODA5fQ.hS4YtRu-vD6UN_s5o3S9DbHAbW3g50WiID1nP4x-0ag","title":null,"type":null},"content":[{"type":"text","text":"深入分析使用最为广泛的容器运行时"}]},{"type":"text","text":"开始。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/aa\/df\/aa8f0375903b5c54d482bc431caf34df.png","alt":null,"title":"","style":[{"key":"width","value":"100%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"容器运行时垫片"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"运行容器不一定需要镜像"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"不过,构建镜像需要容器。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"对于熟悉runc是如何启动容器的人来说,他们都知道镜像并非是必需的。要运行一个容器,运行时需要一个bundle,其中包括:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一个config.json文件,里面包含了与容器有关的参数(例如可执行文件的路径、环境变量,等等);"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"包含可执行文件及其相关文件(如果有的话)的目录。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通常,bundle的目录结构与Linux发行版的文件结构类似(\/var、\/usr、\/lib、\/etc,等等)。当runc启动这样的一个容器,运行在容器中的进程就获得了一个根文件系统,看起来与Linux(比如Debian、CentOS或Alpine)很像。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但这种文件结构并非是强制性的。现在,所谓的Scratch或Distroless容器越来越流行,越是小巧的容器出现安全漏洞的可能性就越少。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我在这篇中介绍了"},{"type":"link","attrs":{"href":"https:\/\/iximiuz.com\/en\/posts\/not-every-container-has-an-operating-system-inside?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhY2Nlc3NfcmVzb3VyY2UiLCJleHAiOjE2MzkxMTg1NjUsImciOiJqV3lnUHlDZDNjUGczNkg5IiwiaWF0IjoxNjM5MTE4MjY1LCJ1c2VySWQiOjcwMDUxODA5fQ.hS4YtRu-vD6UN_s5o3S9DbHAbW3g50WiID1nP4x-0ag","title":null,"type":null},"content":[{"type":"text","text":"如何创建一个只包含Go二进制文件的容器"}]},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/67\/12\/67423d8f76b19aa6415b17349dcde912.png","alt":null,"title":"","style":[{"key":"width","value":"100%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用dive查看scratch镜像"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"既然运行容器不一定需要镜像,那我们为什么还要有容器镜像?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"当每一个容器都包含根文件系统的一个数兆字节那么大的拷贝副本时,所需的磁盘空间就会急剧增加。因此,镜像的存在是为了有效地解决存储和发行问题。对这个问题感兴趣的可以阅读这篇"},{"type":"link","attrs":{"href":"https:\/\/iximiuz.com\/en\/posts\/you-dont-need-an-image-to-run-a-container?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhY2Nlc3NfcmVzb3VyY2UiLCJleHAiOjE2MzkxMTg1NjUsImciOiJqV3lnUHlDZDNjUGczNkg5IiwiaWF0IjoxNjM5MTE4MjY1LCJ1c2VySWQiOjcwMDUxODA5fQ.hS4YtRu-vD6UN_s5o3S9DbHAbW3g50WiID1nP4x-0ag","title":null,"type":null},"content":[{"type":"text","text":"文章"}]},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"你有没有想过镜像是如何构建出来的?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Docker所推广的工作流程试图让你认为镜像才是主要的,容器次之。在执行docker run 命令时,你需要指定一个镜像才能运行容器。但我们知道,严格来说,事情并没有这么简单。实际上,你需要(临时)运行容器来构建镜像!想知道为什么,请阅读这篇"},{"type":"link","attrs":{"href":"https:\/\/iximiuz.com\/en\/posts\/you-need-containers-to-build-an-image?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhY2Nlc3NfcmVzb3VyY2UiLCJleHAiOjE2MzkxMTg1NjUsImciOiJqV3lnUHlDZDNjUGczNkg5IiwiaWF0IjoxNjM5MTE4MjY1LCJ1c2VySWQiOjcwMDUxODA5fQ.hS4YtRu-vD6UN_s5o3S9DbHAbW3g50WiID1nP4x-0ag","title":null,"type":null},"content":[{"type":"text","text":"文章"}]},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"单宿主机上的容器管理器"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在现实世界中,我们发明了集装箱是为了增加一艘船可以装载的物品数量,类似的,容器是为了提高服务器的资源利用率。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一个典型的服务器现在运行数十或数百个容器。因此,它们需要有效地共存在一台服务器上。单个容器运行时关注的是单个容器的生命周期,而容器管理器关注的是在单台主机上共存的多个容器。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"容器管理器的主要职责包括镜像的拉取、解包、配置容器间网络、存储容器日志,等等。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在这方面,你可能认为Docker就是一个很好的例子。但我发现containerd是一个更具代表性的例子。与runc一样,containerd在一开始只是Docker的一个组件,后来被提取到一个独立的项目中。containerd可以使用runc或任何实现了containerd-shim接口的运行时。最酷的是,你可以像使用Docker一样使用containerd来轻松地运行容器。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这篇文章介绍了"},{"type":"link","attrs":{"href":"https:\/\/iximiuz.com\/en\/posts\/containerd-command-line-clients?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhY2Nlc3NfcmVzb3VyY2UiLCJleHAiOjE2MzkxMTg1NjUsImciOiJqV3lnUHlDZDNjUGczNkg5IiwiaWF0IjoxNjM5MTE4MjY1LCJ1c2VySWQiOjcwMDUxODA5fQ.hS4YtRu-vD6UN_s5o3S9DbHAbW3g50WiID1nP4x-0ag","title":null,"type":null},"content":[{"type":"text","text":"如何在命令行中使用containerd"}]},{"type":"text","text":"——这是一个很好的练习,让你更接近实际的容器是什么样子的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果你想了解更多关于容器管理器内部的知识,请看这篇文章。它介绍了"},{"type":"link","attrs":{"href":"https:\/\/iximiuz.com\/en\/posts\/conman-the-container-manager-inception?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhY2Nlc3NfcmVzb3VyY2UiLCJleHAiOjE2MzkxMTg1NjUsImciOiJqV3lnUHlDZDNjUGczNkg5IiwiaWF0IjoxNjM5MTE4MjY1LCJ1c2VySWQiOjcwMDUxODA5fQ.hS4YtRu-vD6UN_s5o3S9DbHAbW3g50WiID1nP4x-0ag","title":null,"type":null},"content":[{"type":"text","text":"如何从零开始实现一个容器管理器"}]},{"type":"text","text":":"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/02\/a0\/02ea8567862022df498dc5c6760dfea0.png","alt":null,"title":"","style":[{"key":"width","value":"100%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"containerd与docker"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"现在,我们准备好要了解Docker了!如果我们忽略(现在已弃用)Swarm,那么Docker包含如下这些:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"dockerd——位于containerd守护进程前面的一个高级守护进程;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"docker——一个命令行客户端,用于与dockerd交互。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/08\/e5\/0803c49141da26350284ae96cea9afe5.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Docker的分层架构"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在我看来,Docker目前的主要任务是让容器工作流变得更友好。为了简化开发人员的工作,Docker将所有主要容器用例整合到一个工具中:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"构建\/拉取\/推送\/扫描图像;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"启动\/暂停\/检查\/杀死容器;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"创建网络\/重定向端口;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"挂载\/卸载\/删除卷;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其他。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是到了2021年,几乎每个用例都被写成了一个定制的软件(如podman、buildah、skopeo、kaniko,等等),以便提供更好的替代解决方案。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"多宿主容器编配器"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在单台主机上协调运行的容器已经很难了,在多个主机之间协调容器就更困难了。还记得Docker Swarm吗?Docker在加入多主机容器编配特性时就已经相当可怕了,因为给已有的守护进程带来了更多的责任……"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"忽略守护进程数量不断膨胀这个问题,Docker Swarm看起来还是不错的。但另一种编配器赢得了比赛——Kubernetes!所以,大约从2020年开始,Docker Swarm就过时了,我们每周都会听到几个新出现的“古希腊”词汇。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Kubernetes将多个服务器(节点)连接到一个集群中,每个节点都有一个叫做kubelet的本地代理。kubelet负责启动Pod(一组容器),但并不是它自己做这些事情。过去,它使用dockerd,但现在这种方法已被弃用,取而代之的是更通用的容器运行时接口(CRI)。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/b7\/a1\/b73fdac10ec68b8b6a5332d4b362bca1.png","alt":null,"title":"","style":[{"key":"width","value":"100%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Kubernetes可以使用containerd、cri-o或其他CRI运行时"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"容器编配器需要完成很多任务。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如何将容器按照高级原语分组(Pods、ReplicaSets等)?"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如何将运行容器的节点连接到一个公共网络中?"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如何提供服务发现?"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其他。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Kubernetes和其他编配器(如Nomad或AWS ECS)可以帮助开发团队更容易地创建独立的服务。它帮助解决了很多管理上的问题,尤其是对大公司来说。但它也带来了很多传统虚拟机所没有的新技术问题!管理大量分布式服务变得非常具有挑战性,从而催生了“云原生项目动物园”。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"有一些容器就是虚拟机"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"你从实现和使用的角度对容器有了更好的理解,现在可以告诉你真相了。容器不是Linux进程!"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"甚至在技术上讲,Linux容器也不是进程。它们是隔离且受约束的环境,可在其中运行一个或多个进程。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"按照上面的定义,至少有些容器可以使用命名空间和cgroups之外的机制来实现,这就不足为奇了。事实上,有些项目(如Kata)就使用真正的虚拟机作为容器!幸好有了像OCI Runtime Spec、OCI Image Spec或Kubernetes CRI这样的开放标准,基于虚拟机的容器可以在不进行重大调整的情况下被更高级的工具(如containerd和Kubernetes)使用。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"要了解更多,请阅读这篇关于"},{"type":"link","attrs":{"href":"https:\/\/iximiuz.com\/en\/posts\/oci-containers?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhY2Nlc3NfcmVzb3VyY2UiLCJleHAiOjE2MzkxMTg1NjUsImciOiJqV3lnUHlDZDNjUGczNkg5IiwiaWF0IjoxNjM5MTE4MjY1LCJ1c2VySWQiOjcwMDUxODA5fQ.hS4YtRu-vD6UN_s5o3S9DbHAbW3g50WiID1nP4x-0ag","title":null,"type":null},"content":[{"type":"text","text":"OCI运行时规范如何定义标准容器"}]},{"type":"text","text":"的文章:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/b3\/cd\/b3257aa3afbb662df5dc7548cca801cd.png","alt":null,"title":"","style":[{"key":"width","value":"100%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"结论"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"只通过Docker或Kubernetes等高级工具无法真正了解容器。这个领域很复杂,只从一个方向了解它会留下太多的盲点。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我认为更好的方法是从更广泛的生态系统开始,将其分解到各个层面,然后利用在每一步中获得的知识,从底层开始逐个击破:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"容器运行时——Linux命名空间和cgroups。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"容器镜像——为什么以及如何。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"容器管理器——让容器在单台主机上共存。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"容器编配器——将多个主机组合成一个集群。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"容器标准——泛化容器知识。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"原文链接:"},{"type":"link","attrs":{"href":"https:\/\/iximiuz.com\/en\/posts\/container-learning-path\/?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhY2Nlc3NfcmVzb3VyY2UiLCJleHAiOjE2MzkxMTg1NjUsImciOiJqV3lnUHlDZDNjUGczNkg5IiwiaWF0IjoxNjM5MTE4MjY1LCJ1c2VySWQiOjcwMDUxODA5fQ.hS4YtRu-vD6UN_s5o3S9DbHAbW3g50WiID1nP4x-0ag","title":null,"type":null},"content":[{"type":"text","text":"https:\/\/iximiuz.com\/en\/posts\/container-learning-path\/"}]}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章