华信教育资源网
深入理解Kubernetes源码
作   译   者:郑东旭 等 出 版 日 期:2024-08-01
出   版   社:电子工业出版社 维   护   人:符隆美 
书   代   号:TP483230 I S B N:9787121483233

编辑推荐:

√专家力荐:业内专家曹伟(鸣嵩)、刘君倾情力荐。√深入解析:以Kubernetes 1.25.0源码为基础,详解核心组件和实现原理,带你全面掌握容器编排技术。√提升竞争力:通过学习Kubernetes源码,提升在云计算领域的专业能力,增强职业竞争力。√实用指南:帮助开发者、运维工程师及架构师高效管理大规模多容器集群,应对生产环境中的复杂编排需求。√技术精髓:适合对容器技术和云计算感兴趣的读者,深入了解Kubernetes,掌握前沿技术,迈向技术巅峰。
您的专属联系人更多
关注 评论(0) 分享
配套资源 图书内容 样章/电子教材 图书评价
  • 配 套 资 源

    本书资源

    本书暂无资源

    会员上传本书资源

  • 图 书 内 容

    内容简介

    在过去几年中,容器技术的广泛应用推动了容器编排技术的迅猛发展,尤其是Kubernetes的兴起。作为当前非常受欢迎的容器编排系统,Kubernetes能够有效应对生产环境中复杂的编排需求,帮助企业实现大规模多容器集群的高效管理。本书将Kubernetes 1.25.0版本源码作为剖析对象,深入探讨其核心组件和实现原理。通过学习Kubernetes源码,读者不仅能掌握容器编排技术的精髓,还能提升自身在云计算领域的竞争力。本书适合对容器技术和云计算感兴趣的开发者、运维工程师及架构师参考和阅读。

    图书详情

    ISBN:9787121483233
    开 本:16(185*260)
    页 数:696
    字 数:1170

    本书目录

    第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源码有更深入的了解。
    展开

    作者简介

    郑东旭(Derek Zheng),BFE(万亿流量转发引擎)开源项目的作者之一,擅长Linux下高性能服务器的开发,对云计算、区块链相关技术领域有深刻的理解。邱世达,云原生技术专家,热爱开源事业,长期参与Kubernetes社区贡献,Kubernetes Contributor Top 30,Sig Cluster Lifecycle成员,Kubeadm项目维护者之一,具备多年云计算领域研究工作经验。冀超,曾在百度等多家互联网公司任职,参与过公有云和公司内的云原生平台建设,具有多年Kubernetes使用和开发经验。李晋林,长期致力于云原生领域,对Kubernetes有深入理解和研究。在金融交易系统中拥有多年的Kubernetes使用和二次开发经验,主要主导公司业务上云、线上流量迁移等工作。杨川胡(阳明),云原生爱好者,k8s技术圈社区作者,云原生学习网站优点知识创始人。周世伟,资深码农,云原生爱好者和践行者,擅长Kubernetes、服务网格开发,技术宅。
  • 样 章 试 读
    本书暂无样章试读!
  • 图 书 评 价 我要评论
华信教育资源网