-
Notifications
You must be signed in to change notification settings - Fork 127
/
Copy pathkubernetes_descheduler.html
1121 lines (511 loc) · 64.2 KB
/
kubernetes_descheduler.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>Kubernetes 中 Descheduler 组件的使用与扩展 · 田飞雨</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="../knative/" />
<link rel="prev" href="k8s_evicted.html" />
<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 " 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 active" 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=".." >Kubernetes 中 Descheduler 组件的使用与扩展</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="#descheduler-组件简介">Descheduler 组件简介</a></li>
<li><a href="#descheduler-策略介绍">Descheduler 策略介绍</a></li>
<li><a href="#descheduler-功能扩展">Descheduler 功能扩展</a><ul>
<li><a href="#lownodeutilization-策略扩展">LowNodeUtilization 策略扩展</a><ul>
<li><a href="#1通过告警回调触发">1、通过告警回调触发</a></li>
<li><a href="#2节点利用率预测">2、节点利用率预测</a></li>
</ul>
</li>
<li><a href="#highnodeutilization-策略扩展">HighNodeUtilization 策略扩展</a></li>
</ul>
</li>
<li><a href="#descheduler-pod-迁移场景中的约束策略">Descheduler Pod 迁移场景中的约束策略</a></li>
<li><a href="#descheduler-pod-迁移的效果分析">Descheduler Pod 迁移的效果分析</a></li>
<li><a href="#总结">总结</a></li>
</ul>
<h3 id="descheduler-组件简介"><a name="descheduler-组件简介" class="anchor-navigation-ex-anchor" href="#descheduler-组件简介"><i class="fa fa-link" aria-hidden="true"></i></a>Descheduler 组件简介</h3>
<p>实例在新建时,调度器可以根据当时集群状态选择最优节点进行调度,但集群内资源使用状况是动态变化的,集群在一段时间内就会出现不均衡的状态,需要 Descheduler 将节点上已经运行的 pods 迁移到其他节点,使集群内资源分布达到一个比较均衡的状态。有以下几个原因我们希望将节点上运行的实例迁移到其他节点:</p>
<ul>
<li>节点上 pod 利用率的变化导致某些节点利用率过低或者过高;</li>
<li>节点标签变化导致 pod 的亲和与反亲和策略不满足要求;</li>
<li>新节点上线与故障节点下线;</li>
</ul>
<p>descheduler 会根据相关的策略挑选出节点需要迁移的实例然后删除实例,新实例会重新通过 kube-scheduler 进行调度到合适的节点上。descheduler 迁移实例的策略需要与 kube-scheduler 的策略共同使用,二者是相辅相成的。</p>
<p>使用 descheduler 的目的主要有两点,一是为了提升集群的稳定性,二是为了提高集群的资源利用率。</p>
<h3 id="descheduler-策略介绍"><a name="descheduler-策略介绍" class="anchor-navigation-ex-anchor" href="#descheduler-策略介绍"><i class="fa fa-link" aria-hidden="true"></i></a>Descheduler 策略介绍</h3>
<p>针对以上几个问题,descheduler 提供了一系列策略让使用者可以根据一些规则和配置来重新平衡集群状态,达到一个理想的效果,其核心原理是根据策略配置找到可以被迁移的 pod 并驱逐它们,其本身并不会进行调度被驱逐的 Pod,而是依靠默认的调度器来实现,当前支持的策略有十种:</p>
<table>
<thead>
<tr>
<th style="text-align:left">策略</th>
<th style="text-align:left">描述</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left">RemoveDuplicates</td>
<td style="text-align:left">将节点上同类型的Pod进行迁移,确保只有一个Pod与同一节点上运行的ReplicaSet、Replication Controller、StatefulSet或者Job关联。</td>
</tr>
<tr>
<td style="text-align:left">LowNodeUtilization</td>
<td style="text-align:left">将 requests 比率较高节点上的Pod进行迁移。</td>
</tr>
<tr>
<td style="text-align:left">HighNodeUtilization</td>
<td style="text-align:left">将 requests 比率较低节点上的Pod进行迁移。</td>
</tr>
<tr>
<td style="text-align:left">RemovePodsViolatingInterPodAntiAffinity</td>
<td style="text-align:left">将不满足反亲和性的Pod进行迁移。</td>
</tr>
<tr>
<td style="text-align:left">RemovePodsViolatingNodeAffinity</td>
<td style="text-align:left">将不满足节点节点亲和性策略的Pod进行迁移。</td>
</tr>
<tr>
<td style="text-align:left">RemovePodsViolatingNodeTaints</td>
<td style="text-align:left">将不满足节点污点策略的Pod进行迁移。</td>
</tr>
<tr>
<td style="text-align:left">RemovePodsViolatingTopologySpreadConstraint</td>
<td style="text-align:left">将不满足拓扑分布约束的Pod进行迁移。</td>
</tr>
<tr>
<td style="text-align:left">RemovePodsHavingTooManyRestarts</td>
<td style="text-align:left">将重启次数过多的Pod进行迁移。</td>
</tr>
<tr>
<td style="text-align:left">PodLifeTime</td>
<td style="text-align:left">将运行时间较长的Pod进行迁移。</td>
</tr>
<tr>
<td style="text-align:left">RemoveFailedPods</td>
<td style="text-align:left">将运行失败的Pod进行迁移。</td>
</tr>
</tbody>
</table>
<p>高利用率节点的迁移策略示例:</p>
<p><img src="https://cdn.tianfeiyu.com/kubernetes%2Fdescheduler-1.png" alt=""></p>
<p>其他策略示例:</p>
<p><img src="https://cdn.tianfeiyu.com/kubernetes%2Fdescheduler-2.png" alt="Strategies diagram"></p>
<p>以上就是针对社区 Descheduler 组件的介绍。</p>
<h3 id="descheduler-功能扩展"><a name="descheduler-功能扩展" class="anchor-navigation-ex-anchor" href="#descheduler-功能扩展"><i class="fa fa-link" aria-hidden="true"></i></a>Descheduler 功能扩展</h3>
<p>在了解了 descheduler 的策略之后会发现,社区 descheduler 的功能远远不能满足公司内部生产环境的需要,首先以 Remove 开头的几个策略其实在大部分场景是不需要的,如果集群内的资源足够通过配置反亲和性策略是可以将同一 workload 下所有 Pod 打散的。LowNodeUtilization 和 HighNodeUtilization 策略可以根据实际的场景进行扩展,社区这两种策略是根据节点的分配率 request 比率来进行决策的,只基于分配率进行 Pod 迁移整体而言效果相对一般,无法达到生产环境的要求,在大部分生产环境下需要使用 node 真实使用率来进行 Pod 迁移。</p>
<h4 id="lownodeutilization-策略扩展"><a name="lownodeutilization-策略扩展" class="anchor-navigation-ex-anchor" href="#lownodeutilization-策略扩展"><i class="fa fa-link" aria-hidden="true"></i></a>LowNodeUtilization 策略扩展</h4>
<p>针对 LowNodeUtilization 策略的扩展,除了将社区 request 分配率指标改为基于节点真实的 cpu 使用率外,在分析了生产环境的数据之后还添加了一些额外的功能。策略在实际使用过程中进行了多次演进,从最初的使用社区的周期性巡检机制进行触发,但该策略有一定的滞后性,真实场景如果节点利用率过高则要尽快进行处理,针对节点高利用率场景为了提高时效性,策略在扩展时直接对接了内部的监控系统,通过告警回调触发节点上面 Pod 的迁移,最后针对部分无法在高峰期进行 Pod 迁移的场景,也设计了节点利用率预测算法,在高峰期前提前预测高利用率节点执行 Pod 迁移操作。</p>
<h5 id="1、通过告警回调触发"><a name="1、通过告警回调触发" class="anchor-navigation-ex-anchor" href="#1、通过告警回调触发"><i class="fa fa-link" aria-hidden="true"></i></a>1、通过告警回调触发</h5>
<p>该策略直接了当,通过监控发现高利用率节点后直接触发节点上 Pod 的迁移,通过告警配置对策略调整也比较灵活,配置完之后直接生效也不需要升级 descheduler 组件。如果高利用率节点比较多可以将报警策略配置在标准阈值之下以激进的方式进行处理,在生产环境中,策略不管是激进还是保守都可能无法达到最好的效果,最终需要将策略调整到一个稳健的状态。</p>
<h5 id="2、节点利用率预测"><a name="2、节点利用率预测" class="anchor-navigation-ex-anchor" href="#2、节点利用率预测"><i class="fa fa-link" aria-hidden="true"></i></a>2、节点利用率预测</h5>
<p>生产环境中业务会有变更的时间窗口,部分高优服务 Pod 迁移的操作也需要和业务的变更时间窗口保持一致,避免因 Pod 迁移影响了业务的稳定性,针对这部分无法在高峰期进行 Pod 迁移的场景,需要在高峰期来临前提前预测到高利用率节点并进行处理,当前预测算法的实现主要是参考了社区 VPA 组件的推荐算法,基于时间序列的一个预估算法,算法的核心是获取节点上所有实例最近8天的利用率数据,再按天计算得到每天的P95数据,最后对每天的P95数据使用不同的权重系数加权计算得到最终的预测结果。</p>
<p>预测数据需要做大量的分析验证,发现对准确性有影响的因素,在实际验证过程中发现影响预测结果的主要有两点,一是服务下不同 Pod cpu 分层问题,服务下所有 Pod 在同一个时间点的 cpu 利用率不一致,出现这种情况可能的原因有:</p>
<ul>
<li><p>(1) 业务实例存在定时任务;</p>
</li>
<li><p>(2) 部分业务实例开启了 OpenTracing;</p>
</li>
<li><p>(3) 服务不同实例流量不均匀;</p>
</li>
<li><p>(4) 硬件影响:不同实例所在的宿主机的 CPU 型号不同,CPU 的主频、多级缓存容量、指令集、位数等等,都会影响 CPU 的性能,进而影响实例的性能;</p>
</li>
<li><p>(5) 软件影响:内核参数配置等;</p>
</li>
</ul>
<p>二是节点上实例数量的变化,如果预测了节点的利用率结果之后,节点上面有实例的新建与销毁操作也会影响预测的准确性。当前节点利用率预测功能也在不断优化中,此处不再对细节进行详细的说明。</p>
<h4 id="highnodeutilization-策略扩展"><a name="highnodeutilization-策略扩展" class="anchor-navigation-ex-anchor" href="#highnodeutilization-策略扩展"><i class="fa fa-link" aria-hidden="true"></i></a>HighNodeUtilization 策略扩展</h4>
<p>实际场景中,某些 request 分配率比较高但实际使用率比较低的节点上有很多实例运行的时间比较久,业务长期不会进行变更导致实例不会通过销毁重建的方式自动进行重调度,针对此场景可以尝试通过迁移 Pod 来提高节点的利用率。</p>
<p>针对 HighNodeUtilization 策略的扩展比 LowNodeUtilization 策略简单一些,主要是将 request 比率替换为了实际的使用率,再就是会在下文讲到两个策略都需要用的一些约束机制与效果分析机制。</p>
<h3 id="descheduler-pod-迁移场景中的约束策略"><a name="descheduler-pod-迁移场景中的约束策略" class="anchor-navigation-ex-anchor" href="#descheduler-pod-迁移场景中的约束策略"><i class="fa fa-link" aria-hidden="true"></i></a>Descheduler Pod 迁移场景中的约束策略</h3>
<p>由于生产环境中场景复杂,Pod 迁移对业务来说也是一个有损的操作,在迁移过程中必须要做好必要的防范措施,需要配置一些约束策略来保障业务的稳定性。</p>
<p>尽管 k8s 可以通过配置 PDB(PodDisruptionBudget)来避免对象的副本被同时驱逐,不过我们认为 PDB 不够精细化,在跨集群场景中也无法更好的运用,此处会通过一个全局的约束限制模块让服务的 Pod 在重调度过程中对服务影响尽可能的小以及尽可能的均衡负载有问题的节点,保证业务不中断或业务SLA不降级。</p>
<p>当前在 Pod 迁移过程中有多种策略来进行约束 ,在宏观策略上,主要是针对全局的约束策略,在不同的集群与资源池中,Pod 迁移时的速率以及一个周期内迁移 Pod 总数量会有限制,Pod 迁移时间窗口、迁移时是否跨集群等策略也有一定的限制,每个集群与资源池也会配置黑白名单。在微观策略上,主要是针对节点和服务的约束策略,节点与服务 Pod 迁移速率与一个周期内迁移 Pod 总数量也有限制,在迁移时挑选服务下 Pod 也会针对 Pod 状态以及服务等级做一些限制。</p>
<h3 id="descheduler-pod-迁移的效果分析"><a name="descheduler-pod-迁移的效果分析" class="anchor-navigation-ex-anchor" href="#descheduler-pod-迁移的效果分析"><i class="fa fa-link" aria-hidden="true"></i></a>Descheduler Pod 迁移的效果分析</h3>
<p>二次调度在功能完善之后,还需要一套效果评估机制,如果二次调度服务运行一段时间后,迁移了很多 Pod,但因为其他因素的影响,高利用率节点数量没有降低的话需要怎么分析呢?</p>
<p>经过对线上数据的分析,最终使用了三个指标对二次调度进行效果评估。第一个是高利用率节点的发现率,指的是二次调度能发现的高利用率节点数量,与通过公司的标准采集到的高利用率节点数量的一个比例,理论上二者的结果应该是接近的,实际上在执行的过程发现报警策略使用的算法无法与公司统计标准使用的算法保持一致、配置的报警敏感度低以及Pod 迁移窗口限制等原因导致发现率是偏低的。</p>
<p>第二个是高利用率节点Pod驱逐率,驱逐率指的是发现高利用率节点之后,能够在节点上挑选出合适的 Pod 并进行驱逐。有些高利用率节点因为服务相关约束、实例挑选算法不合理或者全局策略约束等原因无法驱逐节点上面的 Pod。</p>
<p>第三个是高利用率节点Pod驱逐有效率。如果驱逐了高利用率节点上面的Pod节点利用率没有降低到一定阈值,那也是不符合预期的。主要有三个原因会导致驱逐有效率低,第一个是因为各种约束导致驱逐的 Pod 不是最优的,节点利用率下降不明显,第二个就是 Pod 被驱逐后,节点上很快会有新 Pod 被调度上来了,第三个是节点上部分 Pod 利用率变高了。</p>
<p>最后就是对全集群高利用率节点数量的分析,针对全集群高利用率节点的数据,也会按资源池与集群维度进行拆分建立以上三个指标数据,理论上高利用率节点发现率、驱逐率和有效率三个指标如果都比较符合预期全集群高利用率节点的比例是会控制在一定范围内的。</p>
<p>以上就是二次调度效果分析的一个流程。</p>
<p><img src="https://cdn.tianfeiyu.com/kubernetes%2Fdescheduler-3.png" alt=""></p>
<p>当前主要是通过二次调度组件自身的一些数据进行了分析,全集群的高利用率节点还与业务流量、集群容量、调度器策略等因素相关,部分业务有运营活动时集群整体的资源利用率都会提升,集群资源紧张时调度器针对得分较低的节点也会将实例调度上去,这些都会对高利用率节点数量造成影响。</p>
<h3 id="总结"><a name="总结" class="anchor-navigation-ex-anchor" href="#总结"><i class="fa fa-link" aria-hidden="true"></i></a>总结</h3>
<p>本文主要介绍了当前社区 descheduler 组件的基本功能以及在生产环境中 descheduler 的一些缺陷和一些扩展策略,在使用 descheduler 迁移 Pod 时还需要对业务的稳定性做一些保障措施,组件功能在完善之后还需要对服务自身进行的一些效果评估机制。descheduler 的基本功能是基于一些策略对 Pod 进行迁移,在生产环境中有很多场景需要对 node 上的 Pod 做一些迁移操作,比如需要重启节点的内核升级操作、不同机房进行的机器搬迁操作,还有针对 k8s 组件进行升级的场景中(运行时的切换等) 都可以用 descheduler 添加一些策略进行支持。未来会结合生产环境继续在 descheduler 里面添加其他的策略,比如基于节点干扰率场景的 Pod 迁移,基于服务特征识的反亲和策略进行 Pod 迁移。</p>
<footer class="page-footer"><span class="copyright">Copyright © tianfeiyu 2019 all right reserved,powered by Gitbook</span><span class="footer-modification">该文件修订时间:
2022-06-30 20:41:02
</span></footer> <link rel="stylesheet" type="text/css" href="https://storage.googleapis.com/app.klipse.tech/css/codemirror.css"> <script> window.klipse_settings = { selector: ".language-klipse, .lang-eval-clojure", selector_eval_js: ".lang-eval-js", selector_eval_python_client: ".lang-eval-python", selector_eval_php: ".lang-eval-php", selector_eval_scheme: ".lang-eval-scheme", selector_eval_ruby: ".lang-eval-ruby", selector_reagent: ".lang-reagent", selector_google_charts: ".lang-google-chart", selector_es2017: ".lang-eval-es2017", selector_jsx: ".lang-eval-jsx", selector_transpile_jsx: ".lang-transpile-jsx", selector_render_jsx: ".lang-render-jsx", selector_react: ".lang-react", selector_eval_markdown: ".lang-render-markdown", selector_eval_lambdaway: ".lang-render-lambdaway", selector_eval_cpp: ".lang-eval-cpp", selector_eval_html: ".lang-render-html", selector_sql: ".lang-eval-sql", selector_brainfuck: "lang-eval-brainfuck", selector_js: ".lang-transpile-cljs" }; </script> <script src="https://storage.googleapis.com/app.klipse.tech/plugin/js/klipse_plugin.js"></script>
</section>
</div>
<div class="search-results">
<div class="has-results">
<h1 class="search-results-title"><span class='search-results-count'></span> results matching "<span class='search-query'></span>"</h1>
<ul class="search-results-list"></ul>
</div>
<div class="no-results">
<h1 class="search-results-title">No results matching "<span class='search-query'></span>"</h1>
</div>
</div>
</div>
</div>
</div>
</div>
<a href="k8s_evicted.html" class="navigation navigation-prev " aria-label="Previous page: kubernetes 中 Evicted pod 是如何产生的">
<i class="fa fa-angle-left"></i>
</a>