【fcon】聚焦金融行业在数智化的全面革新,一线的金融数智化实践干货
写点什么

自下而上学习容器-金马国际

  • 2021-12-13
  • 本文字数:3545 字

    阅读完需:约 12 分钟

自下而上学习容器

6 月 17 日,极客时间正式上线,10 周掌握企业级 agents 从设计、开发到部署全流程。

我从 2015 年开始使用容器,我对容器最初的理解就是把它们看成是轻量级的虚拟机,只是启动时间比虚拟机快了很多。脑子里有了这样的概念,就很容易看懂网上那些关于如何将 python 或 node 应用程序装入容器的教程。但很快,我意识到仅仅将容器看成是轻量级的虚拟机有点跳过简单化了,这导致我无法对以下这些问题做出判断:


  • 容器可以做什么以及不可以做什么;

  • 哪些是使用容器的最佳实践以及哪些不是;

  • 哪些东西放在容器是安全的以及哪些不是。


既然“容器就是虚拟机”这种理解有失偏颇,我就开始深入探究,看看容器到底是什么,而 docker 无疑是最好的切入点。问题是,docker 是一个可以用来做各种各样事情的庞然大物,而运行它的命令又如此简单(比如 docker run nginx),很容易就蒙蔽了我们。与 docker 相关的资料有很多,它们要么是太过浅显的教程,要么太多艰深,新手根本就看不懂。


于是,我花了一些时间,为读者铺平了学习容器的道路。


多年来,我尝试从不同的角度探究,终于找到了一条适合我的学习路径。不久前,我在推特上分享了我的学习路径,引起了很多人的共鸣。


本文并不打算一次性解释完所有有关容器的东西。相反,它是我多年来对这个领域探究的一道“前菜”。它介绍了我的学习路径,你可以顺着这条路径,再去阅读其他更加深入介绍容器的文章。


掌握容器知识不是一项简单的任务,所以慢慢来,不要跳过实操的部分!


容器学习路径


我发现按照下面这样的顺序来学习容器非常有效:


  • linux 容器——学习底层的实现细节;

  • 容器镜像——了解什么是镜像以及为什么需要镜像;

  • 容器管理器——了解 docker 是如何管理单台主机上的容器的;

  • 容器编配器——了解 kubernetes 是如何管理集群里的容器的;

  • 非 linux 容器——了解其他容器实现,打开更大的视野。


容器不是虚拟机


容器是一种隔离(命名空间)且受约束(通过 cgroups、capabilities、seccomp)的进程。


上面的这个解释非常有助于我理解什么是容器。当然,这个解释并非绝对准确,当你读到这篇文章的末尾你就会知道,但在刚开始学习容器时,这样的解释是很合适的。



要在 linux 上启动一个进程,需要 fork/exec 它。但要启动一个容器化的进程,要先创建命名空间、配置 cgroups,等等。或者,换句话说,为进程准备一个箱子,让进程在箱子里运行。容器运行时就是一种用来创建这种箱子的工具。容器运行时知道怎样准备好箱子,然后在箱子里启动一个容器化的进程。又因为大多数运行时都遵循常用的规范,容器就成为一种标准的工作负载单元。


使用最广的容器运行时是 runc。runc 是一种普通的命令行工具,所以可以在没有 docker 或其他高级容器软件的情况下直接使用它。



runc 启动一个容器化进程的过程


我对此感到兴奋万分,甚至还写了一系列关于(shim)的文章。垫片是指底层容器运行时(如 runc)和高级容器管理器(如 containerd)之间的一种软件。要做好垫片,需要对运行时了如指掌,所以这一系列文章先从开始。



容器运行时垫片

运行容器不一定需要镜像


不过,构建镜像需要容器。


对于熟悉 runc 是如何启动容器的人来说,他们都知道镜像并非是必需的。要运行一个容器,运行时需要一个 bundle,其中包括:


  • 一个 config.json 文件,里面包含了与容器有关的参数(例如可执行文件的路径、环境变量,等等);

  • 包含可执行文件及其相关文件(如果有的话)的目录。


通常,bundle 的目录结构与 linux 发行版的文件结构类似(/var、/usr、/lib、/etc,等等)。当 runc 启动这样的一个容器,运行在容器中的进程就获得了一个根文件系统,看起来与 linux(比如 debian、centos 或 alpine)很像。


但这种文件结构并非是强制性的。现在,所谓的 scratch 或 distroless 容器越来越流行,越是小巧的容器出现安全漏洞的可能性就越少。


我在这篇中介绍了。



使用 dive 查看 scratch 镜像


既然运行容器不一定需要镜像,那我们为什么还要有容器镜像?


当每一个容器都包含根文件系统的一个数兆字节那么大的拷贝副本时,所需的磁盘空间就会急剧增加。因此,镜像的存在是为了有效地解决存储和发行问题。对这个问题感兴趣的可以阅读这篇。


你有没有想过镜像是如何构建出来的?


docker 所推广的工作流程试图让你认为镜像才是主要的,容器次之。在执行 docker run 命令时,你需要指定一个镜像才能运行容器。但我们知道,严格来说,事情并没有这么简单。实际上,你需要(临时)运行容器来构建镜像!想知道为什么,请阅读这篇。


单宿主机上的容器管理器


在现实世界中,我们发明了集装箱是为了增加一艘船可以装载的物品数量,类似的,容器是为了提高服务器的资源利用率。


一个典型的服务器现在运行数十或数百个容器。因此,它们需要有效地共存在一台服务器上。单个容器运行时关注的是单个容器的生命周期,而容器管理器关注的是在单台主机上共存的多个容器。


容器管理器的主要职责包括镜像的拉取、解包、配置容器间网络、存储容器日志,等等。


在这方面,你可能认为 docker 就是一个很好的例子。但我发现 containerd 是一个更具代表性的例子。与 runc 一样,containerd 在一开始只是 docker 的一个组件,后来被提取到一个独立的项目中。containerd 可以使用 runc 或任何实现了 containerd-shim 接口的运行时。最酷的是,你可以像使用 docker 一样使用 containerd 来轻松地运行容器。


这篇文章介绍了——这是一个很好的练习,让你更接近实际的容器是什么样子的。


如果你想了解更多关于容器管理器内部的知识,请看这篇文章。它介绍了:


containerd 与 docker


现在,我们准备好要了解 docker 了!如果我们忽略(现在已弃用)swarm,那么 docker 包含如下这些:


  • dockerd——位于 containerd 守护进程前面的一个高级守护进程;

  • docker——一个命令行客户端,用于与 dockerd 交互。



docker 的分层架构


在我看来,docker 目前的主要任务是让容器工作流变得更友好。为了简化开发人员的工作,docker 将所有主要容器用例整合到一个工具中:


  • 构建/拉取/推送/扫描图像;

  • 启动/暂停/检查/杀死容器;

  • 创建网络/重定向端口;

  • 挂载/卸载/删除卷;

  • 其他。


但是到了 2021 年,几乎每个用例都被写成了一个定制的软件(如 podman、buildah、skopeo、kaniko,等等),以便提供更好的替代金马国际的解决方案。


多宿主容器编配器


在单台主机上协调运行的容器已经很难了,在多个主机之间协调容器就更困难了。还记得 docker swarm 吗?docker 在加入多主机容器编配特性时就已经相当可怕了,因为给已有的守护进程带来了更多的责任……


忽略守护进程数量不断膨胀这个问题,docker swarm 看起来还是不错的。但另一种编配器赢得了比赛——kubernetes!所以,大约从 2020 年开始,docker swarm 就过时了,我们每周都会听到几个新出现的“古希腊”词汇。


kubernetes 将多个服务器(节点)连接到一个集群中,每个节点都有一个叫做 kubelet 的本地代理。kubelet 负责启动 pod(一组容器),但并不是它自己做这些事情。过去,它使用 dockerd,但现在这种方法已被弃用,取而代之的是更通用的容器运行时接口(cri)。



kubernetes 可以使用 containerd、cri-o 或其他 cri 运行时


容器编配器需要完成很多任务。


  • 如何将容器按照高级原语分组(pods、replicasets 等)?

  • 如何将运行容器的节点连接到一个公共网络中?

  • 如何提供服务发现?

  • 其他。


kubernetes 和其他编配器(如 nomad 或 aws ecs)可以帮助开发团队更容易地创建独立的服务。它帮助解决了很多管理上的问题,尤其是对大公司来说。但它也带来了很多传统虚拟机所没有的新技术问题!管理大量分布式服务变得非常具有挑战性,从而催生了“云原生项目动物园”。


有一些容器就是虚拟机


你从实现和使用的角度对容器有了更好的理解,现在可以告诉你真相了。容器不是 linux 进程!


甚至在技术上讲,linux 容器也不是进程。它们是隔离且受约束的环境,可在其中运行一个或多个进程。


按照上面的定义,至少有些容器可以使用命名空间和 cgroups 之外的机制来实现,这就不足为奇了。事实上,有些项目(如 kata)就使用真正的虚拟机作为容器!幸好有了像 oci runtime spec、oci image spec 或 kubernetes cri 这样的开放标准,基于虚拟机的容器可以在不进行重大调整的情况下被更高级的工具(如 containerd 和 kubernetes)使用。


要了解更多,请阅读这篇关于的文章:



结论


只通过 docker 或 kubernetes 等高级工具无法真正了解容器。这个领域很复杂,只从一个方向了解它会留下太多的盲点。


我认为更好的方法是从更广泛的生态系统开始,将其分解到各个层面,然后利用在每一步中获得的知识,从底层开始逐个击破:


  • 容器运行时——linux 命名空间和 cgroups。

  • 容器镜像——为什么以及如何。

  • 容器管理器——让容器在单台主机上共存。

  • 容器编配器——将多个主机组合成一个集群。

  • 容器标准——泛化容器知识。


原文链接:

2021-12-13 19:477889

评论 1 条评论

发布
这个词的翻译是不是有问题

图像

2022-04-01 10:24
回复
没有更多了
  • 事实上,stl 中每个容器的特性,和它底层的实现机制密切相关,deque 自然也不例外。《c stl deque容器》一节中提到,deque 容器擅长在序列的头部和尾部添加或删除元素。本节将介绍 deque 容器的底层实现机制,探究其拥有此特点的原因。

    2022-09-09

  • aws在其well-architected框架添加了一个新的容器透镜。

  • }

    2022-05-16

  • 在之前的笔记中我们初步了解了一下容器的技术,并在linux系统中安装了当前最流行的容器docker。那到底什么是容器呢,我的理解是,它就像一个个杯子,每个杯子中的装满了各个口味的饮料,为了不和其他口味的饮料产生混合,这里的杯子就是容器。

    2022-06-28

  • 这节课,我会带你从 0 开始认识作为云原生基石的容器镜像,让你在实践中理解镜像和容器的概念,也在这个过程中构建你的第一个容器镜像。

    2022-12-12

  • 这节课,我们继续延伸上一节课程的内容,把之前构建的容器镜像部署到 k8s 集群中

    2022-12-12

  • 2022-05-17

  • 在之前的笔记中我们初步了解了一下容器的技术,并在linux系统中安装了当前最流行的容器docker。那到底什么是容器呢,我的理解是,它就像一个个杯子,每个杯子中的装满了各个口味的饮料,为了不和其他口味的饮料产生混合,这里的杯子就是容器。

    2022-06-26

  • 今天要学习的数据结构是集合容器。像其他语言一样,容器例如数组、列表,是非常重要的数据结构。其实,只要是把某些特定的数据封装在某个数据结构中,这个数据结构就能称为容器。例如 option 封装了存在(some)或不存在(none)的容器。

    2022-08-20

  • 一说到容器,可能就是鼎鼎大名的 c stl。在别的编程语言里面也现成的容器可用,单单唯独 c 语言没有像样的容器可用。在闲的蛋疼之际,我为 c 语言实现了一套容器接口,当然不能做到 stl 那么精美绝伦,功能强大,这只为一探容器的究竟.

    2022-06-23

  • 相似的技术可以共存吗?

  • dockr容器

    2021-11-10

  • 这节课,我们一起来学习如何使用 docker compose 来部署多个容器。

    2023-02-07

  • 一文教你学会spring boot使用undertow容器?超级详细,建议收藏

    2023-04-21

  • 在计算机技术日新月异的今天,层出不穷的新技术推动了生产力的发展,也推动了整个社会的进步。软件架构从单体架构到分布式架构,从soa架构到微服务架构,再到服务网格。数据库从 oracle包打天下到 mysql大行其道,再到内存数据库、nosql数据库遍地开花。容器编

    2021-08-19

  • 基础镜像的选择并没有一套固定规则,你需要从多方面,例如业务程序的依赖、可调试性、安全性、体积大小和社区维护等角度来考虑。

    2023-01-11

  • 这节课,我们来看看容器化技术,并利用docker将我们的程序打包为容器。

    2023-02-04

  • 在当今容器化呼声越来越高的场景下,容器云平台呼声也是越来越高,这节课我们就简单了解一下caas。

    2023-01-09

  • 是该领域功能最丰富且使用最广泛的工具之一,已有数百万应用程序在使用它。还有其他替代品,它们提供了独特的用例和功能。

  • java 提供的基础容器都是线程不安全的,如果并发条件下多个线程同时对一个容器中的数据进行操作,可能会导致各种意想不到的错误。

    2022-06-11

发现更多内容
金马国际
网站地图