编辑推荐:
第1章 Kubernetes基本架构 1
1.1 Kubernetes发展历史 1
1.2 Kubernetes架构 2
1.3 Kubernetes各组件功能 3
1.3.1 kubectl 4
1.3.2 client-go 4
1.3.3 kube-apiserver 4
1.3.4 kube-controller-manager 4
1.3.5 kube-scheduler 5
1.3.6 kubelet 5
1.3.7 kube-proxy 6
1.3.8 Container Runtime 6
1.4 Kubernetes Project Layout设计 7
第2章 Kubernetes构建过程 10
2.1 构建方式 10
2.2 一切都始于Makefile 12
2.3 本地环境构建 13
2.3.1 本地环境构建命令 13
2.3.2 本地环境构建过程 14
2.4 容器环境构建 16
2.4.1 容器环境构建命令 16
2.4.2 容器环境构建过程 16
第3章 Kubernetes核心数据结构 19
3.1 初识数据结构 19
3.2 基本概念 19
3.2.1 API的层次结构 19
3.2.2 版本控制 20
3.2.3 组 21
3.2.4 API术语 22
3.2.5 API资源组成 25
3.2.6 版本化资源与未版本化资源 26
3.2.7 内部版本与外部版本 27
3.3 Kubernetes API的数据结构 28
3.3.1 APIGroup、APIVersions 28
3.3.2 APIResource 30
3.3.3 GVK和GVR 32
3.3.4 内置资源全景图 33
3.4 Kubernetes资源定义 35
3.4.1 内部版本定义 35
3.4.2 外部版本定义 36
3.5 将资源注册到Scheme中 36
3.5.1 资源类型注册入口 37
3.5.2 Scheme的数据结构 38
3.5.3 Scheme的初始化 40
3.5.4 SchemeBuilder资源注册 41
3.5.5 资源外部版本注册 43
3.5.6 资源内部版本注册 44
3.5.7 所有资源的注册入口 45
3.5.8 资源注册表的查询方法 47
3.5.9 资源对象的创建 48
3.5.10 资源对象的转换 48
3.5.11 资源对象默认值的设置 49
3.5.12 资源字段的转换 49
3.6 对象体系设计 49
3.6.1 资源对象的基本信息 49
3.6.2 对象体系类图 50
3.6.3 runtime.Object 51
3.6.4 metav1.TypeMeta 52
3.6.5 metav1.ObjectMeta 52
3.6.6 Unstructured 53
3.7 runtime.Codec资源编/解码 55
3.7.1 编/解码数据结构 56
3.7.2 CodecFactory实例化 57
3.7.3 codec编/解码实现类 60
3.7.4 json.Serializer编/解码 64
3.7.5 protobuf.Serializer编/解码 65
3.7.6 UnstructuredJSONScheme实现类 67
3.7.7 NegotiatedSerializer 67
3.7.8 ParameterCodec 69
3.7.9 runtime包下的Codec相关函数 71
3.7.10 Codec核心调用链路 72
3.7.11 Codec的使用方式 74
3.8 Converter资源版本转换器 75
3.8.1 Converter的数据结构 76
3.8.2 Converter转换函数的注册 77
3.8.3 Converter的初始化 77
3.8.4 Converter资源版本转换的实现 78
3.9 使用RESTMapper管理GVR和GVK映射 79
3.9.1 RESTMapper的数据结构 80
3.9.2 RESTMapper实现类 81
3.9.3 DefaultRESTMapper默认实现类 82
3.9.4 PriorityRESTMapper优先级映射 83
3.9.5 DeferredDiscoveryRESTMapper实现类 84
3.9.6 RESTMapper的使用 85
3.9.7 RESTMapping的数据结构及典型用法 85
第4章 Kubernetes核心资源对象 87
4.1 初识Kubernetes资源对象 87
4.2 metav1.ObjectMeta属性元数据 88
4.2.1 Name 88
4.2.2 GenerateName 89
4.2.3 Annotation 89
4.2.4 Generation 89
4.2.5 ResourceVersion 90
4.2.6 OwnerReference 91
4.2.7 Finalizers 92
4.2.8 ManagedFields 94
4.3 Pod资源对象 99
4.3.1 PodSpec字段详解 100
4.3.2 Container字段详解 110
4.3.3 Pod创建流程 114
4.3.4 Pause容器及创建流程 115
4.3.5 PodSpec生成容器参数 122
4.3.6 容器的通用创建流程 124
4.3.7 资源配额与cgroup 126
4.3.8 QoS与驱逐顺序 131
4.3.9 静态Pod 135
4.3.10 健康检查 137
4.3.11 Pod的状态 140
4.3.12 原地升级 144
4.4 工作负载资源 146
4.4.1 Deployment 146
4.4.2 ReplicaSet 153
4.4.3 StatefulSet 156
4.4.4 DaemonSet 160
4.4.5 Job 163
4.4.6 CronJob 166
4.5 发现和负载均衡资源 169
4.5.1 Service 169
4.5.2 Ingress 175
4.5.3 Endpoints 177
4.5.4 EndpointSlice 178
4.5.5 NetworkPolicy 182
4.6 配置和存储资源 185
4.6.1 卷 185
4.6.2 PV与PVC 186
4.6.3 StorageClass 191
4.7 自定义资源 194
4.7.1 概述 194
4.7.2 Operator 196
4.7.3 controller-runtime 197
4.7.4 Kubebuilder 198
第5章 client-go编程式交互 200
5.1 初识client-go 200
5.2 客户端 200
5.2.1 kubeconfig配置管理 201
5.2.2 RESTClient客户端 204
5.2.3 ClientSet客户端 207
5.2.4 DynamicClient客户端 210
5.2.5 DiscoveryClient发现客户端 212
5.3 Informer机制 214
5.3.1 Informer使用示例 214
5.3.2 Informer架构 216
5.3.3 Reflector数据同步 217
5.3.4 DeltaFIFO操作队列 223
5.3.5 Indexer资源缓存 226
5.3.6 processor资源处理 230
5.3.7 workqueue工作队列 233
5.4 常用工具类 240
5.4.1 事件管理机制 240
5.4.2 Leader选举机制 247
第6章 kubectl命令式交互 256
6.1 初识kubectl 256
6.2 kubectl执行流程 256
6.2.1 初始化命令对象 257
6.2.2 补全命令参数 257
6.2.3 校验命令参数 258
6.2.4 执行命令输出结果 258
6.3 kubectl缓存机制 263
6.3.1 缓存数据结构 264
6.3.2 缓存机制详解 265
6.3.3 缓存使用场景 269
6.4 kubectl变更比对策略 272
6.4.1 变更比对策略介绍 272
6.4.2 服务端应用和客户端应用 272
6.4.3 策略比对器和JSON比对器 274
6.4.4 双路合并和三路合并 275
6.5 kubectl扩展命令 277
6.5.1 扩展命令介绍 277
6.5.2 扩展命令实现原理 277
6.5.3 扩展命令管理器Krew 278
第7章 etcd存储核心实现 280
7.1 初识etcd存储 280
7.2 etcd存储架构设计 280
7.3 RESTStorage资源存储接口 282
7.4 genericregistry.Store通用操作封装 283
7.4.1 标准存储实现 283
7.4.2 版本冲突检测 284
7.4.3 通用钩子函数 284
7.4.4 DryRun实现原理 287
7.5 storage.Interface通用存储接口 288
7.6 Cacher Storage缓存层 290
7.6.1 Cacher Storage缓存架构 291
7.6.2 ResourceVersion资源版本号 295
7.6.3 watchCache缓存滑动窗口 297
7.7 Underlying Storage底层存储对象 300
7.8 Codec数据编/解码 301
7.9 Strategy预处理 304
7.9.1 Create Strategy预处理 304
7.9.2 Update Strategy预处理 307
7.9.3 Delete Strategy预处理 308
第8章 kube-apiserver核心实现 310
8.1 初识kube-apiserver 310
8.2 网络通信框架 311
8.2.1 go-restful框架 311
8.2.2 Protobuf序列化 314
8.3 kube-apiserver架构设计 319
8.4 kube-apiserver启动流程 321
8.4.1 Scheme资源注册 322
8.4.2 Cobra命令行参数解析 324
8.4.3 创建API Server通用配置 325
8.4.4 创建APIExtensionsServer 336
8.4.5 创建KubeAPIServer 345
8.4.6 创建AggregatorServer 353
8.4.7 GenericAPIServer初始化 360
8.4.8 准备和启动HTTPS服务 362
8.5 请求处理流程 367
8.6 权限控制体系 368
8.7 认证 369
8.7.1 RequestHeader认证 370
8.7.2 ClientCA认证 372
8.7.3 TokenAuth认证 373
8.7.4 ServiceAccountAuth认证 374
8.7.5 BootstrapToken认证 377
8.7.6 OIDC认证 379
8.7.7 WebhookTokenAuth认证 381
8.7.8 Anonymous认证 383
8.8 授权 383
8.8.1 AlwaysAllow授权 386
8.8.2 AlwaysDeny授权 387
8.8.3 ABAC授权 388
8.8.4 Webhook授权 389
8.8.5 RBAC授权 391
8.8.6 Node授权 396
8.9 准入控制器 397
8.9.1 内置插件介绍 398
8.9.2 内部实现原理 401
8.9.3 MutatingAdmissionWebhook准入控制器 404
8.9.4 ValidatingAdmissionWebhook准入控制器 411
8.10 信号处理机制 416
8.10.1 常驻进程实现 416
8.10.2 进程的优雅关闭 417
8.10.3 向systemd报告进程状态 419
8.11 List-Watch的实现原理 420
8.11.1 长连接通信协议 420
8.11.2 List-Watch的核心原理 425
第9章 kube-scheduler核心实现 430
9.1 初识kube-scheduler 430
9.1.1 kube-scheduler调度模型 430
9.1.2 kube-scheduler内部架构 431
9.1.3 kube-scheduler事件驱动 434
9.2 kube-scheduler启动流程 437
9.2.1 Cobra命令行参数解析 438
9.2.2 实例化Scheduler对象 439
9.2.3 运行EventBroadcaster事件管理器 442
9.2.4 运行HTTPS Server 442
9.2.5 运行Informer同步资源 443
9.2.6 执行Leader选举 444
9.2.7 运行调度器 445
9.3 Scheduling Framework 445
9.3.1 诞生背景 445
9.3.2 核心架构 446
9.4 调度器运行流程 452
9.4.1 整体运行流程 452
9.4.2 Scheduling Cycle 454
9.4.3 Binding Cycle 462
9.5 优先级与抢占机制 464
9.5.1 Pod优先级 465
9.5.2 Pod驱逐抢占机制 466
9.6 内置调度插件介绍 473
第10章 kube-controller-manager核心实现 475
10.1 初识kube-controller-manager 475
10.2 架构设计详解 477
10.2.1 控制器状态模型 477
10.2.2 控制器执行原理 478
10.3 启动流程 479
10.3.1 Cobra命令行参数解析 480
10.3.2 运行EventBroadcaster事件处理器 481
10.3.3 运行HTTPS服务 481
10.3.4 执行Leader选举 482
10.3.5 启动控制器主循环 482
10.4 ReplicaSet控制器 484
10.4.1 控制器初始化 485
10.4.2 主要执行逻辑 485
10.4.3 慢启动创建Pod 487
10.4.4 排序并删除多余的Pod 487
10.4.5 Expectation机制 488
10.5 Deployment控制器 492
10.5.1 控制器初始化 492
10.5.2 主要执行逻辑 492
10.5.3 调谐Pod的数量 495
10.5.4 更新策略 495
10.5.5 版本回滚 496
10.6 DaemonSet控制器 497
10.6.1 控制器初始化 498
10.6.2 主要执行逻辑 498
10.6.3 调谐Pod的数量 500
10.6.4 更新策略 501
10.7 StatefulSet控制器 503
10.7.1 控制器初始化 503
10.7.2 主要执行逻辑 503
10.7.3 调谐Pod的数量 504
10.7.4 更新策略 507
10.8 Job控制器 508
10.8.1 控制器初始化 508
10.8.2 主要执行逻辑 508
10.8.3 调谐Pod的数量 511
10.9 CronJob控制器 512
10.9.1 控制器初始化 513
10.9.2 主要执行逻辑 513
10.9.3 计算Job的启动时间 515
10.9.4 Job并行策略 518
10.10 Endpoint控制器 519
10.10.1 控制器初始化 519
10.10.2 主要执行逻辑 520
10.10.3 Subsets属性的计算 523
10.11 EndpointSlice控制器 524
10.11.1 控制器初始化 524
10.11.2 主要执行逻辑 525
10.11.3 EndpointSlice控制器的计算与填充 527
10.12 GarbageCollector控制器 531
10.12.1 控制器初始化 532
10.12.2 主要执行逻辑 533
10.12.3 更新资源对象依赖关系图 534
10.12.4 孤儿删除 537
10.12.5 级联删除 537
10.13 NodeLifecycle控制器 539
10.13.1 控制器初始化 539
10.13.2 主要执行逻辑 541
10.13.3 添加NoSchedule效果的Taint 543
10.13.4 Node健康状态检测 544
10.13.5 使用NoExecute Taint驱逐Node上的Pod 546
10.13.6 直接驱逐Node上的Pod 547
10.14 其他控制器 548
10.14.1 Namespace控制器 548
10.14.2 ServiceAccount控制器 550
10.14.3 PodGC控制器 550
10.14.4 SA Token控制器 551
10.14.5 ResourceQuota控制器 552
第11章 kube-proxy核心实现 553
11.1 初识kube-proxy 553
11.2 Service资源 553
11.3 架构设计详解 554
11.4 kube-proxy初始化过程 555
11.4.1 生成iptables、ipvs、Kernel、IP Set接口 556
11.4.2 判断是否支持ipvs代理模式 558
11.4.3 获取宿主节点的Hostname 559
11.4.4 生成KubeClient和EventClient 559
11.4.5 获取宿主节点的IP地址 560
11.4.6 确定代理模式 560
11.4.7 确定本地数据包判定方法 560
11.4.8 确定IP协议栈 561
11.4.9 生成Proxier结构体 562
11.5 iptables代理模式的执行过程 562
11.5.1 统计Stale Service和Stale Endpoints 563
11.5.2 创建基础iptables链和规则 564
11.5.3 初始化iptables内容缓冲区 566
11.5.4 配置KUBE-POSTROUTING链跳转规则 567
11.5.5 配置KUBE-MARK-MASQ链跳转规则 567
11.5.6 统计宿主节点IP地址 568
11.5.7 为每个Service Port配置iptables链和规则 568
11.5.8 配置KUBE-NODEPORTS链跳转规则 576
11.5.9 配置KUBE-FORWARD链跳转规则 577
11.5.10 将iptables缓冲区内容刷新到宿主机 577
11.5.11 清理残留的UDP Conntrack记录 577
11.6 ipvs代理模式的执行过程 578
11.6.1 统计Stale Service和Stale Endpoints 579
11.6.2 初始化iptables内容缓冲区 580
11.6.3 创建基础iptables链和规则 580
11.6.4 创建Dummy网卡 583
11.6.5 创建IP Set 583
11.6.6 统计宿主节点的IP地址 585
11.6.7 为每个Service Port配置规则 585
11.6.8 更新各个IP Set的内容 590
11.6.9 创建匹配IP Set的iptables规则 591
11.6.10 将iptables缓冲区内容刷新到宿主机 593
11.6.11 清理冗余的Service地址 594
11.6.12 清理残留的UDP Conntrack记录 595
第12章 kubelet核心实现 596
12.1 初识kubelet 596
12.2 kubelet架构设计 596
12.3 kubelet启动流程 601
12.3.1 Cobra命令行参数解析 601
12.3.2 运行环境检测与设置 603
12.3.3 Kubelet对象实例化 605
12.3.4 启动kubelet主服务 606
12.3.5 启动HTTP Server服务和gRPC Server服务 611
12.4 Pod生命周期管理 612
12.4.1 CRI 613
12.4.2 Pod启动流程 616
12.4.3 Pod驱逐流程 629
12.5 cgroup资源隔离 637
12.6 垃圾回收原理 639
12.6.1 镜像垃圾回收 639
12.6.2 容器垃圾回收 645
12.7 PLEG核心原理 652
12.7.1 PLEG产生原因 652
12.7.2 PLEG架构设计 652
12.7.3 PLEG原理剖析 653
12.8 HTTP服务接口 657
12.8.1 日志查询接口 659
12.8.2 命令执行接口 666
12.8.3 端口转发接口 673
第13章 代码生成器【通过读者服务二维码获取】 679
附录A Kubernetes组件配置参数介绍【通过读者服务二维码获取】 680
展开
前言
近几年,容器技术的使用迅速增加。容器技术的火热推动了容器编排技术的发展,目前非常受欢迎的容器编排系统是Kubernetes,它引领技术潮流,可以应对生产环境中编排容器所需的额外复杂度及成本。Kubernetes帮助企业加快容器编排的速度,并实现对多容器集群的大规模管理。它允许持续集成和交付、网络处理、服务发现、存储服务等,并且具有在多云环境中进行操作的能力。
为何说掌控Kubernetes等于掌控了云计算的未来?在过去几年里,Kubernetes一直在飞速发展,社区也随之发展壮大,截至本书截稿时,Kubernetes项目在GitHub上已经拥有10?万多颗星星,以及11万多提交量。
Kubernetes已经越来越成熟,很多企业从试水阶段逐步走向大规模落地阶段。虽然Kubernetes的稳定和成熟导致了代码迭代能力逐渐变弱,但底层代码的成熟及健壮性能够支撑更大的上层应用,更多优秀的生态应用围绕Kubernetes各自发展。这得益于Kubernetes的高扩展性,它越来越像一个操作系统核心(Kernel),对外提供通用接口,制定了众多标准。如今,Kubernetes得到了许多云计算服务提供商(Cloud Provider),如Google、Cisco、VMware、Microsoft、Amazon等技术巨头的支持。
建议大家在阅读Kubernetes源码的过程中,学习一些设计模式(Design Pattern),这会帮助大家理解源码的实现原理,而非只是泛泛地看懂代码但没有理解其原理。例如,在Go语言中,常用NewXXX函数来实例化相关类,在设计模式中,它被称为简单工厂模式,该模式在Go语言中替代了其他语言的类似构造函数的功能。不同语言的设计模式原理基本类似,只是在语法上的实现方式不同。对于Go语言的设计模式,大家可以参考Go Design Pattern。
本书将Kubernetes 1.25.0版本源码作为剖析对象。学习Kubernetes代码库并不容易,它拥有大量的源码,但在学习过程中我们会收益良多。在本书中,我们将深入研究并分析Kubernetes源码的关键部分。在阅读本书时,建议同时参考Kubernetes源码。
Kubernetes源码阅读建议
阅读Kubernetes源码是了解Kubernetes内部工作原理和提高自己技能的重要途径。以下是一些建议,可以帮助大家更好地阅读Kubernetes源码。
(1)了解基本概念和架构:在阅读Kubernetes源码之前,确保你已经熟悉Kubernetes的基本概念(如Pod、Deployment、Service等)及核心组件(如kube-apiserver、kube-controller-manager、kube-scheduler、kubelet和etcd)。这些知识将有助于你理解源码中的一些设计决策。
(2)熟悉Go语言:Kubernetes主要使用Go语言编写,因此熟悉Go语言的语法、编程规范和标准库是很有必要的。Go语言的官方文档是一个很好的学习资源。
(3)从一个关注点开始:Kubernetes是一个庞大且复杂的项目,试图一次性掌握所有Kubernetes源码可能会令人生畏。你最好先选择一个特定的关注点,如API、调度器、控制器或网络,然后逐步深入了解。
(4)阅读文档和博客:Kubernetes官方文档中包含许多关于项目设计和实现的信息。此外,社区中的开发者和用户经常分享他们的经验和见解。利用这些资源,你可以更好地了解Kubernetes源码的原理。
(5)跟踪代码执行流程:当你开始阅读Kubernetes源码时,可以从主要组件(如kube-apiserver、kube-controller-manager或kube-scheduler)开始,跟踪代码执行流程。这有助于你了解各组件的内部逻辑和组件之间的交互。
(6)阅读测试代码:Kubernetes项目包含大量的测试代码,阅读这些测试代码可以帮助你理解功能的实现及如何在实际环境中使用这些功能。
(7)参与社区:Kubernetes社区非常活跃,你可以通过参加SIG(Special Interest Group)会议、加入Slack或邮件列表来了解项目动态和发展方向。与其他开发者和用户交流可以加深你对Kubernetes源码的理解。
(8)动手实践:通过对Kubernetes源码进行修改和编译,尝试实现一些自定义功能或解决一些问题,可以帮助你更好地理解源码的结构和工作原理。
(9)使用调试工具:使用调试工具(如Delve)可以帮助你更好地理解代码的执行过程,找到感兴趣的函数和代码片段。
阅读大型开源项目的源码可能需要一定的时间和毅力。不要期望立即掌握所有内容。随着你不断地阅读、实践和参与社区讨论,你会逐渐积累经验,加深理解。请保持耐心并持续学习,随着时间的推移,你会对Kubernetes源码有更深入的了解。
展开