写点什么

自下而上学习容器

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

    阅读完需:约 12 分钟

自下而上学习容器

AI 大模型超全落地场景&金融应用实践,8 月 16 - 19 日 FCon x AICon 大会联诀来袭、干货翻倍!

我从 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 容器越来越流行,越是小巧的容器出现安全漏洞的可能性就越少。


我在这篇中介绍了如何创建一个只包含Go二进制文件的容器



使用 dive 查看 scratch 镜像


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


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


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


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


单宿主机上的容器管理器


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


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


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


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


这篇文章介绍了如何在命令行中使用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)使用。


要了解更多,请阅读这篇关于OCI运行时规范如何定义标准容器的文章:



结论


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


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


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

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

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

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

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


原文链接:https://iximiuz.com/en/posts/container-learning-path/

2021-12-13 19:477945

评论 1 条评论

发布
用户头像
这个词的翻译是不是有问题

图像

2022-04-01 10:24
回复
没有更多了
发现更多内容

Bootstrap.yml的作用

Rubble

4月日更 4月月更

ETCD 安全模式

爱好编程进阶

Java 面试 后端开发

Flink on Yarn三部曲之二:部署和设置

爱好编程进阶

Java 面试 后端开发

HDU-3038-How Many Answers Are Wrong【 带权并查集 】题解

爱好编程进阶

Java 面试 后端开发

线上活动| 阿里云、亚马逊云与MongoDB的大佬带你来涨知识!

MongoDB中文社区

mongodb

linux之dos2unix命令

入门小站

Linux

在线CSV转HTMLTable工具

入门小站

工具

Canal 如何实现数据库库事务的一致性

爱好编程进阶

Java 面试 后端开发

Element-UI 要怎么学?官方文档!

爱好编程进阶

Java 面试 后端开发

在线ASCII流程图编辑器工具

入门小站

工具

英特尔公布可持续发展新目标,到2040 年实现温室气体净零排放

科技新消息

以海洋为主题的元宇宙Aquqnee,为GameFi带来新的标杆

BlockChain先知

ElasticSearch java API - 聚合查询

爱好编程进阶

Java 面试 后端开发

InnoDB 和 MyISAM 的数据分布是什么样的?

爱好编程进阶

Java 面试 后端开发

【OB实践】意出望外的一次相遇|利楚初探 OceanBase

OceanBase 数据库

oceanbase

中兴通讯加入星策开源社区 携手推动企业智能化转型建设

星策开源社区

人工智能 机器学习 开源社区 企业转型

生产到一半改工艺生产为另一个产品的业务方案探讨

秋去冬来春未远

生产改单 生产执行 生产拆单

漏洞挖掘之Spring Cloud注入漏洞

网络安全学海

网络安全 信息安全 渗透测试 WEB安全 漏洞挖掘

首届全球基础软件创新大会明天开幕!

OpenAnolis小助手

开源 操作系统 龙蜥社区 国产 基础软件创新大会

英特尔承诺到2040 年实现温室气体净零排放

科技新消息

GitHub上已获赞百万!阿里架构师最新发布的图解网络协议文档(2021版)开源分享

爱好编程进阶

Java 面试 后端开发

干掉丑陋的swagger,堪称开发者的瑞士军刀!

Liam

后端 Jmeter Postman 后端开发 swagger

虎符交易所「虎年玩虎符」活动攻略 三天赠送三万美金

区块链前沿News

虎符交易所

为什么要对我们的sql进行优化

乌龟哥哥

4月月更

1-4 云商城项目工程搭建

爱好编程进阶

Java 面试 后端开发

2022年最新面试手册,在Github爆火,96人拿下大厂offer

爱好编程进阶

Java 面试 后端开发

TASKCTL 调度高可用架构服务与安装

敏捷调度TASKCTL

kettle 批量任务 调度引擎 ETL 调度任务

英特尔最新计划:到2040 年实现温室气体净零排放

科技新消息

亚信科技两方案入围工信部“数字技术融合创新解决方案”评选

亚信AntDB数据库

AntDB #数据库 奖项

Elasticsearch的安装和基本使用

爱好编程进阶

Java 面试 后端开发

火山引擎支持 Pico 完成业界首场 8K 3D 实时互动 VR 演唱会

字节跳动视频云技术团队

音视频 火山引擎 视频云 VR开发应用

自下而上学习容器_架构_iximiuz_InfoQ精选文章