-
Notifications
You must be signed in to change notification settings - Fork 127
/
Copy pathkube_apiserver.html
2336 lines (1606 loc) · 145 KB
/
kube_apiserver.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE HTML>
<html lang="zh-hans" >
<head>
<meta charset="UTF-8">
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>kube-apiserver 的设计与实现 · 田飞雨</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="description" content="">
<meta name="generator" content="GitBook 3.2.3">
<meta name="author" content="gosoon">
<link rel="stylesheet" href="../gitbook/style.css">
<link rel="stylesheet" href="../gitbook/gitbook-plugin-search-plus/search.css">
<link rel="stylesheet" href="../gitbook/gitbook-plugin-prism/prism-base16-ateliersulphurpool.light.css">
<link rel="stylesheet" href="../gitbook/gitbook-plugin-advanced-emoji/emoji-website.css">
<link rel="stylesheet" href="../gitbook/gitbook-plugin-anchors/plugin.css">
<link rel="stylesheet" href="../gitbook/gitbook-plugin-ace/ace.css">
<link rel="stylesheet" href="../gitbook/gitbook-plugin-emphasize/plugin.css">
<link rel="stylesheet" href="../gitbook/gitbook-plugin-katex/katex.min.css">
<link rel="stylesheet" href="../gitbook/gitbook-plugin-splitter/splitter.css">
<link rel="stylesheet" href="../gitbook/gitbook-plugin-mermaid-gb3/mermaid/mermaid.css">
<link rel="stylesheet" href="../gitbook/gitbook-plugin-tbfed-pagefooter/footer.css">
<link rel="stylesheet" href="../gitbook/gitbook-plugin-expandable-chapters-small/expandable-chapters-small.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="../gitbook/gitbook-plugin-sectionx/sectionx.css">
<link rel="stylesheet" href="../gitbook/gitbook-plugin-local-video/video-js.min.css">
<link rel="stylesheet" href="../gitbook/gitbook-plugin-anchor-navigation-ex/style/plugin.css">
<link rel="stylesheet" href="../gitbook/gitbook-plugin-terminal/plugin.css">
<link rel="stylesheet" href="../gitbook/gitbook-plugin-alerts/style.css">
<link rel="stylesheet" href="../gitbook/gitbook-plugin-versions-select/plugin.css">
<link rel="stylesheet" href="../gitbook/gitbook-plugin-fontsettings/website.css">
<link rel="stylesheet" href="../gitbook/gitbook-plugin-theme-comscore/test.css">
<link rel="stylesheet" href="../styles/website.css">
<meta name="HandheldFriendly" content="true"/>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<link rel="apple-touch-icon-precomposed" sizes="152x152" href="../gitbook/images/apple-touch-icon-precomposed-152.png">
<link rel="shortcut icon" href="../gitbook/images/favicon.ico" type="image/x-icon">
<link rel="next" href="apiserver_bootstrap_controller.html" />
<link rel="prev" href="./" />
<link rel="stylesheet" href="../gitbook/gitbook-plugin-chart/c3/c3.min.css">
<script src="../gitbook/gitbook-plugin-chart/c3/d3.min.js"></script>
<script src="../gitbook/gitbook-plugin-chart/c3/c3.min.js"></script>
<script src="../gitbook/gitbook-plugin-graph/d3.min.js"></script>
<script src="../gitbook/gitbook-plugin-graph/function-plot.js"></script>
<link rel="shortcut icon" href='../favicon.ico' type="image/x-icon">
<link rel="bookmark" href='../favicon.ico' type="image/x-icon">
<style>
@media only screen and (max-width: 640px) {
.book-header .hidden-mobile {
display: none;
}
}
</style>
<script>
window["gitbook-plugin-github-buttons"] = {"repo":"gosoon/source-code-reading-notes","types":["star"],"size":"large"};
</script>
</head>
<body>
<div class="book">
<div class="book-summary">
<div id="book-search-input" role="search">
<input type="text" placeholder="输入并搜索" />
</div>
<nav role="navigation">
<ul class="summary">
<li>
<a href="https://blog.tianfeiyu.com" target="_blank" class="custom-link">Home</a>
</li>
<li class="divider"></li>
<li class="chapter " data-level="1.1" data-path="../">
<a href="../">
<b>1.1.</b>
Introduction
</a>
</li>
<li class="chapter " data-level="1.2" data-path="./">
<a href="./">
<b>1.2.</b>
kubernetes
</a>
<ul class="articles">
<li class="chapter active" data-level="1.2.1" data-path="kube_apiserver.html">
<a href="kube_apiserver.html">
<b>1.2.1.</b>
kube-apiserver 的设计与实现
</a>
</li>
<li class="chapter " data-level="1.2.2" data-path="apiserver_bootstrap_controller.html">
<a href="apiserver_bootstrap_controller.html">
<b>1.2.2.</b>
kube-apiserver 中 apiserver service 的实现
</a>
</li>
<li class="chapter " data-level="1.2.3" data-path="nodelifecycle_controller.html">
<a href="nodelifecycle_controller.html">
<b>1.2.3.</b>
node controller 源码分析
</a>
</li>
<li class="chapter " data-level="1.2.4" data-path="job_controller.html">
<a href="job_controller.html">
<b>1.2.4.</b>
job controller 源码分析
</a>
</li>
<li class="chapter " data-level="1.2.5" data-path="garbagecollector_controller.html">
<a href="garbagecollector_controller.html">
<b>1.2.5.</b>
garbage collector controller 源码分析
</a>
</li>
<li class="chapter " data-level="1.2.6" data-path="daemonset_controller.html">
<a href="daemonset_controller.html">
<b>1.2.6.</b>
daemonset controller 源码分析
</a>
</li>
<li class="chapter " data-level="1.2.7" data-path="statefulset_controller.html">
<a href="statefulset_controller.html">
<b>1.2.7.</b>
statefulset controller 源码分析
</a>
</li>
<li class="chapter " data-level="1.2.8" data-path="deployment_controller.html">
<a href="deployment_controller.html">
<b>1.2.8.</b>
deployment controller 源码分析
</a>
</li>
<li class="chapter " data-level="1.2.9" data-path="replicaset_controller.html">
<a href="replicaset_controller.html">
<b>1.2.9.</b>
replicaset controller 源码分析
</a>
</li>
<li class="chapter " data-level="1.2.10" data-path="kube_scheduler_process.html">
<a href="kube_scheduler_process.html">
<b>1.2.10.</b>
kube-scheduler 源码分析
</a>
</li>
<li class="chapter " data-level="1.2.11" data-path="kube_scheduler_algorithm.html">
<a href="kube_scheduler_algorithm.html">
<b>1.2.11.</b>
kube-scheduler predicates 与 priorities 调度算法源码分析
</a>
</li>
<li class="chapter " data-level="1.2.12" data-path="kube_scheduler_preempt.html">
<a href="kube_scheduler_preempt.html">
<b>1.2.12.</b>
kube-scheduler 优先级与抢占机制源码分析
</a>
</li>
<li class="chapter " data-level="1.2.13" data-path="k8s_service_theory.html">
<a href="k8s_service_theory.html">
<b>1.2.13.</b>
kubernetes service 原理解析
</a>
</li>
<li class="chapter " data-level="1.2.14" data-path="kube_proxy_process.html">
<a href="kube_proxy_process.html">
<b>1.2.14.</b>
kube-proxy 源码分析
</a>
</li>
<li class="chapter " data-level="1.2.15" data-path="kube_proxy_iptables.html">
<a href="kube_proxy_iptables.html">
<b>1.2.15.</b>
kube-proxy iptables 模式源码分析
</a>
</li>
<li class="chapter " data-level="1.2.16" data-path="kube_proxy_ipvs.html">
<a href="kube_proxy_ipvs.html">
<b>1.2.16.</b>
kube-proxy ipvs 模式源码分析
</a>
</li>
<li class="chapter " data-level="1.2.17" data-path="kubelet-modules.html">
<a href="kubelet-modules.html">
<b>1.2.17.</b>
kubelet 架构浅析
</a>
</li>
<li class="chapter " data-level="1.2.18" data-path="kubelet_init.html">
<a href="kubelet_init.html">
<b>1.2.18.</b>
kubelet 启动流程分析
</a>
</li>
<li class="chapter " data-level="1.2.19" data-path="kubelet_create_pod.html">
<a href="kubelet_create_pod.html">
<b>1.2.19.</b>
kubelet 创建 pod 的流程
</a>
</li>
<li class="chapter " data-level="1.2.20" data-path="node_status.html">
<a href="node_status.html">
<b>1.2.20.</b>
kubelet 状态上报的方式
</a>
</li>
<li class="chapter " data-level="1.2.21" data-path="k8s_events.html">
<a href="k8s_events.html">
<b>1.2.21.</b>
kubelet 中事件处理机制
</a>
</li>
<li class="chapter " data-level="1.2.22" data-path="kubelet_status_manager.html">
<a href="kubelet_status_manager.html">
<b>1.2.22.</b>
kubelet statusManager 源码分析
</a>
</li>
<li class="chapter " data-level="1.2.23" data-path="kubelet_qos.html">
<a href="kubelet_qos.html">
<b>1.2.23.</b>
kubernetes 中 Qos 的设计与实现
</a>
</li>
<li class="chapter " data-level="1.2.24" data-path="kubelet_garbage_collect.html">
<a href="kubelet_garbage_collect.html">
<b>1.2.24.</b>
kubelet 中垃圾回收机制的设计与实现
</a>
</li>
<li class="chapter " data-level="1.2.25" data-path="k8s_evicted.html">
<a href="k8s_evicted.html">
<b>1.2.25.</b>
kubernetes 中 Evicted pod 是如何产生的
</a>
</li>
<li class="chapter " data-level="1.2.26" data-path="kubernetes_descheduler.html">
<a href="kubernetes_descheduler.html">
<b>1.2.26.</b>
Kubernetes 中 Descheduler 组件的使用与扩展
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="1.3" data-path="../knative/">
<a href="../knative/">
<b>1.3.</b>
knative
</a>
<ul class="articles">
<li class="chapter " data-level="1.3.1" data-path="../knative/deploy_with_minkube.html">
<a href="../knative/deploy_with_minkube.html">
<b>1.3.1.</b>
在 minkube 上部署 knative
</a>
</li>
<li class="chapter " data-level="1.3.2" data-path="../knative/knative_serving.html">
<a href="../knative/knative_serving.html">
<b>1.3.2.</b>
knative serving 组件分析
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="1.4" data-path="../cgroup/">
<a href="../cgroup/">
<b>1.4.</b>
cgroup
</a>
<ul class="articles">
<li class="chapter " data-level="1.4.1" data-path="../cgroup/blkio_cgroup.html">
<a href="../cgroup/blkio_cgroup.html">
<b>1.4.1.</b>
blkio cgroup
</a>
</li>
<li class="chapter " data-level="1.4.2" data-path="../cgroup/pid_cgroup.html">
<a href="../cgroup/pid_cgroup.html">
<b>1.4.2.</b>
pid cgroup
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="1.5" data-path="../go/">
<a href="../go/">
<b>1.5.</b>
go
</a>
<ul class="articles">
<li class="chapter " data-level="1.5.1" data-path="../go/func_return_value_or_pointer.html">
<a href="../go/func_return_value_or_pointer.html">
<b>1.5.1.</b>
golang 中函数使用值返回与指针返回的区别,底层原理分析
</a>
</li>
<li class="chapter " data-level="1.5.2" data-path="../go/golang_bootstrap.html">
<a href="../go/golang_bootstrap.html">
<b>1.5.2.</b>
Golang 程序启动流程分析
</a>
</li>
<li class="chapter " data-level="1.5.3" data-path="../go/golang_gpm.html">
<a href="../go/golang_gpm.html">
<b>1.5.3.</b>
Golang GPM 模型剖析
</a>
</li>
</ul>
</li>
<li class="divider"></li>
<li>
<a href="https://www.gitbook.com" target="blank" class="gitbook-link">
本书使用 GitBook 发布
</a>
</li>
</ul>
</nav>
</div>
<div class="book-body">
<div class="body-inner">
<div class="book-header" role="navigation">
<!-- Title -->
<h1>
<i class="fa fa-circle-o-notch fa-spin"></i>
<a href=".." >kube-apiserver 的设计与实现</a>
</h1>
</div>
<div class="page-wrapper" tabindex="-1" role="main">
<div class="page-inner">
<div id="book-search-results">
<div class="search-noresults">
<section class="normal markdown-section">
<ul>
<li><a href="#kube-apiserver-处理流程">kube-apiserver 处理流程</a></li>
<li><a href="#kube-apiserver--中的组件">kube-apiserver 中的组件</a><ul>
<li><a href="#aggregator">Aggregator</a><ul>
<li><a href="#启用-api-aggregation">启用 API Aggregation</a></li>
</ul>
</li>
<li><a href="#kubeapiserver">KubeAPIServer</a></li>
<li><a href="#apiextensionserver">APIExtensionServer</a></li>
</ul>
</li>
<li><a href="#kube-apiserver-启动流程分析">kube-apiserver 启动流程分析</a><ul>
<li><a href="#run">Run</a></li>
<li><a href="#createserverchain">CreateServerChain</a><ul>
<li><a href="#createkubeapiserverconfig">CreateKubeAPIServerConfig</a></li>
<li><a href="#buildgenericconfig">buildGenericConfig</a></li>
<li><a href="#createapiextensionsserver">createAPIExtensionsServer</a></li>
<li><a href="#createkubeapiserver">CreateKubeAPIServer</a></li>
<li><a href="#kubeapiserverconfigcompletenew">kubeAPIServerConfig.Complete().New</a></li>
<li><a href="#minstalllegacyapi">m.InstallLegacyAPI</a></li>
</ul>
</li>
<li><a href="#createaggregatorserver">createAggregatorServer</a><ul>
<li><a href="#aggregatorconfigcompletenewwithdelegate">aggregatorConfig.Complete().NewWithDelegate</a></li>
</ul>
</li>
<li><a href="#preparedrun">prepared.Run</a><ul>
<li><a href="#snonblockingrun">s.NonBlockingRun</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#storagefactory-的构建">storageFactory 的构建</a><ul>
<li><a href="#newlegacyreststorage">NewLegacyRESTStorage</a><ul>
<li><a href="#podstorenewstorage">podstore.NewStorage</a></li>
<li><a href="#storecompletewithoptions">store.CompleteWithOptions</a><ul>
<li><a href="#newetcd3storage">newETCD3Storage</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#路由注册">路由注册</a><ul>
<li><a href="#aregisterresourcehandlers">a.registerResourceHandlers</a></li>
<li><a href="#restfulcreatenamedresource">restfulCreateNamedResource</a></li>
<li><a href="#createhandler">createHandler</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#总结">总结</a></li>
</ul>
<p>kube-apiserver 是 kubernetes 中与 etcd 直接交互的一个组件,其控制着 kubernetes 中核心资源的变化。它主要提供了以下几个功能:</p>
<ul>
<li>提供 <a href="https://kubernetes.io/docs/concepts/overview/kubernetes-api/" target="_blank">Kubernetes API</a>,包括认证授权、数据校验以及集群状态变更等,供客户端及其他组件调用;</li>
<li>代理集群中的一些附加组件组件,如 Kubernetes UI、metrics-server、npd 等;</li>
<li>创建 kubernetes 服务,即提供 apiserver 的 Service,kubernetes Service;</li>
<li>资源在不同版本之间的转换;</li>
</ul>
<h3 id="kube-apiserver-处理流程"><a name="kube-apiserver-处理流程" class="anchor-navigation-ex-anchor" href="#kube-apiserver-处理流程"><i class="fa fa-link" aria-hidden="true"></i></a>kube-apiserver 处理流程</h3>
<p>kube-apiserver 主要通过对外提供 API 的方式与其他组件进行交互,可以调用 kube-apiserver 的接口 <code>$ curl -k https://<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>masterIP</span><span class="token punctuation">></span></span>:6443</code>或者通过其提供的 <strong>swagger-ui</strong> 获取到,其主要有以下三种 API:</p>
<ul>
<li>core group:主要在 <code>/api/v1</code> 下;</li>
<li>named groups:其 path 为 <code>/apis/$NAME/$VERSION</code>;</li>
<li>暴露系统状态的一些 API:如<code>/metrics</code> 、<code>/healthz</code> 等;</li>
</ul>
<p>API 的 URL 大致以 <code>/apis/group/version/namespaces/my-ns/myresource</code> 组成,其中 API 的结构大致如下图所示:</p>
<p><img src="http://cdn.tianfeiyu.com/API-server-space-1.png" alt=""></p>
<p>了解了 kube-apiserver 的 API 后,下面会介绍 kube-apiserver 如何处理一个 API 请求,一个请求完整的流程如下图所示:</p>
<p><img src="http://cdn.tianfeiyu.com/API-server-flow-2.png" alt=""></p>
<p>此处以一次 POST 请求示例说明,当请求到达 kube-apiserver 时,kube-apiserver 首先会执行在 http filter chain 中注册的过滤器链,该过滤器对其执行一系列过滤操作,主要有认证、鉴权等检查操作。当 filter chain 处理完成后,请求会通过 route 进入到对应的 handler 中,handler 中的操作主要是与 etcd 的交互,在 handler 中的主要的操作如下所示:</p>
<p><img src="http://cdn.tianfeiyu.com/API-server-storage-flow-2.png" alt="API-server-storage-flow-2"></p>
<p><strong>Decoder</strong></p>
<p>kubernetes 中的多数 resource 都会有一个 <code>internal version</code>,因为在整个开发过程中一个 resource 可能会对应多个 version,比如 deployment 会有 <code>extensions/v1beta1</code>,<code>apps/v1</code>。 为了避免出现问题,kube-apiserver 必须要知道如何在每一对版本之间进行转换(例如,v1⇔v1alpha1,v1⇔v1beta1,v1beta1⇔v1alpha1),因此其使用了一个特殊的<code>internal version</code>,<code>internal version</code> 作为一个通用的 version 会包含所有 version 的字段,它具有所有 version 的功能。 Decoder 会首先把 creater object 转换到 <code>internal version</code>,然后将其转换为 <code>storage version</code>,<code>storage version</code> 是在 etcd 中存储时的另一个 version。</p>
<p>在解码时,首先从 HTTP path 中获取期待的 version,然后使用 scheme 以正确的 version 创建一个与之匹配的空对象,并使用 JSON 或 protobuf 解码器进行转换,在转换的第一步中,如果用户省略了某些字段,Decoder 会把其设置为默认值。</p>
<p><strong>Admission</strong></p>
<p>在解码完成后,需要通过验证集群的全局约束来检查是否可以创建或更新对象,并根据集群配置设置默认值。在 <code>k8s.io/kubernetes/plugin/pkg/admission</code> 目录下可以看到 kube-apiserver 可以使用的所有全局约束插件,kube-apiserver 在启动时通过设置 <code>--enable-admission-plugins</code> 参数来开启需要使用的插件,通过 <code>ValidatingAdmissionWebhook</code> 或 <code>MutatingAdmissionWebhook</code> 添加的插件也都会在此处进行工作。</p>
<p><strong>Validation</strong></p>
<p>主要检查 object 中字段的合法性。</p>
<p>在 handler 中执行完以上操作后最后会执行与 etcd 相关的操作,POST 操作会将数据写入到 etcd 中,以上在 handler 中的主要处理流程如下所示:</p>
<pre class="language-"><code>v1beta1 ⇒ internal ⇒ | ⇒ | ⇒ v1 ⇒ json/yaml ⇒ etcd
admission validation
</code></pre><h3 id="kube-apiserver--中的组件"><a name="kube-apiserver--中的组件" class="anchor-navigation-ex-anchor" href="#kube-apiserver--中的组件"><i class="fa fa-link" aria-hidden="true"></i></a>kube-apiserver 中的组件</h3>
<p>kube-apiserver 共由 3 个组件构成(Aggregator、KubeAPIServer、APIExtensionServer),这些组件依次通过 Delegation 处理请求:</p>
<ul>
<li><strong>Aggregator</strong>:暴露的功能类似于一个七层负载均衡,将来自用户的请求拦截转发给其他服务器,并且负责整个 APIServer 的 Discovery 功能;</li>
<li><strong>KubeAPIServer</strong> :负责对请求的一些通用处理,认证、鉴权等,以及处理各个内建资源的 REST 服务;</li>
<li><strong>APIExtensionServer</strong>:主要处理 CustomResourceDefinition(CRD)和 CustomResource(CR)的 REST 请求,也是 Delegation 的最后一环,如果对应 CR 不能被处理的话则会返回 404。</li>
</ul>
<p>Aggregator 和 APIExtensionsServer 对应两种主要扩展 APIServer 资源的方式,即分别是 AA 和 CRD。</p>
<h4 id="aggregator"><a name="aggregator" class="anchor-navigation-ex-anchor" href="#aggregator"><i class="fa fa-link" aria-hidden="true"></i></a>Aggregator</h4>
<p>Aggregator 通过 APIServices 对象关联到某个 Service 来进行请求的转发,其关联的 Service 类型进一步决定了请求转发形式。Aggregator 包括一个 <code>GenericAPIServer</code> 和维护自身状态的 Controller。其中 <code>GenericAPIServer</code> 主要处理 <code>apiregistration.k8s.io</code> 组下的 APIService 资源请求。</p>
<p><strong>Aggregator 除了处理资源请求外还包含几个 controller:</strong></p>
<ul>
<li>1、<code>apiserviceRegistrationController</code>:负责 APIServices 中资源的注册与删除;</li>
<li>2、<code>availableConditionController</code>:维护 APIServices 的可用状态,包括其引用 Service 是否可用等;</li>
<li>3、<code>autoRegistrationController</code>:用于保持 API 中存在的一组特定的 APIServices;</li>
<li>4、<code>crdRegistrationController</code>:负责将 CRD GroupVersions 自动注册到 APIServices 中;</li>
<li>5、<code>openAPIAggregationController</code>:将 APIServices 资源的变化同步至提供的 OpenAPI 文档;</li>
</ul>
<p>kubernetes 中的一些附加组件,比如 metrics-server 就是通过 Aggregator 的方式进行扩展的,实际环境中可以通过使用 <a href="https://github.com/kubernetes-sigs/apiserver-builder-alpha" target="_blank">apiserver-builder</a> 工具轻松以 Aggregator 的扩展方式创建自定义资源。</p>
<h5 id="启用-api-aggregation"><a name="启用-api-aggregation" class="anchor-navigation-ex-anchor" href="#启用-api-aggregation"><i class="fa fa-link" aria-hidden="true"></i></a>启用 API Aggregation</h5>
<p>在 kube-apiserver 中需要增加以下配置来开启 API Aggregation:</p>
<pre class="language-"><code>--proxy-client-cert-file=/etc/kubernetes/certs/proxy.crt
--proxy-client-key-file=/etc/kubernetes/certs/proxy.key
--requestheader-client-ca-file=/etc/kubernetes/certs/proxy-ca.crt
--requestheader-allowed-names=aggregator
--requestheader-extra-headers-prefix=X-Remote-Extra-
--requestheader-group-headers=X-Remote-Group
--requestheader-username-headers=X-Remote-User
</code></pre><h4 id="kubeapiserver"><a name="kubeapiserver" class="anchor-navigation-ex-anchor" href="#kubeapiserver"><i class="fa fa-link" aria-hidden="true"></i></a>KubeAPIServer</h4>
<p>KubeAPIServer 主要是提供对 API Resource 的操作请求,为 kubernetes 中众多 API 注册路由信息,暴露 RESTful API 并且对外提供 kubernetes service,使集群中以及集群外的服务都可以通过 RESTful API 操作 kubernetes 中的资源。</p>
<h4 id="apiextensionserver"><a name="apiextensionserver" class="anchor-navigation-ex-anchor" href="#apiextensionserver"><i class="fa fa-link" aria-hidden="true"></i></a>APIExtensionServer</h4>
<p>APIExtensionServer 作为 Delegation 链的最后一层,是处理所有用户通过 Custom Resource Definition 定义的资源服务器。</p>
<p>其中包含的 controller 以及功能如下所示:</p>
<ul>
<li>1、<code>openapiController</code>:将 crd 资源的变化同步至提供的 OpenAPI 文档,可通过访问 <code>/openapi/v2</code> 进行查看;</li>
<li>2、<code>crdController</code>:负责将 crd 信息注册到 apiVersions 和 apiResources 中,两者的信息可通过 <code>$ kubectl api-versions</code> 和 <code>$ kubectl api-resources</code> 查看;</li>
<li>3、<code>namingController</code>:检查 crd obj 中是否有命名冲突,可在 crd <code>.status.conditions</code> 中查看;</li>
<li>4、<code>establishingController</code>:检查 crd 是否处于正常状态,可在 crd <code>.status.conditions</code> 中查看;</li>
<li>5、<code>nonStructuralSchemaController</code>:检查 crd obj 结构是否正常,可在 crd <code>.status.conditions</code> 中查看;</li>
<li>6、<code>apiApprovalController</code>:检查 crd 是否遵循 kubernetes API 声明策略,可在 crd <code>.status.conditions</code> 中查看;</li>
<li>7、<code>finalizingController</code>:类似于 finalizes 的功能,与 CRs 的删除有关;</li>
</ul>
<h3 id="kube-apiserver-启动流程分析"><a name="kube-apiserver-启动流程分析" class="anchor-navigation-ex-anchor" href="#kube-apiserver-启动流程分析"><i class="fa fa-link" aria-hidden="true"></i></a>kube-apiserver 启动流程分析</h3>
<blockquote>
<p>kubernetes 版本:v1.16</p>
</blockquote>
<p>首先分析 kube-apiserver 的启动方式,kube-apiserver 也是通过其 <code>Run</code> 方法启动主逻辑的,在<code>Run</code> 方法调用之前会进行解析命令行参数、设置默认值等。</p>
<h4 id="run"><a name="run" class="anchor-navigation-ex-anchor" href="#run"><i class="fa fa-link" aria-hidden="true"></i></a>Run</h4>
<p><code>Run</code> 方法的主要逻辑为:</p>
<ul>
<li>1、调用 <code>CreateServerChain</code> 构建服务调用链并判断是否启动非安全的 http server,http server 链中包含 apiserver 要启动的三个 server,以及为每个 server 注册对应资源的路由;</li>
<li>2、调用 <code>server.PrepareRun</code> 进行服务运行前的准备,该方法主要完成了健康检查、存活检查和<code>OpenAPI</code>路由的注册工作;</li>
<li>3、调用 <code>prepared.Run</code> 启动 https server;</li>
</ul>
<p>server 的初始化使用委托模式,通过 DelegationTarget 接口,把基本的 API Server、CustomResource、Aggregator 这三种服务采用链式结构串联起来,对外提供服务。</p>
<p><code>k8s.io/kubernetes/cmd/kube-apiserver/app/server.go:147</code></p>
<pre class="language-"><code>func Run(completeOptions completedServerRunOptions, stopCh <-chan struct{}) error {
server, err := CreateServerChain(completeOptions, stopCh)
if err != nil {
return err
}
prepared, err := server.PrepareRun()
if err != nil {
return err
}
return prepared.Run(stopCh)
}
</code></pre><h4 id="createserverchain"><a name="createserverchain" class="anchor-navigation-ex-anchor" href="#createserverchain"><i class="fa fa-link" aria-hidden="true"></i></a>CreateServerChain</h4>
<p><code>CreateServerChain</code> 是完成 server 初始化的方法,里面包含 <code>APIExtensionsServer</code>、<code>KubeAPIServer</code>、<code>AggregatorServer</code> 初始化的所有流程,最终返回 <code>aggregatorapiserver.APIAggregator</code> 实例,初始化流程主要有:http filter chain 的配置、API Group 的注册、http path 与 handler 的关联以及 handler 后端存储 etcd 的配置。其主要逻辑为:</p>
<ul>
<li>1、调用 <code>CreateKubeAPIServerConfig</code> 创建 KubeAPIServer 所需要的配置,主要是创建 <code>master.Config</code>,其中会调用 <code>buildGenericConfig</code> 生成 genericConfig,genericConfig 中包含 apiserver 的核心配置;</li>