容器本质

一个“容器”,实际上是一个由 Linux Namespace、Linux Cgroups 和 rootfs 三种技术构建出来的进程的隔离环境。

从这个结构中我们不难看出,一个正在运行的 Linux 容器,其实可以被“一分为二”地看待:

  1. 一组联合挂载在 /var/lib/docker/aufs/mnt 上的 rootfs,这一部分我们称为“容器镜像”(Container Image),是容器的静态视图;

  2. 一个由 Namespace+Cgroups 构成的隔离环境,这一部分我们称为“容器运行时”(Container Runtime),是容器的动态视图。

更进一步地说,作为一名开发者,我并不关心容器运行时的差异。因为,在整个“开发 - 测试 - 发布”的流程中,真正承载着容器信息进行传递的,是容器镜像,而不是容器运行时。

Kubernetes 项目要解决的问题是什么?

编排?调度?容器云?还是集群管理?

实际上,这个问题到目前为止都没有固定的答案。因为在不同的发展阶段,Kubernetes 需要着重解决的问题是不同的。

但是,对于大多数用户来说,他们希望 Kubernetes 项目带来的体验是确定的:现在我有了应用的容器镜像,请帮我在一个给定的集群上把这个应用运行起来。

更进一步地说,我还希望 Kubernetes 能给我提供路由网关、水平扩展、监控、备份、灾难恢复等一系列运维能力。

Kubernetes 项目的架构

我们可以看到,Kubernetes 项目的架构,跟它的原型项目 Borg 非常类似,都由 Master 和 Node 两种节点组成,而这两种角色分别对应着控制节点和计算节点。

其中,控制节点,即 Master 节点,由三个紧密协作的独立组件组合而成,它们分别是

负责 API 服务的 kube-apiserver、

负责调度的 kube-scheduler,

以及负责容器编排的 kube-controller-manager。

整个集群的持久化数据,则由 kube-apiserver 处理后保存在 Ectd 中。

而计算节点上最核心的部分,则是一个叫作 kubelet 的组件。

在 Kubernetes 项目中,kubelet 主要负责同容器运行时(比如 Docker 项目)打交道。而这个交互所依赖的,是一个称作 CRI(Container Runtime Interface)的远程调用接口,这个接口定义了容器运行时的各项核心操作,比如:启动一个容器需要的所有参数。

这也是为何,Kubernetes 项目并不关心你部署的是什么容器运行时、使用的什么技术实现,只要你的这个容器运行时能够运行标准的容器镜像,它就可以通过实现 CRI 接入到 Kubernetes 项目当中。

而具体的容器运行时,比如 Docker 项目,则一般通过 OCI 这个容器运行时规范同底层的 Linux 操作系统进行交互,即:把 CRI 请求翻译成对 Linux 操作系统的调用(操作 Linux Namespace 和 Cgroups 等)。

此外,kubelet 还通过 gRPC 协议同一个叫作 Device Plugin 的插件进行交互。这个插件,是 Kubernetes 项目用来管理 GPU 等宿主机物理设备的主要组件,也是基于 Kubernetes 项目进行机器学习训练、高性能作业支持等工作必须关注的功能。

kubelet 的另一个重要功能,则是调用网络插件和存储插件为容器配置网络和持久化存储。这两个插件与 kubelet 进行交互的接口,分别是 CNI(Container Networking Interface)和 CSI(Container Storage Interface)。

可以说,kubelet 完全就是为了实现 Kubernetes 项目对容器的管理能力而重新实现的一个组件

Borg 对于 Kubernetes 项目的指导作用又体现在哪里呢?

答案是,Master 节点。

虽然在 Master 节点的实现细节上 Borg 项目与 Kubernetes 项目不尽相同,但它们的出发点却高度一致,即:如何编排、管理、调度用户提交的作业?

所以,Borg 项目完全可以把 Docker 镜像看做是一种新的应用打包方式。这样,Borg 团队过去在大规模作业管理与编排上的经验就可以直接“套”在 Kubernetes 项目上了。

这些经验最主要的表现就是,从一开始,Kubernetes 项目就没有像同时期的各种“容器云”项目那样,把 Docker 作为整个架构的核心,而仅仅把它作为最底层的一个容器运行时实现。

而 Kubernetes 项目要着重解决的问题,则来自于 Borg 的研究人员在论文中提到的一个非常重要的观点:

运行在大规模集群中的各种任务之间,实际上存在着各种各样的关系。这些关系的处理,才是作业编排和管理系统最困难的地方。

事实也正是如此。

其实,这种任务与任务之间的关系,在我们平常的各种技术场景中随处可见。比如,一个 Web 应用与数据库之间的访问关系,一个负载均衡器和它的后端服务之间的代理关系,一个门户应用与授权组件之间的调用关系。

更进一步地说,同属于一个服务单位的不同功能之间,也完全可能存在这样的关系。比如,一个 Web 应用与日志搜集组件之间的文件交换关系。

而在容器技术普及之前,传统虚拟机环境对这种关系的处理方法都是比较“粗粒度”的。你会经常发现很多功能并不相关的应用被一股脑儿地部署在同一台虚拟机中,只是因为它们之间偶尔会互相发起几个 HTTP 请求。

更常见的情况则是,一个应用被部署在虚拟机里之后,你还得手动维护很多跟它协作的守护进程(Daemon),用来处理它的日志搜集、灾难恢复、数据备份等辅助工作。

但容器技术出现以后,你就不难发现,在“功能单位”的划分上,容器有着独一无二的“细粒度”优势:毕竟容器的本质,只是一个进程而已。

也就是说,只要你愿意,那些原先拥挤在同一个虚拟机里的各个应用、组件、守护进程,都可以被分别做成镜像,然后运行在一个个专属的容器中。它们之间互不干涉,拥有各自的资源配额,可以被调度在整个集群里的任何一台机器上。而这,正是一个 PaaS 系统最理想的工作状态,也是所谓“微服务”思想得以落地的先决条件。

当然,如果只做到“封装微服务、调度单容器”这一层次,Docker Swarm 项目就已经绰绰有余了。如果再加上 Compose 项目,你甚至还具备了处理一些简单依赖关系的能力,比如:一个“Web 容器”和它要访问的数据库“DB 容器”。

在 Compose 项目中,你可以为这样的两个容器定义一个“link”,而 Docker 项目则会负责维护这个“link”关系,其具体做法是:Docker 会在 Web 容器中,将 DB 容器的 IP 地址、端口等信息以环境变量的方式注入进去,供应用进程使用,

    DB_NAME=/web/dbDB_PORT=tcp://172.17.0.5:5432DB_PORT_5432_TCP=tcp://172.17.0.5:5432DB_PORT_5432_TCP_PROTO=tcpDB_PORT_5432_TCP_PORT=5432DB_PORT_5432_TCP_ADDR=172.17.0.5

而当 DB 容器发生变化时(比如,镜像更新,被迁移到其他宿主机上等等),这些环境变量的值会由 Docker 项目自动更新。这就是平台项目自动地处理容器间关系的典型例子。

可是,如果我们现在的需求是,要求这个项目能够处理前面提到的所有类型的关系,甚至还要能够支持未来可能出现的更多种类的关系呢?

这时,“link”这种单独针对一种案例设计的解决方案就太过简单了。如果你做过架构方面的工作,就会深有感触:一旦要追求项目的普适性,那就一定要从顶层开始做好设计。

所以,Kubernetes 项目最主要的设计思想是,从更宏观的角度,以统一的方式来定义任务之间的各种关系,并且为将来支持更多种类的关系留有余地。

比如,Kubernetes 项目对容器间的“访问”进行了分类,首先总结出了一类非常常见的“紧密交互”的关系,即:这些应用之间需要非常频繁的交互和访问;又或者,它们会直接通过本地文件进行信息交换。

围绕着容器和 Pod 不断向真实的技术场景扩展,我们就能够摸索出一幅如下所示的 Kubernetes 项目核心功能的“全景图”。

Kubernetes 项目核心功能的“全景图”

在 Kubernetes 项目中,我们所推崇的使用方法是:

  • 首先,通过一个“编排对象”,比如 Pod、Job、CronJob 等,来描述你试图管理的应用;
  • 然后,再为它定义一些“服务对象”,比如 Service、Secret、Horizontal Pod Autoscaler(自动水平扩展器)等。这些对象,会负责具体的平台级功能。

这种使用方法,就是所谓的“声明式 API”。这种 API 对应的“编排对象”和“服务对象”,都是 Kubernetes 项目中的 API 对象(API Object)。

过去很多的集群管理项目(比如 Yarn、Mesos,以及 Swarm)所擅长的,都是把一个容器,按照某种规则,放置在某个最佳节点上运行起来。这种功能,我们称为“调度”。

而 Kubernetes 项目所擅长的,是按照用户的意愿和整个系统的规则,完全自动化地处理好容器之间的各种关系。这种功能,就是我们经常听到的一个概念:编排。

所以说,Kubernetes 项目的本质,是为用户提供一个具有普遍意义的容器编排工具。

深入剖析Kubernetes:容器编排与 Kubernetes 核心特性剖析相关推荐

  1. 容器编排技术 -- Kubernetes 联邦 Deployment

    容器编排技术 -- Kubernetes 联邦 Deployment 1 Before you begin 2 创建联邦 Deployment 2.1 在底层集群中分布副本 3 更新联邦 Deploy ...

  2. 容器编排技术 -- Kubernetes Volume

    容器编排技术 -- Kubernetes Volume 1 背景 2 Volume 类型 2.1 emptyDir 2.2 hostPath 2.3 gcePersistentDisk 2.4 aws ...

  3. 容器编排技术 -- Kubernetes Labels 和 Selectors

    容器编排技术 -- Kubernetes Labels 和 Selectors 1 Motivation 2 语法和字符集 3 Labels选择器 3.1 Equality-based require ...

  4. 容器编排技术 -- Kubernetes从零开始搭建自定义集群

    容器编排技术 -- Kubernetes从零开始搭建自定义集群 1 设计和准备 1.1 学习 1.2 Cloud Provider 1.3 节点 1.4 网络 1.4.1 网络连接 1.4.2 网络策 ...

  5. 容器编排技术 -- Kubernetes 架构

    容器编排技术 -- Kubernetes 架构 1 Borg简介 2 Kubernetes架构 2.1 分层架构 Kubernetes最初源于谷歌内部的Borg,提供了面向应用的容器集群部署和管理系统 ...

  6. 容器编排技术 -- Kubernetes 设计理念

    容器编排技术 -- Kubernetes 设计理念 1 Kubernetes 设计理念 1.1 Kubernetes设计理念与分布式系统 1.2 API设计原则 1.3 控制机制设计原则 2 Kube ...

  7. 容器编排技术 -- kubernetes设计理念

    容器编排技术 -- kubernetes设计理念 Kubernetes设计理念与分布式系统 分析和理解Kubernetes的设计理念可以使我们更深入地了解Kubernetes系统,更好地利用它管理分布 ...

  8. 容器编排技术 -- Kubernetes设计架构

    容器编排技术 -- Kubernetes设计架构 Kubernetes集群包含有节点代理kubelet和Master组件(APIs, scheduler, etc),一切都基于分布式的存储系统.下面这 ...

  9. 容器编排技术 -- Kubernetes入门概述

    容器编排技术 -- Kubernetes入门概述 简介 Kubernetes是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单并且高效(powe ...

  10. 容器编排技术 -- Kubernetes StatefulSet基本使用

    容器编排技术 -- Kubernetes StatefulSet基本使用 1 Objectives 2 Before you begin 2.1 顺序创建 Pod 3 Pods in a Statef ...

最新文章

  1. c语言如何判断数据是否符合正态分布_如何判断机器学习数据集是否是线性的?...
  2. 向io设备发出中断请求_人们常说的计算机设备管理是什么,深入解读计算机设备管理...
  3. json 格式化工具_如何在命令行中优雅地处理JSON
  4. 关于.c和.h 和定义变量的问题
  5. android 4.4 keyfactory.getinstance 报错_Android实际开发bug大总结
  6. 基于JAVA+SpringMVC+Mybatis+MYSQL的员工事物管理系统
  7. python查函数用法语句_Python-17 (函数的基本使用)
  8. 181202每日一句
  9. FSG压缩壳和ImportREC的使用 - 脱壳篇05
  10. Intellij IDEA中修改Maven项目的项目名称
  11. JDBC实现多条件查询万能解决思路
  12. matlab 打开xml文件怎么打开方式,导入 XML 文档
  13. [编程题] 头条校招
  14. 总结前端好用的ui框架,做开发非常的奈斯,总有一款你喜欢。
  15. 腾讯Java一面失利,四月凭借这份offer,直接进厂
  16. continue用法(continue用法总结)
  17. Linux使用tc模拟网络延迟和丢包
  18. rust开发环境_Rust开发环境搭建
  19. Linux中的软件管理(一)配置本地yum源及yum命令详解
  20. Winscp连接Ubuntu

热门文章

  1. 【BUAA_CO_LAB】计组p3p4碎碎念
  2. android+p手势操作,手势操作哪家强:Android P对比iPhone X
  3. 渗透测试工具实战技巧合集
  4. Lenovo GTX960M 配置CUDA
  5. 什么是PCB抄板?主要抄板软件有哪些?
  6. 给20块钱买可乐,每瓶可乐3块钱,喝完之后退瓶子可以换回1块钱,问最多可以喝到多少瓶可乐。
  7. [Swift]LeetCode41. 缺失的第一个正数 | First Missing Positive
  8. 于的繁体字有几种写法_处字的繁体字书法作品图片
  9. 微信中域名链接被封如何解决
  10. bzoj 3036: 绿豆蛙的归宿