Kubernetes 名字源自于希腊语,意为「舵手」或「飞行员」,前身是 Google 内部运行多年的集群管理系统 Borg。2014 年 6 月使用 Go 语言重写并开源。

Kuberntes 与容器引擎之间的关系

Kubernetes 的成功与 Docker 的成功并不相同。Docker 靠的是优秀的理念,以一个「好点子」引爆了一个时代。Kubernetes 的成功不仅有 Google 深厚的技术功底作为支撑,而且有领先时代的设计理念,更加关键的是 Kubernetes 的出现符合所有云计算大厂的切身利益,有着业界巨头不遗余力的广泛支持,所以它的成功是一种必然。

容器构建系统

自从 Docker 提出的 「以封装应用为中心」 的容器发展理念成功取代 LXC 的 「以封装系统为中心」 的理念以后,一个容器封装一个单进程应用已经成为被广泛认可的最佳实践。

然而单体时代过去之后,分布式系统里应用的概念已不再等同于进程,此时的应用需要多个进程共同协作,通过集群的形式对外提供服务,而以虚拟化方法实现这个目标的过程就被称为 容器编排 (Container Orchestration)。

Kubernetes 考虑到了应用程序容器的大部分操作需求,主要包括:

  • 容器部署;
  • 持久化存储;
  • 容器监控;
  • 计算资源管理;
  • 自动扩展;
  • 高可用(集群联邦)。

Kubernetes 组件

Kubernetes 集群包含两大组件:

  • Master 组件:Kubernetes 的核心,控制和调度集群中的所有活动。
  • 节点组件:运行容器的工作节点。

Master 组件

Master 组件包括 API 服务器(API server)、控制器管理器(Controller Manager)、调度器(Scheduler)和 etcd。所有组件都可以在集群中的任何节点上运行。

  • 客户端使用 kubectl 向API服务器发送请求;API服务器响应该请求,在 etcd 中推送和提取相应的对象信息。
  • 调度器(Scheduler)决定应该分配哪个节点来执行任务(例如运行 Pod)。
  • 控制器管理器 Controller Manager 监控正在运行的任务,当状态异常时做出响应。

节点组件

每个节点上都需要安装和运行以下组件,记录 Pod 的运行时状态,并报告给Master。

k8s节点组件

Pod

Pod 的概念在容器正式出现之前的 Borg 系统中就已经存在了。从 Google 发表的 Large-Scale Cluster Management at Google with Borg 可以看出,Kubernetes 时代的 Pod 整合了 Borg 时代的「Prod」(Production Task 的缩写)与 「Non-Prod」的职能。

扮演容器组的角色,满足容器共享名称空间的需求,是 Pod 的两大最基本职责之一。

多个容器位于同一个 Pod 的特殊关系,它们将默认共享如下内容:

  • UTS 名称空间:所有容器都有相同的主机名和域名。
  • 网络名称空间:所有容器都共享一样的网卡、网络栈、IP 地址等。因此,同一个 Pod 中不同容器占用的端口不能冲突。
  • IPC 名称空间:所有容器都可以通过信号量或者 POSIX 共享内存等方式通信。
  • 时间名称空间:所有容器都共享相同的系统时间。

同一个 Pod 的容器,只有 PID 名称空间和文件名称空间默认是隔离的。

只有关系非常密切的(超亲密)的容器才会放到同一个 Pod 中。对于普通容器之间的协作,一般通过网络;普通亲密关系的容器协作,一般则调度到同一个集群节点上。

Pod 内部多个容器共享 UTS、IPC、网络等名称空间是通过一个名为 Infra Container 的容器来实现的,这个容器是整个 Pod 中第一个启动的容器,只有几百 KB 字节大小(代码只有很短的几十行)。
由于 Infra Container 的代码除了注册 SIGINTSIGTERMSIGCHLD 等信号的处理器外,就只是一个以 pause() 方法为循环体的无限循环,永远处于 Pause 状态,所以也常被称为 「Pause Container」。

Pod 的另外一个基本职责是实现原子性调度 。如果容器编排不跨越集群节点(单台机器),是否具有原子性并不重要。但是如果容器跨机器调度,如果容器在不同机器上,那么两个之间本身就是物理隔离的,依靠网络连接,这时候,谈名称空间共享、cgroups 配额都没有任何意义。

计算资源

Pod 是隔离与调度的基本单位 ,也是我们接触的第一种 Kubernetes 资源。Kubernetes 将一切皆视为资源 ,不同资源之间依靠层级关系相互组合、协作的这个思想是贯穿 Kubernetes 整个系统的两大核心设计理念之一,

Kubernetes 资源

Kubernetes 对象是集群中的各类资源,这些对象的信息存储在 etcd 中,它们代表着集群的状态。我们编写一个对象规约,然后通过 kubectl 将规约发送到 API 服务器, Kubernetes 将尝试实现目标状态 (不提倡像平常编程那样去调用某个或某一组方法来达成目的,而是要通过描述清楚这些资源的期望状态,用函数式思想去考虑而不是命令式的思想) ,并更新对象信息。

与资源相对应,只要是实际状态有可能发生变化的资源对象,通常都会由对应的控制器进行追踪。

资源管理

(TODO)

Kubernetes 网络

(TODO)

小结

  • Kubernetes 被诟病最多的就是复杂,自诞生之日起就以陡峭的学习曲线而闻名。

参考资料

  1. 周志明.凤凰架构:构建可靠的大型分布式系统[M].2021
  2. [日] Hideto Saito,[加] Hui-Chuan Chloe Lee,Cheng-Yang Wu著.基于Kubernetes的DevOps实践:容器加速软件交付.电子工业出版社.2019