【重识云原生】第六章容器6.2.2节——K8S架构剖析

1. K8s架构综述

        Kubernetes 最初源于谷歌内部的 Borg,提供了面向应用的容器集群部署和管理系统。Kubernetes 的目标旨在消除编排物理/虚拟计算、网络和存储等基础设施资源的负担,并使应用程序运营商和开发人员完全将重点放在以容器为中心的原语上进行自助运营。Kubernetes 也提供稳定、兼容的基础(平台),用于构建定制化的 workflows 和更高级的自动化任务。 Kubernetes 具备完善的集群管理能力,包括多层次的安全防护和准入机制、多租户应用支撑能力、透明的服务注册和服务发现机制、内建负载均衡器、故障发现和自我修复能力、服务滚动升级和在线扩容、可扩展的资源自动调度机制、多粒度的资源配额管理能力。 Kubernetes 还提供完善的管理工具,涵盖开发、部署测试、运维监控等各个环节。

1.1 Borg 简介

        Borg 是谷歌内部的大规模集群管理系统,负责对谷歌内部很多核心服务的调度和管理。Borg 的目的是让用户能够不必操心资源管理的问题,让他们专注于自己的核心业务,并且做到跨多个数据中心的资源利用率最大化。

Borg 主要由 BorgMaster、Borglet、borgcfg 和 Scheduler 组成,如下图所示:

  • BorgMaster 是整个集群的大脑,负责维护整个集群的状态,并将数据持久化到 Paxos 存储中;
  • Scheduer 负责任务的调度,根据应用的特点将其调度到具体的机器上去;
  • Borglet 负责真正运行任务(在容器中);
  • borgcfg 是 Borg 的命令行工具,用于跟 Borg 系统交互,一般通过一个配置文件来提交任务。

1.2 Kubernetes 架构介绍

        Kubernetes 借鉴了 Borg 的设计理念,比如 Pod、Service、Labels 和单 Pod 单 IP 等。Kubernetes 的整体架构跟 Borg 非常像,在设计遵循了c/s架构设计理念,也就是下图中apiserver与其余组件的交互。K8s将集群中的机器划分为主节点(Master Node)和工作节点(Worker Node),在生产中通常会有多个Master节点组成高可用集群,以实现K8s系统管控服务的高可用。K8s业务集群至少有一个工作节点,节点上运行 K8s 所管理的容器化应用。

        在Master通常上包括 kube-apiserver、etcd 存储、kube-controller-manager、cloud-controller-manager、kube-scheduler 和用于 K8s 服务的 DNS 服务器(插件)。这些对集群做出全局决策(比如调度),以及检测和响应集群事件的组件集合也称为控制平面。通过这些组件,可实现整个集群的资源管理、pod 调度、弹性伸缩、安全控制、系统监控和纠错等管理功能,并且都是全自动完成的。

        其实K8s官方并没有Master这一说,只是大多数安装工具(kubeadm)或者脚本为了架构更明了会把控制平面中的组件安装到一台机器上即Master机器,并且不会在此机器上运行用户容器。但这不是强制性的,所以你也可以将控制平面组件实行分布式部署,不过这样的话高可用会是一个不小的挑战。

        集群中的工作节点是真正运行应用程序的地方,各自又通过若干组件的组合来实现。在节点上,K8s管理的最小运行单元是pod。而在Worker Node上的管理组件包括 kubelet 、kube-porxy 以及服务于pod的容器运行时(runtime)。外部storage与registry用于为容器提供存储与镜像仓库服务。

1.3 Kubernetes设计理念

1.3.1 设计理念与分布式系统

        分析和理解Kubernetes的设计理念可以使我们更深入地了解Kubernetes系统,更好地利用它管理分布式部署的云原生应用,另一方面也可以让我们借鉴其在分布式系统设计方面的经验。

1.3.2 API设计原则

        对于云计算系统,系统API实际上处于系统设计的统领地位。Kubernetes集群系统每支持一项新功能,引入一项新技术,一定会新引入对应的API对象,以支持对该功能的管理操作。理解掌握了K8S的API,就好比抓住了K8s系统的牛鼻子。Kubernetes系统API的设计有以下几条原则:

  1. 所有API应该是声明式的。声明式的操作,相对于命令式操作,对于重复操作的效果是稳定的,这对于容易出现数据丢失或重复的分布式环境来说是很重要的。另外,声明式操作更容易被用户使用,可以使系统向用户隐藏实现的细节,同时也保留了系统未来持续优化的可能性。此外,声明式的API还隐含了所有的API对象都是名词性质的,例如Service、Volume这些API都是名词,这些名词描述了用户所期望得到的一个目标对象。 
  2. API对象是彼此互补而且可组合的。这实际上鼓励API对象尽量实现面向对象设计时的要求,即“高内聚,松耦合”,对业务相关的概念有一个合适的分解,提高分解出来的对象的可重用性。 
  3. 高层API以操作意图为基础设计。如何能够设计好API,跟如何能用面向对象的方法设计好应用系统有相通的地方,高层设计一定是从业务出发,而不是过早的从技术实现出发。因此,针对Kubernetes的高层API设计,一定是以K8s的业务为基础出发,也就是以系统调度管理容器的操作意图为基础设计。 
  4. 低层API根据高层API的控制需要设计。设计实现低层API的目的,是为了被高层API使用,考虑减少冗余、提高重用性的目的,低层API的设计也要以需求为基础,要尽量抵抗受技术实现影响的诱惑。 
  5. 尽量避免简单封装,不要有在外部API无法显式知道的内部隐藏的机制。简单的封装,实际没有提供新的功能,反而增加了对所封装API的依赖性。内部隐藏的机制也是非常不利于系统维护的设计方式,例如StatefulSet和ReplicaSet,本来就是两种Pod集合,那么Kubernetes就用不同API对象来定义它们,而不会说只用同一个ReplicaSet,内部通过特殊的算法再来区分这个ReplicaSet是有状态的还是无状态。 
  6. API操作复杂度与对象数量成正比。这一条主要是从系统性能角度考虑,要保证整个系统随着系统规模的扩大,性能不会迅速变慢到无法使用,那么最低的限定就是API的操作复杂度不能超过O(N),N是对象的数量,否则系统就不具备水平伸缩性了。 
  7. API对象状态不能依赖于网络连接状态。由于众所周知,在分布式环境下,网络连接断开是经常发生的事情,因此要保证API对象状态能应对网络的不稳定,API对象的状态就不能依赖于网络连接状态。 
  8. 尽量避免让操作机制依赖于全局状态,因为在分布式系统中要保证全局状态的同步是非常困难的。

1.3.3 控制机制设计原则

  • 控制逻辑应该只依赖于当前状态。这是为了保证分布式系统的稳定可靠,对于经常出现局部错误的分布式系统,如果控制逻辑只依赖当前状态,那么就非常容易将一个暂时出现故障的系统恢复到正常状态,因为你只要将该系统重置到某个稳定状态,就可以自信的知道系统的所有控制逻辑会开始按照正常方式运行。 
  • 假设任何错误的可能,并做容错处理。在一个分布式系统中出现局部和临时错误是大概率事件。错误可能来自于物理系统故障,外部系统故障也可能来自于系统自身的代码错误,依靠自己实现的代码不会出错来保证系统稳定其实也是难以实现的,因此要设计对任何可能错误的容错处理。 
  • 尽量避免复杂状态机,控制逻辑不要依赖无法监控的内部状态。因为分布式系统各个子系统都是不能严格通过程序内部保持同步的,所以如果两个子系统的控制逻辑互相有影响,那么子系统就一定要能互相访问到影响控制逻辑的状态,否则,就等同于系统里存在不确定的控制逻辑。 
  • 假设任何操作都可能被任何操作对象拒绝,甚至被错误解析。由于分布式系统的复杂性以及各子系统的相对独立性,不同子系统经常来自不同的开发团队,所以不能奢望任何操作被另一个子系统以正确的方式处理,要保证出现错误的时候,操作级别的错误不会影响到系统稳定性。 
  • 每个模块都可以在出错后自动恢复。由于分布式系统中无法保证系统各个模块是始终连接的,因此每个模块要有自我修复的能力,保证不会因为连接不到其他模块而自我崩溃。 
  • 每个模块都可以在必要时优雅地降级服务。所谓优雅地降级服务,是对系统鲁棒性的要求,即要求在设计实现模块时划分清楚基本功能和高级功能,保证基本功能不会依赖高级功能,这样同时就保证了不会因为高级功能出现故障而导致整个模块崩溃。根据这种理念实现的系统,也更容易快速地增加新的高级功能,因为不必担心引入高级功能影响原有的基本功能。

1.3.4 架构设计原则

  • 只有apiserver可以直接访问etcd存储,其他服务必须通过Kubernetes API来访问集群状态
  • 单节点故障不应该影响集群的状态
  • 在没有新请求的情况下,所有组件应该在故障恢复后继续执行上次最后收到的请求(比如网络分区或服务重启等)
  • 所有组件都应该在内存中保持所需要的状态,apiserver将状态写入etcd存储,而其他组件则通过apiserver更新并监听所有的变化
  • 优先使用事件监听而不是轮询

1.3.5 引导(Bootstrapping)原则

  • Self-hosting 是目标
  • 减少依赖,特别是稳态运行的依赖
  • 通过分层的原则管理依赖
  • 循环依赖问题的原则
    • 同时还接受其他方式的数据输入(比如本地文件等),这样在其他服务不可用时还可以手动配置引导服务
    • 状态应该是可恢复或可重新发现的
    • 支持简单的启动临时实例来创建稳态运行所需要的状态;使用分布式锁或文件锁等来协调不同状态的切换(通常称为pivoting技术)
    • 自动重启异常退出的服务,比如副本或者进程管理器等

2 Kubernetes 架构剖析

Kubernetes 主要由以下几个核心组件组成:

  • etcd 保存了整个集群的状态;
  • kube-apiserver 提供了资源操作的唯一入口,并提供认证、授权、访问控制、API 注册和发现等机制;
  • kube-controller-manager 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
  • kube-scheduler 负责资源的调度,按照预定的调度策略将 Pod 调度到相应的机器上;
  • kubelet 负责维持容器的生命周期,同时也负责 Volume(CVI)和网络(CNI)的管理;
  • Container runtime 负责镜像管理以及 Pod 和容器的真正运行(CRI),默认的容器运行时为 Docker;
  • kube-proxy 负责为 Service 提供 cluster 内部的服务发现和负载均衡;

 除了核心组件,还有一些推荐的 Add-ons:

  • kube-dns 负责为整个集群提供 DNS 服务
  • Ingress Controller 为服务提供外网入口
  • Heapster 提供资源监控
  • Dashboard 提供 GUI
  • Federation 提供跨可用区的集群
  • Fluentd-elasticsearch 提供集群日志采集、存储与查询

2.1 分层架构

        Kubernetes 设计理念和功能其实就是一个类似 Linux 的分层架构,如下图所示:

  • 核心层:Kubernetes 最核心的功能,对外提供 API 构建高层的应用,对内提供插件式应用执行环境
  • 应用层:部署(无状态应用、有状态应用、批处理任务、集群应用等)和路由(服务发现、DNS 解析等)
  • 管理层:系统度量(如基础设施、容器和网络的度量),自动化(如自动扩展、动态 Provision 等)以及策略管理(RBAC、Quota、PSP、NetworkPolicy 等)
  • 接口层:kubectl 命令行工具、客户端 SDK 以及集群联邦
  • 生态系统:在接口层之上的庞大容器集群管理调度的生态系统,可以划分为两个范畴
    • Kubernetes 外部:日志、监控、配置管理、CI、CD、Workflow、FaaS、OTS 应用、ChatOps 等
    • Kubernetes 内部:CRI、CNI、CVI、镜像仓库、Cloud Provider、集群自身的配置和管理等

2.2 核心组件

2.3 核心 API

2.4 生态系统

       关于分层架构,可以关注下 Kubernetes 社区正在推进的 Kubernetes architectural roadmap

2.5 组件通信

        Kubernetes 多组件之间的通信原理为:

  • API Server 负责 etcd 存储的所有操作,且只有 API Server 才直接操作 etcd 集群
  • API Server 对内(集群中的其他组件)和对外(用户)提供统一的 REST API,其他组件均通过 API Server 进行通信
    • Controller Manager、Scheduler、Kube-proxy 和 Kubelet 等均通过 API Server watch API 监测资源变化情况,并对资源作相应的操作
    • 所有需要更新资源状态的操作均通过 API Server 的 REST API 进行
  • API Server 也会直接调用 Kubelet API(如 logs, exec, attach 等),默认不校验 Kubelet 证书,但可以通过 

--kubelet-certificate-authority 开启(而 GKE 通过 SSH 隧道保护它们之间的通信)

        比如典型的创建 Pod 的流程为:

  1. 用户通过 REST API 创建一个 Pod
  2. API Server 将其写入 etcd
  3. Scheduluer 检测到未绑定 Node 的 Pod,开始调度并更新 Pod 的 Node 绑定
  4. Kubelet 检测到有新的 Pod 调度过来,通过 Container Runtime 运行该 Pod
  5. Kubelet 通过 Container Runtime 取到 Pod 状态,并更新到 API Server 中

2.6 各组件端口号

 Master node(s)

 Worker node(s)

参考链接

k8s 架构图_信安成长日记的博客-CSDN博客_k8s架构原理图

K8s架构|全面整理K8s的架构介绍_BugGuys的博客-CSDN博客_k8s架构

k8s整体架构的知识整理

k8s架构与组件详解 - 知乎

一文讲明白K8S各核心架构组件

一文讲明白K8S各核心架构组件 - 赐我白日梦 - 博客园

k8s的架构 -阿里云开发者社区

通俗易懂 k8s——架构篇

Kubernetes的整体架构

K8s架构|全面整理K8s的架构介绍

一文秒懂 K8s 架构 | Kubernetes 架构简介 | 红帽

2.k8s的架构 - 腾讯云开发者社区-腾讯云

架构原理 · Kubernetes指南

Master-Node communication

Core Kubernetes: Jazz Improv over Orchestration

Installing kubeadm | Kubernetes

核心组件 · Kubernetes指南

   《重识云原生系列》专题索引:

  1. 第一章——不谋全局不足以谋一域
  2. 第二章计算第1节——计算虚拟化技术总述
  3. 第二章计算第2节——主流虚拟化技术之VMare ESXi
  4. 第二章计算第3节——主流虚拟化技术之Xen
  5. 第二章计算第4节——主流虚拟化技术之KVM
  6. 第二章计算第5节——商用云主机方案
  7. 第二章计算第6节——裸金属方案
  8. 第三章云存储第1节——分布式云存储总述
  9. 第三章云存储第2节——SPDK方案综述
  10. 第三章云存储第3节——Ceph统一存储方案
  11. 第三章云存储第4节——OpenStack Swift 对象存储方案
  12. 第三章云存储第5节——商用分布式云存储方案
  13. 第四章云网络第一节——云网络技术发展简述
  14. 第四章云网络4.2节——相关基础知识准备
  15. 第四章云网络4.3节——重要网络协议
  16. 第四章云网络4.3.1节——路由技术简述
  17. 第四章云网络4.3.2节——VLAN技术
  18. 第四章云网络4.3.3节——RIP协议
  19. 第四章云网络4.3.4.1-2节——OSPF协议综述
  20. 第四章云网络4.3.4.3节——OSPF协议工作原理
  21. 第四章云网络4.3.4.4节——[转载]OSPF域内路由
  22. 第四章云网络4.3.4.5节——[转载]OSPF外部路由
  23. 第四章云网络4.3.4.6节——[转载]OSPF特殊区域之Stub和Totally Stub区域详解及配置
  24. 第四章云网络4.3.4.7节——OSPF特殊区域之NSSA和Totally NSSA详解及配置
  25. 第四章云网络4.3.5节——EIGRP协议
  26. 第四章云网络4.3.6节——IS-IS协议
  27. 第四章云网络4.3.7节——BGP协议
  28. 第四章云网络4.3.7.2节——BGP协议概述
  29. 第四章云网络4.3.7.3节——BGP协议实现原理
  30. 第四章云网络4.3.7.4节——高级特性
  31. 第四章云网络4.3.7.5节——实操
  32. 第四章云网络4.3.7.6节——MP-BGP协议
  33. 第四章云网络4.3.8节——策略路由
  34. 第四章云网络4.3.9节——Graceful Restart(平滑重启)技术
  35. 第四章云网络4.3.10节——VXLAN技术
  36. 第四章云网络4.3.10.2节——VXLAN Overlay网络方案设计
  37. 第四章云网络4.3.10.3节——VXLAN隧道机制
  38. 第四章云网络4.3.10.4节——VXLAN报文转发过程
  39. 第四章云网络4.3.10.5节——VXlan组网架构
  40. 第四章云网络4.3.10.6节——VXLAN应用部署方案
  41. 第四章云网络4.4节——Spine-Leaf网络架构
  42. 第四章云网络4.5节——大二层网络
  43. 第四章云网络4.6节——Underlay 和 Overlay概念
  44. 第四章云网络4.7.1节——网络虚拟化与卸载加速技术的演进简述
  45. 第四章云网络4.7.2节——virtio网络半虚拟化简介
  46. 第四章云网络4.7.3节——Vhost-net方案
  47. 第四章云网络4.7.4节vhost-user方案——virtio的DPDK卸载方案
  48. 第四章云网络4.7.5节vDPA方案——virtio的半硬件虚拟化实现
  49. 第四章云网络4.7.6节——virtio-blk存储虚拟化方案
  50. 第四章云网络4.7.8节——SR-IOV方案
  51. 第四章云网络4.7.9节——NFV
  52. 第四章云网络4.8.1节——SDN总述
  53. 第四章云网络4.8.2.1节——OpenFlow概述
  54. 第四章云网络4.8.2.2节——OpenFlow协议详解
  55. 第四章云网络4.8.2.3节——OpenFlow运行机制
  56. 第四章云网络4.8.3.1节——Open vSwitch简介
  57. 第四章云网络4.8.3.2节——Open vSwitch工作原理详解
  58. 第四章云网络4.8.4节——OpenStack与SDN的集成
  59. 第四章云网络4.8.5节——OpenDayLight
  60. 第四章云网络4.8.6节——Dragonflow
  61.  第四章云网络4.9.1节——网络卸载加速技术综述

  62. 第四章云网络4.9.2节——传统网络卸载技术

  63. 第四章云网络4.9.3.1节——DPDK技术综述

  64. 第四章云网络4.9.3.2节——DPDK原理详解

  65. 第四章云网络4.9.4.1节——智能网卡SmartNIC方案综述

  66. 第四章云网络4.9.4.2节——智能网卡实现

  67. 第六章容器6.1.1节——容器综述

  68. 第六章容器6.1.2节——容器安装部署

  69. 第六章容器6.1.3节——Docker常用命令

  70. 第六章容器6.1.4节——Docker核心技术LXC

  71. 第六章容器6.1.5节——Docker核心技术Namespace

  72. 第六章容器6.1.6节—— Docker核心技术Chroot

  73. 第六章容器6.1.7.1节——Docker核心技术cgroups综述

  74. 第六章容器6.1.7.2节——cgroups原理剖析

  75. 第六章容器6.1.7.3节——cgroups数据结构剖析

  76. 第六章容器6.1.7.4节——cgroups使用

  77. 第六章容器6.1.8节——Docker核心技术UnionFS

  78. 第六章容器6.1.9节——Docker镜像技术剖析

  79. 第六章容器6.1.10节——DockerFile解析

  80. 第六章容器6.1.11节——docker-compose容器编排

  81. 第六章容器6.1.12节——Docker网络模型设计

  82. 第六章容器6.2.1节——Kubernetes概述

  83. 第六章容器6.2.2节——K8S架构剖析

  84. 第六章容器6.3.1节——K8S核心组件总述

  85. 第六章容器6.3.2节——API Server组件

  86. 第六章容器6.3.3节——Kube-Scheduler使用篇

  87. 第六章容器6.3.4节——etcd组件

  88. 第六章容器6.3.5节——Controller Manager概述

  89. 第六章容器6.3.6节——kubelet组件

  90. 第六章容器6.3.7节——命令行工具kubectl

  91. 第六章容器6.3.8节——kube-proxy

  92.  第六章容器6.4.1节——K8S资源对象总览

  93. 第六章容器6.4.2.1节——pod详解

  94. 第六章容器6.4.2.2节——Pod使用(上)

  95. 第六章容器6.4.2.3节——Pod使用(下)

  96. 第六章容器6.4.3节——ReplicationController

  97. 第六章容器6.4.4节——ReplicaSet组件

  98. 第六章容器基础6.4.5.1节——Deployment概述

  99. 第六章容器基础6.4.5.2节——Deployment配置详细说明

  100. 第六章容器基础6.4.5.3节——Deployment实现原理解析

  101. 第六章容器基础6.4.6节——Daemonset

  102. 第六章容器基础6.4.7节——Job

  103. 第六章容器基础6.4.8节——CronJob

  104. 第六章容器基础6.4.9.1节——Service综述

  105. 第六章容器基础6.4.9.2节——使用 Service 连接到应用

  106. 第六章容器基础6.4.9.3节——Service拓扑感知

  107. 第六章容器基础6.4.10.1节——StatefulSet概述

  108. 第六章容器基础6.4.10.2节——StatefulSet常规操作实操

  109. 第六章容器基础6.4.10.3节——StatefulSet实操案例-部署WordPress 和 MySQL

  110. 第六章容器基础6.4.10.4节——StatefulSet实操案例-使用 StatefulSet 部署Cassandra

  111. 第六章容器基础6.4.10.5节——Statefulset原理剖析

  112. 第六章容器基础6.4.11.1节——Ingress综述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江中散人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值