编者按

过去三年内,Kubernetes 在不断发展,其社区也保持着极高的活跃度。截至目前,有超过2300名贡献者,Kubernetes也在各种生产环境上大规模应用,本文从 KEP的角度分析过去三年内各 SIG 内的主要变动。


由于篇幅较长,文章将分成上下篇进行讲解,本文为下篇,欢迎阅读并留言讨论(点击🔗了解详情:《Kubernetes 这三年不得不说的事(下篇)》)。





V1.14





 
走过了突飞猛进的 2018 年,Kubernetes 在 2019 年终于迎来了第一个大动作:Kubernetes 1.14 版本的正式发布!Kubernetes 本次发布的 1.14 版本,包含了 31 项增强,其中 10 项为 GA,12 项进入 beta 试用阶段,7 个为全新的 alpha 功能。1.14 版本的主题是可扩展性,并且支持更多的业务场景,其中三个主要的功能具备生产可用,一个重要功能进入 beta 试用阶段。总体而言,1.14 版本相比之前的版本更着重于将更多的功能推进到稳定状态,尤其是部分关键功能对于用户来说具有重大的里程碑意义。

结合最近几次版本发布来看,Kubernetes 核心的发展越来越趋于稳定,1.14 版本几乎没有引入大的新特性,而是把重点放在了让已有特性的稳定上。正如许多人会说,Kubernetes 正在变得无聊,事实上放眼整个云原生生态,面向最终用户的各种落地场景,仍有巨大的发展空间,许许多多围绕 Kubernetes 的新项目仍然在如雨后春笋般地涌现,而 K8s 本身一些子项目的动态也开始进入人们的视野,不断地被商业落地。相信 2019 年会是 Kubernetes 和云原生技术面向用户场景开枝散叶的一年。

随本次 Kubernetes 1.14 版本发布的,还有全新的 kubectl 文档及 Logo。社区重写了 kubectl 文档,并重点聚焦使用声明式的资源配置管理资源。目前 kubectl 文档已作为独立的站点上线,地址为: https://kubectl.docs.kubernetes.io。
 

[SIG Storage] 持久化本地存储卷GA

 
KEP:https://github.com/kubernetes/enhancements/blob/master/keps/sig-storage/20190124-local-persistent-volumes.md
 
历经漫长的改进,持久化本地存储卷特性终于在 1.14 版本中达到生产可用。

本地持久卷可以使用 K8s 节点上挂载的本地存储设备作为持久卷的来源。相对于远程磁盘来说,持久化本地存储拥有优越的性能,使用更少的系统开销,更加适合分布式文件系统以及数据库等场景。相比于云盘,本地 SSD 盘比远程磁盘就具有更好的 IO 性能。相比于裸机, 除了性能以外,本地存储通常更加便宜,并且使用它是配置分布式文件系统的必要条件。

虽然本地持久卷特性达到生产可用,但是易用性仍然没有得到显著的改进。用户可以通过两种相对手动的方式来使用持久化本地存储特性:1. 用户手动指定块设备的方式提供本地持久卷;2. 使用 sig-storage-local-static-provisioner 插件静态维护本地卷的生命周期。

根据 Pod 及 PVC 状态自动地维护各节点中本地持久卷的能力,仍然需要较长的时间在社区推进。
 

[SIG Node] 应用就绪状态判断的改进:Pod Readiness Gates (Pod Ready++) GA

 
KEP:https://github.com/kubernetes/enhancements/blob/master/keps/sig-network/0007-pod-ready%2B%2B.md
 
对于 Pod 的状态,Kubernetes 为用户提供了两项判断 Pod 运行情况的能:Readiness(就绪状态) 和 Liveness(存活状态)。一个 Pod 被判断为 Ready(就绪),意味着所有初始化相关的工作已经完成,Pod 可以接收处理外部访问的请求。而 Liveness 则用于判断已就绪的 Pod 是否持续处于正常工作中。

然而在实际使用中,特别是针对大型应用,情况往往比较复杂。由于 K8s 中大量采用的异步机制、以及多种对象关系设计上的解耦,当应用实例数增加/删除, 或者应用版本发生变化触发滚动升级时,系统并不能保证应用相关的 Service,负载均衡器配置总是及时完成刷新。在一些情况下,往往只是新的 Pod 完成自身初始化,系统尚未完成 Endpoint、负载均衡器等外部可达的访问信息刷新,老的 Pod 就立即被删除,最终造成服务不可用。这对用户来说是不可接受的。

Pod Ready++ 的引入正是为了修正 Pod 就绪状态的判断机制——用户可以通过 ReadinessGates 自定义 Pod 就绪的条件(如, 从外部访问入口判断新建的 Pod 开始处理外部请求),当用户自定义的条件以及容器状态都就绪时,kubelet 才会标记 Pod 准备就绪。

在 1.14 版本中,Pod ready++ 特性达到了稳定,用户可以在生产系统中直接使用该特性。需要注意的是:对于用户自定义的就绪条件,一定需要有自定义的控制器配合更新 Pod 状态,否则,Pod 永远不会变成就绪状态。
 

[SIG Scheduling] Pod 优先级与抢占式调度GA

 
KEP:https://github.com/kubernetes/enhancements/blob/master/keps/sig-scheduling/20190131-pod-priority-preemption.md
 
Pod 优先级与抢占可以使 K8s 调度器在集群资源耗尽的情况下优先调度更加重要的 Pod,并且驱逐集群中正在运行的相对不重要的 Pod,为更重要的 Pod 腾出资源。Pod 的重要性通过 PriorityClassName 定义,其中 “system-node-critical” 和 “system-cluster-critical” 是两个特殊的最高优先级的关键词。优先级低的 Pod 在资源不足时,容易首先被驱逐,因而对于重要的 daemonset 或者重要的应用组件,用户可以设置较高的优先级防止被抢占。

要使用优先级与抢占,管理员必须开启 Priority Admission Controller。用户在为 Pod 设置 PriorityClassName 时,必须指向集群中已创建的 PriorityClass 对象,否则 Pod 创建失败。
 
 
Kubernetes 这三年不得不说的事(下篇)
 

[SIG Node] PID Limit 进入beta阶段

 
KEP:https://github.com/kubernetes/enhancements/blob/master/KEPs/sig-node/20190129-pid-limiting.md
 
进程 ID (PID) 是 Linux 主机基本的资源,以往 K8s 没有任何措施限制容器内的进程创建 PID,如果 PID 资源耗尽,即使其他的资源充足,也可能导致主机不稳定。在引入 PID 限制特性后,K8s 管理员可以通过 kubelet 启动参数–pod-max-pids 来设置每个 Pod 最大可启动的进程数目,并通过–system-reserved 和–kube-reserved 两项参数设置系统预留的 PID 数目。这么做的目的一是防止 Pod 因 PID 资源匮乏而不能正常运行,二是隔离 Pod 之间以及 Pod 与 node 之间的 PID 资源。
 



V1.15





 
1.15 版本主要围绕可扩展性展开,北向 API 接口方面 API Machinery SIG 致力于发展 CRD 以提升 API 可扩展性,南向插件集成方面,Storage SIG 和 Node SIG 则分别对 CSI 和设备监控插件可扩展性进行了优化。另外 Kubeadm 对 HA 集群配置也达到 Beta 可用,并发优化了证书管理相关功能。
 

[SIG Node] 提供监控插件框架用于异构硬件监控 GA

 
新版本很好的解决了异构硬件设备监控难题,现在不需要修改 Kubelet 代码就可以实现各种指标(如 GPU、显存利用率等)监控。新版本通过新的监控插件框架将 Kubelet 与设备监控处理逻辑解耦,把监控交给更加专业的设备提供商去做。此外新增的监控指标不需要升级kubelet,而是更新设备监控代理版本即可,很好的解决了以往 Kubelet 代码管理和 K8s 集群运维之间的痛点。
 
Kubernetes 这三年不得不说的事(下篇)


[Scheduling SIG] Scheduler Framework 加强调度器扩展定制能力 Beta

 
KEP:https://github.com/kubernetes/enhancements/blob/master/KEPs/sig-scheduling/20180409-scheduling-framework.md
 
Scheduler Framework 终于在 1.15 迎来了 Alpha 版本。Scheduler Framework 最早在 2018 年初提出,主要是为了解决日益增加的定制化调度需求。Scheduler Framework 在原有的 Priority/Predicates 接口的基础上增加了 reserve ,pre-bind 等十几个接口用于相应前处理及后处理。在 1.15 中,Scheduler Framework 实现 QueueSort, Prebind, Postbind, Reserve, Unreserve 和 Permit 接口,这些接口为后继更多的调度策略提供了基础,比如 gang-scheduling。

然而,出于设计上的延续性考虑,目前 Scheduler Framework 仍以 Pod 为单位进行调度,而计算类(离线)任务调度往往需要考虑工作负载中相关的 Pod 按组进行调度,例如 faire-share。现在的 Scheduler Framework 还不能有效的解决。所幸针对这一能力缺失,社区已经有相应的项目在 Kubernetes 上支持计算类(离线)任务,例如 Volcano ( http://github.com/volcano-sh/volcano )。
 



V1.16





 
美国时间 9 月 18 日,Kubernetes 迎来了 2019 年的第三个新版本 1.16。经过 5 年的发展,Kubernetes 核心的基本功能已相对稳定,具备大规模生产可用水平。但是客户需求往往是多种多样的,社区从很早就意识到这个问题,因而提供了各种接口(CRD、CRI、CSI、CNI 等),希望在保持 Kubernetes 独立的条件下,尽量满足用户差异化的需求,这从 1.15 发布的主要特性也可以看出来。对比分析过去几个版本的特性成熟度,不难发现 Alpha 新特性的占比稳定在 20%~40% 之间。按照社区惯例,当一项全新的功能被添加时,会在特性说明中打上 Alpha 标记。持续稳定甚至小幅上涨的 Alpha 特性占比说明社区仍然在大量开发全新的特性,而不是满足于既有功能的加固。
 

[SIG Instrumentation] CRD GA, 基于OpenAPI的结构模式

 
KEP:https://github.com/kubernetes/enhancements/blob/master/KEPs/sig-api-machinery/20180731-crd-pruning.md
 
CRD 的新开发主题一直都围绕着数据一致性以及提供更加接近 Kubernetes 原生 API 的能力。用户不应该感知到到底是以 CR(Custom Resource)还是以原生的资源对象形式与 Kube APIServer 进行交互。社区目前正迈着大步,计划将在接下来的某个版本中将 CRD 以及 Admission Webhook GA(升级为稳定版本)。

朝着这个方向, 社区重新思考了基于 OpenAPI 的 CRD 验证模式,从 1.15 开始,根据结构模式(Structural Schema)的限制检查每个字段。这基本保证了能够像原生的 API 对象一样提供完整的 CR 校验能力。在 v1beta1 API 中, 非结构模式(non-Structural Schema)仍然保持工作状态。但是任何严格的 CRD 应用程序都应该在可预见的将来迁移到结构模式。
Kubernetes 这三年不得不说的事(下篇)


[SIG Network] ipv4/v6 双栈支持 Alpha

 
KEP:https://github.com/kubernetes/enhancements/blob/master/keps/sig-network/20180612-ipv4-ipv6-dual-stack.md#implementation-plan
 
新版本对 Kubernetes Pod、节点和服务提供 IPv4/IPv6 双栈支持和感知。这为 Kubernetes 集群添加了 IPv4/IPv6 双栈功能,包括:

  • 了解每个 Pod 的多个 IPv4/IPv6 地址分配;

集群之间本地 IPv4-to-IPv4、IPv6-to-IPv6 的通信。
 

[SIG Network] 引入Endpoint切片 Alpha

 
KEP:https://github.com/kubernetes/enhancements/blob/master/KEPs/sig-network/20190603-EndpointSlice-API.md
 
Kubernetes 1.16 版本还包含一项令人兴奋的全新 Alpha 功能:Endpoint 切片。这为 Endpoint 资源提供了一个可伸缩和可扩展的替代方案。在后端,这些资源在 Kubernetes 内部的网络路由中扮演着重要的角色。每个网络 Endpoint 都在这些资源中受到追踪,kube-proxy 利用如上 Endpoint 生成代理规则,允许 Pod 在 Kubernetes 中如此轻松地相互通信。

Endpoint 切片的一个关键目标是为 Kubernetes 服务提供更强大的可扩展性。对于现有 Endpoint资源,单个资源必须包含表示与某项服务相关联的所有 Pod 的网络 Endpoint。随着服务扩展至数千个 Pod,相应的 Endpoint 资源变得非常大。如果简单地对服务添加或删除一个Endpoint 可能带来可观的成本。随着 Endpoint 资源的更新,代码中与该 Endpoint 相关的部分都需要获取一份关于该资源的完整副本。群集中的每个节点运行 kube-proxy 时,需要将副本发送到每个节点。在小范围内,这不是问题,但随着集群变大,影响会变得越来越明显。比如,在一个拥有 5,000 个节点和 1MB Endpoint 对象的集群中,任何更新都会导致大约 5GB 的传输(这足以填满一张DVD光盘)。考虑到 Endpoint 在部署期间频繁滚动更新等事件,这将是一笔巨大的资源浪费。

使用 Endpoint 切片,服务的网络 Endpoint 可以拆分为多个资源,从而显着减少大规模更新所需的数据量。默认情况下,每个 Endpoint 切片最多包含 100 个 Endpoint。例如,我们拥有 20,000 个网络 Endpoint,分布在拥有 5,000 个节点的集群上。利用 Endpoint 切片更新单个 Endpoint 的效率会更高,因为每个 Endpoint 仅包含网络 Endpoint 总数的一小部分。相较于以往将大 Endpoint 对象传输至各个节点的方式,现在我们只需要传输已经变更的小型 Endpoint 切片。实际效果就是,现在更新操作的数据传输量仅相当于以往的约二百分之一。
 
Kubernetes 这三年不得不说的事(下篇)
image.png

Endpoint 切片的第二个主要目标,是提供一种在各种用例中具有高度可扩展性和实用性的资源。Endpoint 切片的一个关键添加还涉及新的拓扑属性。默认情况下,这将填充 Kubernetes 中使用的现有拓扑标签,用以指示 region 与 zone 等属性。当然,这个字段也可以填充自定义标签以及更专业的用例。Endpoint 切片还实现了更大的地址类型灵活性。每个都包含一个地址列表。多地址初始用例同时支持具有 IPv4 和 IPv6 地址的双栈 Endpoint。
 



V1.17






美国时间 12 月 9 日,Kubernetes 迎来了 2019 年的最后一个新版本 1.17。随着Kubernetes的采用率增加, 工作负载, 用户需求和环境的多样性也随之增加。其中许多增强功能可满足大规模, 关键生产环境中用户的需求。Kubernetes指导委员会和社区团体将继续保持平衡, 在为用户提供所需的控制权的同时, 仍保持可适应许多不同组织和工作负载的灵活, 可定制的平台。
 

[SIG Storage] Volume Snapshot 进入 beta

 
KEP:https://github.com/kubernetes/enhancements/blob/master/KEPs/sig-storage/20190709-csi-snapshot.md
 
Kubernetes Volume Snapshot 在 v1.17 中进入 beta。此前,它在 v1.12 中作为 Alpha 引入 Kubernetes,并曾在 v1.13 中迎来重大变化。许多存储系统(如 Google Cloud Persistent Disks、Amazon Elastic Block Storage 和许多本地存储系统)都可以创建 Persistent Volume(持久卷)的“快照”。快照表示 Volume 的时间点副本,可用于设置新的 Volume(预填充快照数据)或将现有 Volume 还原到先前状态(由快照表示)。

Kubernetes Volume 插件系统提供强大的抽象功能,可以自动配置、附加和挂载块和文件存储。这些功能都基于 Kubernetes 的工作负载可移植性:Kubernetes 的目标是在分布式系统应用程序和底层集群之间创建一个抽象层,以便应用程序可以不知道底层集群的具体情况,且在部署时不需要“特定于集群”的知识。

Kubernetes Storage SIG 将快照操作确定为许多有状态工作负载的关键功能。例如,在进行数据库操作之前,数据库管理员可能需要对数据库卷进行快照。通过提供一种在 Kubernetes API 中触发快照操作的标准方式,Kubernetes 用户现在可以轻松应对上述场景,而不必使用 Kubernetes API 手动执行针对存储系统的特定操作。

Kubernetes 用户现在被授权以与集群无关的方式,将快照操作合并到他们的工具和策略中,并且可以放心地知道它将针对任意的 Kubernetes 集群,而不需要在意底层存储是什么。此外,这些 Kubernetes 快照原语是基本的构建块,可用于为 Kubernetes 开发高级的企业级存储管理功能,如应用程序级或集群级的备份解决方案。
 

[SIG Strorage] in-tree 插件迁移到CSI  beta

 
KEP:https://github.com/kubernetes/enhancements/blob/master/keps/sig-storage/20190129-csi-migration.md
 
CSI Migration 允许使用相应的 CSI 驱动程序替换现有 in-tree 存储插件,如 kubernetes.io/gce-pd 和 kubernetes.io/aws-ebs。 如果 CSI Migration 工作正常,Kubernetes 终端用户不会注意到差异。迁移之后,开发者可以继续使用现有接口依赖于 in-tree 存储插件的所有功能。当 Kubernetes 集群管理员更新集群以支持 CSI Migration 时,现有的有状态部署和工作负载将继续正常工作,但这时 Kubernetes 已经将所有的存储管理操作(以前针对 in-tree 驱动程序)都交给了 CSI 驱动程序。

Kubernetes 团队一直致力于确保存储 API 的稳定性,并承诺提供平滑的升级体验。这需要仔细考虑所有现有的特性和行为,以确保向后兼容性和 API 稳定性。你可以把它想象成赛车在直道上加速时换轮子。在 CSI 之前,Kubernetes 提供了一套功能强大的 Volume 插件系统。这些插件是“in-tree 插件”,这意味着它们的代码是核心 Kubernetes 代码的一部分,并随核心 Kubernetes 二进制文件一起发布。

然而,向 Kubernetes 添加对新的 Volume 插件的支持具有挑战性。首先,希望向 Kubernetes 添加对其存储系统支持的供应商需要被迫与 Kubernetes 的发布进度保持一致。其次,第三方存储代码在核心 Kubernetes 二进制文件中也容易引起可靠性和安全性问题,且这些代码对于运维人员来说通常很难测试和维护。在 Kubernetes 中使用 CSI 可以解决这些主要问题。

随着越来越多 CSI 驱动程序被开发出来并投入生产,Kubernetes 开发团队希望所有用户都能从 CSI 模型中受益。但是,团队不想通过破坏现有的通用存储 API 来迫使用户进行工作负载/配置更改,相反地,他们必须用 CSI 替换”in-tree 插件” API 的后端。
 

[SIG Network] 拓扑感知服务路由 beta

 
KEP:https://github.com/kubernetes/enhancements/blob/master/KEPs/sig-network/20181024-service-topology.md
 
拓扑域表示在集群中的某一类 “地方”,比如某节点、某机架、某可用区或某地域等, 这些都可以作为某种拓扑域。想象一下,k8s 集群节点分布在不同的地方,service 对应的 endpoints 分布在不同节点,传统转发策略会对所有 endpoint 做负载均衡,通常会等概率转发。当访问 service 时,流量就可能被分散打到这些不同的地方。虽然 service 转发做了负载均衡,但如果 endpoint 距离比较远,流量转发过去网络时延就相对比较高会影响网络性能,在某些情况下甚至还可能会付出额外的流量费用。要是如能实现 service 就近转发 endpoint,就可以降低网络时延,提升网络性能。

通常在节点初始化的时候,controller-manager 就会为节点打上许多 label,比如 kubernetes.io/hostname 表示节点的 hostname 来区分节点;另外,在云厂商提供的 k8s 服务,或者使用 cloud-controller-manager 的自建集群,通常还会给节点打上 failure-domain.beta.kubernetes.io/zone 和 failure-domain.beta.kubernetes.io/region 以区分节点所在可用区和所在地域,但自 v1.17 开始将会改名成 topology.kubernetes.io/zone 和 topology.kubernetes.io/region。拓扑感知服务路由特性会通过 Endpoint Slice 获取这些拓扑信息实现 endpoint 筛选 (过滤出在同一拓扑域的 endpoint), 然后再转换为 iptables 或 ipvs 规则写入节点以实现拓扑感知的路由转发。

之前每个节点上转发 service 的 iptables/ipvs 规则基本是一样的,但启用了拓扑感知服务路由特性之后,每个节点上的转发规则就可能不一样了,因为不同节点的拓扑信息不一样,导致过滤出的 endpoint 就不一样。也正是因为这样,service 转发变得不再等概率,灵活的就近转发才得以实现。
 

[SIG Node] Pod中的进程命名空间共享

 
KEP:https://github.com/kubernetes/enhancements/blob/master/KEPs/sig-node/20190920-pod-pid-namespace.md
 
此功能使共享一个容器的容器能够共享相同的进程名称空间。将 Pod 的 shareProcessNamespace 字段设置为 true 时,该 Pod 中的所有容器将在共享的(Linux)进程名称空间中运行,从而简化了进程间的信号传递和应用程序调试。
 



V1.18




 


[SIG Node] Kubernetes拓扑管理器(Topology Manager) Beta

 
KEP:https://github.com/kubernetes/enhancements/blob/master/KEPs/sig-node/0035-20190130-topology-manager.md
 
越来越多的系统利用 CPU 和硬件加速器的组合来支持对延迟要求较高的任务和高吞吐量的并行计算。这类负载包括电信,科学计算,机器学习,金融服务和数据分析等。此类混合系统即用于构造这些高性能环境。为了获得最佳性能,需要进行与 CPU 隔离、内存和设备局部性有关的优化。但是,在 Kubernetes 中,这些优化由各自独立的组件集合来处理。拓扑管理器(Topology Manager) 是 Kubelet 的一部分,旨在协调负责这些优化的一组组件。

在引入拓扑管理器之前, Kubernetes 中的 CPU 和设备管理器相互独立地做出资源分配决策。这可能会导致在多处理系统上出现并非期望的资源分配,由于这些与期望相左的分配,对性能或延迟敏感的应用将受到影响。这里的不符合期望意指,例如,CPU 和设备是从不同的 NUMA 节点分配的,因此会导致额外的延迟。拓扑管理器是一个 Kubelet 组件,扮演信息源的角色,以便其他 Kubelet 组件可以做出与拓扑结构相对应的资源分配决定。

拓扑管理器为组件提供了一个 Hint Providers 接口以发送和接收拓扑信息。拓扑管理器具有一组节点级策略,拓扑管理器从 Hint Providers 接收拓扑信息,作为表示可用的 NUMA 节点和首选分配指示的位掩码。拓扑管理器策略对所提供的建议执行一组操作,并根据策略对提示进行约减以得到最优解。如果存储了与预期不符的建议,则该建议的优选字段将被设置为 false。在当前策略中,首选的是最窄的优选掩码。所选建议将被存储为拓扑管理器的一部分。取决于所配置的策略,所选建议可用来决定节点接受或拒绝 Pod。之后,建议会被存储在拓扑管理器中,供 Hint Providers 进行资源分配决策时使用。
 

[SIG API Machinery] Server-side Apply Beta

 
KEP:https://github.com/kubernetes/enhancements/blob/master/keps/sig-api-machinery/0006-apply.md
 
对于apiserver来说,Server-side apply 是对 kubectl apply 的重要变动,使用了新的合并算法,通过在managedFields追踪记录各个字段的变动达到冲突检测的目的。
 

[SIG CLI] kubectl debug alpha

 
KEP:https://github.com/kubernetes/enhancements/blob/master/keps/sig-cli/20190805-kubectl-debug.md
 
kubectl debug的初始功能有:

  • 创建一个拥有各种debug工具临时容器attach进调试容器
  • 使用 PodSpec 用不同的镜像或者权限复制重启一个容器
  • 使用特权模式进入 host 命名空间
 
附录 A – K8S 各个版本值得注意的 Feature 变更:
 
Kubernetes 这三年不得不说的事(下篇)




END



九州云成立于2012年,是中国早期从事开放基础架构服务的专业公司。成立八年,秉承“开源 · 赋能变革”的理念,不断夯实自身实力,先后为政府、金融、运营商、能源、制造业、商业、交通、物流、教育、医疗等各行业的企业级客户提供高质量的开放基础架构服务。目前拥有国家电网、南方电网广东公司、中国人民银行、中国银联、中国移动、中国电信、中国联通、中国资源卫星、eBay、国际陆港集团、中国人寿、万达信息、东风汽车、诺基亚等众多重量级客户,被用户认可为最值得信赖的合作伙伴。

Kubernetes 这三年不得不说的事(下篇)

点击“阅读原文”,了解九州云更多信息!