-
Notifications
You must be signed in to change notification settings - Fork 0
/
feed.xml
5368 lines (4191 loc) · 478 KB
/
feed.xml
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
<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.7.3">Jekyll</generator><link href="https://kevinguo.me/feed.xml" rel="self" type="application/atom+xml" /><link href="https://kevinguo.me/" rel="alternate" type="text/html" /><updated>2018-07-04T18:22:19+08:00</updated><id>https://kevinguo.me/</id><title type="html">KevinGuo</title><subtitle>KevinGuo's blog</subtitle><author><name>KevinGuo</name></author><entry><title type="html">docker中的一些组件</title><link href="https://kevinguo.me/2018/07/04/docker-components/" rel="alternate" type="text/html" title="docker中的一些组件" /><published>2018-07-04T00:00:00+08:00</published><updated>2018-07-04T00:00:00+08:00</updated><id>https://kevinguo.me/2018/07/04/docker-components</id><content type="html" xml:base="https://kevinguo.me/2018/07/04/docker-components/"><h3 id="docker主要组件">docker主要组件</h3>
<p>安装docker,实际上就是安装了docker客户端、dockerd等一系列组件,其中比较重要的有下面几个</p>
<p><img src="/images/posts/containerd.png" alt="" /></p>
<h4 id="docker-clidocker">docker CLI(docker)</h4>
<p>docker 程序是一个客户端工具,用来把用户的请求发送给docker daemon(dockerd)</p>
<h4 id="dockerd">dockerd</h4>
<p>docker daemon(dockerd),docker服务端,一般也会被称为docker engine</p>
<h4 id="docker-containerd">docker-containerd</h4>
<p>带API的容器运行时</p>
<p>containerd主要职责是镜像管理(镜像、元信息等)、容器执行(调用最终运行时组件执行)。</p>
<p>containerd向上为Docker Daemon提供了gRPC接口,使得Docker Daemon屏蔽下面的结构变化,确保原有接口向下兼容。</p>
<p>containerd向下通过containerd-shim结合runC,使得引擎可以独立升级,避免之前Docker Daemon升级会导致所有容器不可用的问题</p>
<p>当docker daemon启动后,dockerd和docker-containerd进程就一直存在。</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">[</span>root@kevinguo my_container]# ps <span class="nt">-ef</span> |grep docker
root 5261 1 0 11:48 ? 00:00:03 /usr/bin/dockerd
root 5266 5261 0 11:48 ? 00:00:10 docker-containerd <span class="nt">--config</span> /var/run/docker/containerd/containerd.toml
</code></pre></div></div>
<p>当启动容器之后,docker-containerd会创建子进程docker-containerd-shim进程</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root 5261 1 0 11:48 ? 00:00:03 /usr/bin/dockerd
root 5266 5261 0 11:48 ? 00:00:10 docker-containerd <span class="nt">--config</span> /var/run/docker/containerd/containerd.toml
root 5484 5266 0 11:48 ? 00:00:00 docker-containerd-shim <span class="nt">-namespace</span> moby <span class="nt">-workdir</span> /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/eaad9500e9a03473933179362983dd4615ba075062b184b0c4e8a3a34abacf34 <span class="nt">-address</span> /var/run/docker/containerd/docker-containerd.sock <span class="nt">-containerd-binary</span> /usr/bin/docker-containerd <span class="nt">-runtime-root</span> /var/run/docker/runtime-runc
</code></pre></div></div>
<h5 id="安装containerd">安装containerd</h5>
<p>containerd会调用runc,所以我们在安装containerd之前,需先安装runc</p>
<p>从<a href="https://github.com/containerd/containerd/releases/download/v1.1.0/containerd-1.1.0.linux-amd64.tar.gz">官网</a>下载最新的稳定版本</p>
<p>然后把下载的包解压到<code class="highlighter-rouge">/usr/local</code>下</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo tar</span> <span class="nt">-C</span> /usr/local <span class="nt">-xf</span> containerd-1.1.0.linux-amd64.tar.gz
</code></pre></div></div>
<p>配置containerd作为系统服务</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mkdir /etc/containerd
containerd config default <span class="o">&gt;</span> /etc/containerd/config.toml
vi /usr/lib/systemd/system/containerd.service
<span class="o">[</span>Unit]
<span class="nv">Description</span><span class="o">=</span>containerd container runtime
<span class="nv">Documentation</span><span class="o">=</span>https://containerd.io
<span class="nv">After</span><span class="o">=</span>network.target
<span class="o">[</span>Service]
<span class="nv">ExecStartPre</span><span class="o">=</span>/sbin/modprobe overlay
<span class="nv">ExecStart</span><span class="o">=</span>/usr/local/bin/containerd
<span class="nv">Delegate</span><span class="o">=</span>yes
<span class="nv">KillMode</span><span class="o">=</span>process
<span class="nv">LimitNOFILE</span><span class="o">=</span>1048576
<span class="c"># Having non-zero Limit*s causes performance problems due to accounting overhead</span>
<span class="c"># in the kernel. We recommend using cgroups to do container-local accounting.</span>
<span class="nv">LimitNPROC</span><span class="o">=</span>infinity
<span class="nv">LimitCORE</span><span class="o">=</span>infinity
<span class="o">[</span>Install]
<span class="nv">WantedBy</span><span class="o">=</span>multi-user.target
</code></pre></div></div>
<p>启动服务,然后尝试着用ctr命令来启动容器</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>systemctl daemon-reload containerd
systemctl start containerd
<span class="c"># containerd的默认命令ctr</span>
ctr images pull docker.io/library/busybox:latest
ctr run <span class="nt">-t</span> docker.io/library/busybox:latest mybusybox
<span class="c"># 列出容器</span>
<span class="o">[</span>root@kevinguo ~]# ctr c <span class="nb">ls
</span>CONTAINER IMAGE RUNTIME
mybusybox docker.io/library/busybox:latest io.containerd.runtime.v1.linux
<span class="c"># 列出任务</span>
<span class="o">[</span>root@kevinguo ~]# ctr t <span class="nb">ls
</span>TASK PID STATUS
mybusybox 16359 RUNNING
</code></pre></div></div>
<p>删除容器之前先要kill掉容器进程,然后再用<code class="highlighter-rouge">ctr c rm mybusybox</code>的命令来删除</p>
<h4 id="docker-containerd-shim">docker-containerd-shim</h4>
<p>它是containerd的一个组件,是容器的运行时载体,我们在宿主机上看到的shim,正是代表着一个个通过containerd启动的docker容器,它允许容器运行时在容器启动之后退出,即便在containerd和dockerd都挂掉的情况下,容器的标准io和其他描述文件都是可用的</p>
<h4 id="runc">runC</h4>
<p>容器运行时</p>
<p>RunC 是一个轻量级的工具,它是用来运行容器的,只用来做这一件事,并且这一件事要做好。我们可以认为它就是个命令行小工具,可以不用通过 docker 引擎,直接运行容器。事实上,runC 是标准化的产物,它根据 OCI 标准来创建和运行容器。而 OCI(Open Container Initiative)组织,旨在围绕容器格式和运行时制定一个开放的工业化标准。</p>
<p>我们可以在运行dockerd的时候使用<code class="highlighter-rouge">--add-runtime</code>来指定其他的运行时</p>
<p>在容器启动的过程中,docker-runc 进程是作为 docker-containerd-shim 的子进程存在的。docker-runc 进程根据配置找到容器的 rootfs 并创建子进程 bash 作为容器中的第一个进程。当这一切都完成后 docker-runc 进程退出,然后容器进程 bash 由 docker-runc 的父进程 docker-containerd-shim 接管</p>
<h5 id="安装runc">安装runc</h5>
<p>runc是golan的项目,因此在编译它之前,咱们先安装一下golan,这里我是在centos上,直接用命令安装</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yum install golan <span class="nt">-y</span>
</code></pre></div></div>
<p><a href="https://github.com/opencontainers/runc">参考官方文档</a></p>
<p>安装必要的依赖包</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yum install libseccomp libseccomp-devel <span class="nt">-y</span>
</code></pre></div></div>
<p>在你的golan的src目录下,创建github.com/opencontainers,如果你也是用yum 安装的golan,那么目录如下</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mkdir <span class="nt">-p</span> /usr/lib/golang/src/github.com/opencontainers
</code></pre></div></div>
<p>获取runc的代码,并且编译安装</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git clone https://github.com/opencontainers/runc
<span class="nb">cd </span>runc
make
make install
<span class="o">[</span>root@kevinguo src]# runc <span class="nt">--version</span>
runc version 1.0.0-rc5+dev
commit: 2c632d1a2de0192c3f18a2542ccb6f30a8719b1f
spec: 1.0.0
</code></pre></div></div>
<h5 id="使用runcdocker-runc来运行busybox容器">使用runC/docker-runc来运行busybox容器</h5>
<p>先准备一个工作目录,所有的操作都是在该目录下执行</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mkdir mycontainer
</code></pre></div></div>
<p>接着,准备容器镜像的文件系统,我们从docker镜像中获取</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd </span>mycontainer
mkdir rootfs
docker <span class="nb">export</span> <span class="k">$(</span>docker create busybox<span class="k">)</span> |tar <span class="nt">-C</span> rootfs <span class="nt">-xvf</span> -
</code></pre></div></div>
<p>有了rootfs之后,我们还需要一个符合OCI标准的配置文件config.json,我们可以使用docker-runc来生成</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker-runc spec
</code></pre></div></div>
<p>接着,我们就可以使用runC来操作了</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker-runc run busybox
<span class="c"># 切换到另一个终端来查看</span>
<span class="o">[</span>root@kevinguo ~]# docker-runc list
ID PID STATUS BUNDLE CREATED OWNER
busybox 8754 running /root/mycontainer 2018-07-04T06:39:50.137725285Z root
<span class="o">[</span>root@kevinguo ~]# docker-runc ps busybox
UID PID PPID C STIME TTY TIME CMD
root 8754 8745 0 15:39 pts/0 00:00:00 sh
</code></pre></div></div>
<p>我们还可以尝试着修改config.json,让容器后台运行</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="s2">"terminal"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
</span><span class="s2">"args"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="s2">"sleep"</span><span class="p">,</span><span class="s2">"20"</span><span class="w">
</span><span class="p">],</span><span class="w">
</span></code></pre></div></div>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">[</span>root@kevinguo mycontainer]# docker-runc create mybusybox
<span class="o">[</span>root@kevinguo mycontainer]# docker-runc start mybusybox
<span class="o">[</span>root@kevinguo mycontainer]# docker-runc list
ID PID STATUS BUNDLE CREATED OWNER
busybox 8754 running /root/mycontainer 2018-07-04T06:39:50.137725285Z root
mybusybox 8886 running /root/mycontainer 2018-07-04T06:42:14.404232848Z root
</code></pre></div></div>
<blockquote>
<p>就现状而言,虽然containerd1.1已经可以直接被kubernetes使用了,但是相对而言,我们还是建议先使用docker这个容器运行时,所以不论是cri还是cri-o,简单了解下就好</p>
</blockquote></content><author><name>KevinGuo</name></author><summary type="html">docker主要组件</summary></entry><entry><title type="html">Linux top 详解</title><link href="https://kevinguo.me/2018/02/09/Linux-top/" rel="alternate" type="text/html" title="Linux top 详解" /><published>2018-02-09T00:00:00+08:00</published><updated>2018-02-09T00:00:00+08:00</updated><id>https://kevinguo.me/2018/02/09/Linux-top</id><content type="html" xml:base="https://kevinguo.me/2018/02/09/Linux-top/"><blockquote>
<p>一直都对服务性能这块的东西不怎么感冒,但是,有一次面试的时候,被问到了,突然发现自己对这些基础的知识点,好匮乏,正好今天在学python的psutil模块的时候,看到了cpu_times,顺便记录下关于top这个命令的内容;top这个命令其实很多人都会用,但是用的好的人却不多,甚至有人会对监控视图中的内容含义有不少曲解。</p>
</blockquote>
<!--more-->
<blockquote>
<p><strong>先来一份top命令的结果,后面会详细解读</strong></p>
</blockquote>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>top - 18:02:01 up 1:06, 1 user, load average: 0.22, 0.12, 0.10
Tasks: 200 total, 2 running, 198 sleeping, 0 stopped, 0 zombie
%Cpu<span class="o">(</span>s<span class="o">)</span>: 3.0 us, 1.0 sy, 0.0 ni, 96.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 4039816 total, 1270872 free, 1432504 used, 1336440 buff/cache
KiB Swap: 385836 total, 385836 free, 0 used. 2321064 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
</code></pre></div></div>
<p><strong>第一行:</strong></p>
<p><code class="highlighter-rouge">top - 18:02:01 up 1:06, 1 user, load average: 0.22, 0.12, 0.10</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
18:02:01 <span class="nt">--</span> 当前系统时间
1:06 <span class="nt">--</span> 系统已经运行了多长时间
1 user <span class="nt">--</span> 当前有一个用户登录系统
load average: 0.22, 0.12, 0.10 <span class="nt">--</span> load average后面的三个数分别是1分钟、5分钟、15分钟的负载情况
</code></pre></div></div>
<p>load average数据是每隔5秒钟检查一次活跃的进程数,然后按特定算法计算出的数值。如果这个数除以逻辑CPU的数量,结果高于5就表明系统在超负荷运转了</p>
<p><strong>第二行:</strong></p>
<p><code class="highlighter-rouge">Tasks: 200 total, 2 running, 198 sleeping, 0 stopped, 0 zombie</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
200 total <span class="nt">--</span> 系统现在一共有多少个进程
2 running <span class="nt">--</span> 其中处于运行中的有几个
198 sleeping <span class="nt">--</span> 处于休眠状态的有多少个
0 stopped <span class="nt">--</span> 处于停止状态的有多少个
0 zombie <span class="nt">--</span> 僵尸进程有多少个
</code></pre></div></div>
<p><strong>第三行:</strong></p>
<p><code class="highlighter-rouge">%Cpu(s): 3.0 us, 1.0 sy, 0.0 ni, 96.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
3.0 us <span class="nt">--</span> 用户空间占用CPU的百分比
1.0 sy <span class="nt">--</span> 内核空间占用CPU的百分比
0.0 ni <span class="nt">--</span> 用户进程空间内改变过优先级的进程占用CPU的百分比
96.0 id <span class="nt">--</span> 空闲CPU百分比
0.0 wa <span class="nt">--</span> IO等待占用CPU百分比
0.0 hi <span class="nt">--</span> 硬中断<span class="o">(</span>Hardware IRQ<span class="o">)</span>占用CPU百分比
0.0 si <span class="nt">--</span> 软中断<span class="o">(</span>Software Interrupts<span class="o">)</span>占用CPU百分比
0.0 st <span class="nt">--</span> 虚拟机被hypervisor偷去的CPU时间
</code></pre></div></div>
<p><strong>第四行:</strong></p>
<p><code class="highlighter-rouge">KiB Mem : 4039816 total, 1270872 free, 1432504 used, 1336440 buff/cache</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
4039816 total <span class="nt">--</span> 物理总内存
1270872 free <span class="nt">--</span> 空闲内存总量
1432504 used <span class="nt">--</span> 使用内存量
1336440 buff/cache <span class="nt">--</span> 用作内核缓存的内存量
</code></pre></div></div>
<p><strong>第五行:</strong></p>
<p><code class="highlighter-rouge">KiB Swap: 385836 total, 385836 free, 0 used. 2321064 avail Mem</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
385836 total <span class="nt">--</span> 交换区总量
385836 free <span class="nt">--</span> 空闲的交换区总量
0 used <span class="nt">--</span> 使用的交换区量
2321064 avail Mem <span class="nt">--</span> 可用于进程下一次分配的物理内存数量
</code></pre></div></div>
<p><strong>第七行:</strong></p>
<p><code class="highlighter-rouge">PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
PID <span class="nt">--</span> 进程ID
USER <span class="nt">--</span> 进程所有者
PR <span class="nt">--</span> 进程优先级
NI <span class="nt">--</span> nice值。负值表示高优先级,正值表示低优先级
VIRT <span class="nt">--</span> 进程使用的虚拟内存总量 VIRT <span class="o">=</span> SWAP+RES
RES <span class="nt">--</span> 进程使用的,未被换出的物理内存大小
SHR <span class="nt">--</span> 共享内存大小
S <span class="nt">--</span> 进程状态 <span class="nv">R</span><span class="o">=</span>运行,S<span class="o">=</span>睡眠,T<span class="o">=</span>跟踪/停止,Z<span class="o">=</span>僵尸经常,D<span class="o">=</span>不可中断的睡眠状态
%CPU <span class="nt">--</span> 上次更新到现在的CPU时间占用百分比
%MEM <span class="nt">--</span> 进程使用的物理内存百分比
TIME+ 进程使用的CPU时间总计
COMMAND - 进程名称<span class="o">(</span>命令名/命令行<span class="o">)</span>
</code></pre></div></div>
<blockquote>
<p>交互的时候,使用P,以CPU百分比大小进行排序,使用M,以内存大小进行排序,使用T,以时间进行排序</p>
</blockquote>
<blockquote>
<p>最后记录下如何用python来计算top里面的各个利用率</p>
</blockquote>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
top上的cpu利用率,大致算法如下
CPU总时间2<span class="o">=</span>user2+system2+nice2+idle2+iowait2+irq2+softirq2
CPU总时间1<span class="o">=</span>user1+system1+nice1+idle1+iowait1+irq1+softirq1
用户cpu利用率 <span class="o">=</span> user_pass <span class="k">*</span> 100% / <span class="o">(</span>CPU总时间2 - CPU总时间1<span class="o">)</span>
内核cpu利用率 <span class="o">=</span> system_pass <span class="k">*</span> 100% / <span class="o">(</span>CPU总时间2 - CPU总时间1<span class="o">)</span>
总的cpu利用率<span class="o">=</span> 用户cpu利用率 + 内核cpu利用率
</code></pre></div></div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
<span class="n">cs1</span> <span class="o">=</span> <span class="nb">sum</span><span class="p">(</span><span class="n">psutil</span><span class="o">.</span><span class="n">cpu_times</span><span class="p">())</span>
<span class="n">cu1</span> <span class="o">=</span> <span class="n">psutil</span><span class="o">.</span><span class="n">cpu_times</span><span class="p">()</span><span class="o">.</span><span class="n">user</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="n">cs2</span> <span class="o">=</span> <span class="nb">sum</span><span class="p">(</span><span class="n">psutil</span><span class="o">.</span><span class="n">cpu_times</span><span class="p">())</span>
<span class="n">cu2</span> <span class="o">=</span> <span class="n">psutil</span><span class="o">.</span><span class="n">cpu_times</span><span class="p">()</span><span class="o">.</span><span class="n">user</span>
<span class="n">ss</span> <span class="o">=</span> <span class="n">cs2</span> <span class="o">-</span> <span class="n">cs1</span>
<span class="k">print</span><span class="p">(((</span><span class="n">cu2</span> <span class="o">-</span> <span class="n">cu1</span><span class="p">)</span> <span class="o">/</span> <span class="n">ss</span><span class="p">)</span> <span class="o">*</span> <span class="mi">100</span><span class="p">)</span>
</code></pre></div></div></content><author><name>KevinGuo</name></author><summary type="html">一直都对服务性能这块的东西不怎么感冒,但是,有一次面试的时候,被问到了,突然发现自己对这些基础的知识点,好匮乏,正好今天在学python的psutil模块的时候,看到了cpu_times,顺便记录下关于top这个命令的内容;top这个命令其实很多人都会用,但是用的好的人却不多,甚至有人会对监控视图中的内容含义有不少曲解。</summary></entry><entry><title type="html">python 多重继承之拓扑排序</title><link href="https://kevinguo.me/2018/01/19/python-topological-sorting/" rel="alternate" type="text/html" title="python 多重继承之拓扑排序" /><published>2018-01-19T00:00:00+08:00</published><updated>2018-01-19T00:00:00+08:00</updated><id>https://kevinguo.me/2018/01/19/python-topological-sorting</id><content type="html" xml:base="https://kevinguo.me/2018/01/19/python-topological-sorting/"><blockquote>
<p>最近在学python,学到class 多重继承,降到了c3算法,这里记录一下</p>
</blockquote>
<!--more-->
<h3 id="一什么是拓扑排序">一、什么是拓扑排序</h3>
<p>在图论中,<strong>拓扑排序(Topological Sorting)</strong> 是一个 <strong>有向无环图(DAG,Directed Acyclic Graph)</strong> 的所有顶点的线性序列。且该序列必须满足下面两个条件:</p>
<ul>
<li>每个顶点出现且只出现一次。</li>
<li>若存在一条从顶点A到顶点B的路径,那么在序列中顶点A出现在顶点B的前面。</li>
</ul>
<p>例如,下面这个图:</p>
<p><img src="/images/posts/original.png" alt="" /></p>
<p>它是一个DAG图,那么如何写出它的拓扑顺序呢?这里说一种比较常用的方法:</p>
<ul>
<li>从DAG途中选择一个没有前驱(即入度为0)的顶点并输出</li>
<li>从图中删除该顶点和所有以它为起点的有向边。</li>
<li>重复1和2直到当前DAG图为空或当前途中不存在无前驱的顶点为止。后一种情况说明有向图中必然存在环。</li>
</ul>
<p><img src="/images/posts/topological-sorting.png" alt="" /></p>
<p>于是,得到拓扑排序后的结果是{1,2,4,3,5}</p>
<p>下面,我们看看拓扑排序在python多重继承中的例子</p>
<h3 id="二python-多重继承">二、python 多重继承</h3>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/usr/bin/env python3</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="k">class</span> <span class="nc">A</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">print</span><span class="p">(</span><span class="s">'A foo'</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">bar</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">print</span><span class="p">(</span><span class="s">'A bar'</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">B</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">print</span><span class="p">(</span><span class="s">'B foo'</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">bar</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">print</span><span class="p">(</span><span class="s">'B bar'</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">C1</span><span class="p">(</span><span class="n">A</span><span class="p">,</span><span class="n">B</span><span class="p">):</span>
<span class="k">pass</span>
<span class="k">class</span> <span class="nc">C2</span><span class="p">(</span><span class="n">A</span><span class="p">,</span><span class="n">B</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">bar</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">print</span><span class="p">(</span><span class="s">'C2-bar'</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">D</span><span class="p">(</span><span class="n">C1</span><span class="p">,</span><span class="n">C2</span><span class="p">):</span>
<span class="k">pass</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">'__main__'</span><span class="p">:</span>
<span class="k">print</span><span class="p">(</span><span class="n">D</span><span class="o">.</span><span class="n">__mro__</span><span class="p">)</span>
<span class="n">d</span><span class="o">=</span><span class="n">D</span><span class="p">()</span>
<span class="n">d</span><span class="o">.</span><span class="n">foo</span><span class="p">()</span>
<span class="n">d</span><span class="o">.</span><span class="n">bar</span><span class="p">()</span>
</code></pre></div></div>
<blockquote>
<p>首先,我们根据上面的继承关系构成一张图,如下</p>
</blockquote>
<p><img src="/images/posts/python-inherit.png" alt="" /></p>
<ul>
<li>找到入度为0的点,只有一个D,把D拿出来,把D相关的边剪掉</li>
<li>现在有两个入度为0的点(C1,C2),取最左原则,拿C1,剪掉C1相关的边,这时候的排序是{D,C1}</li>
<li>现在我们看,入度为0的点(C2),拿C2,剪掉C2相关的边,这时候排序是{D,C1,C2}</li>
<li>接着看,入度为0的点(A,B),取最左原则,拿A,剪掉A相关的边,这时候的排序是{D,C1,C2,A}</li>
<li>继续,入度哦为0的点只有B,拿B,剪掉B相关的边,最后只剩下object</li>
<li>所以最后的排序是{D,C1,C2,A,B,object}</li>
</ul>
<p>我们执行上面的代码,发现<code class="highlighter-rouge">print(D.__mro__)</code>的结果也正是这样,而这也就是多重继承所使用的C3算法啦</p>
<blockquote>
<p>为了进一步熟悉这个拓扑排序的方法,我们再来一张图,试试看排序结果是怎样的,它继承的内容是否如你所想</p>
</blockquote>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/usr/bin/env python3</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="k">class</span> <span class="nc">A</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">print</span><span class="p">(</span><span class="s">'A foo'</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">bar</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">print</span><span class="p">(</span><span class="s">'A bar'</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">B</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">print</span><span class="p">(</span><span class="s">'B foo'</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">bar</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">print</span><span class="p">(</span><span class="s">'B bar'</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">C1</span><span class="p">(</span><span class="n">A</span><span class="p">):</span>
<span class="k">pass</span>
<span class="k">class</span> <span class="nc">C2</span><span class="p">(</span><span class="n">B</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">bar</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">print</span><span class="p">(</span><span class="s">'C2-bar'</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">D</span><span class="p">(</span><span class="n">C1</span><span class="p">,</span><span class="n">C2</span><span class="p">):</span>
<span class="k">pass</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">'__main__'</span><span class="p">:</span>
<span class="k">print</span><span class="p">(</span><span class="n">D</span><span class="o">.</span><span class="n">__mro__</span><span class="p">)</span>
<span class="n">d</span><span class="o">=</span><span class="n">D</span><span class="p">()</span>
<span class="n">d</span><span class="o">.</span><span class="n">foo</span><span class="p">()</span>
<span class="n">d</span><span class="o">.</span><span class="n">bar</span><span class="p">()</span>
</code></pre></div></div>
<blockquote>
<p>还是先根据继承关系构一个继承图</p>
</blockquote>
<p><img src="/images/posts/python-inherit2.png" alt="" /></p>
<ul>
<li>找到入度为0的顶点,只有一个D,拿D,剪掉D相关的边</li>
<li>得到两个入度为0的顶点(C1,C2),根据最左原则,拿C1,剪掉C1相关的边,这时候序列为{D,C1}</li>
<li>接着看,入度为0的顶点有两个(A,C1),根据最左原则,拿A,剪掉A相关的边,这时候序列为{D,C1,A}</li>
<li>接着看,入度为0的顶点为C2,拿C2,剪掉C2相关的边,这时候序列为{D,C1,A,C2}</li>
<li>继续,入度为0的顶点为B,拿B,剪掉B相关的边,最后还有一个object</li>
<li>所以最后的序列为{D,C1,A,C2,B,object}</li>
</ul>
<p>最后,我们执行上面的代码,发现<code class="highlighter-rouge">print(D.__mro__)</code>的结果正如上面所计算的结果</p>
<p>最后的最后,python继承顺序遵循C3算法,只要在一个地方找到了所需的内容,就不再继续查找</p></content><author><name>KevinGuo</name></author><summary type="html">最近在学python,学到class 多重继承,降到了c3算法,这里记录一下</summary></entry><entry><title type="html">jenkins with pipeline on kubernetes</title><link href="https://kevinguo.me/2017/12/27/jenkins-on-kubernetes-with-pipeline/" rel="alternate" type="text/html" title="jenkins with pipeline on kubernetes" /><published>2017-12-27T00:00:00+08:00</published><updated>2017-12-27T00:00:00+08:00</updated><id>https://kevinguo.me/2017/12/27/jenkins-on-kubernetes-with-pipeline</id><content type="html" xml:base="https://kevinguo.me/2017/12/27/jenkins-on-kubernetes-with-pipeline/"><blockquote>
<p>jenkins CI/CD用了有很长一段时间了,包括现公司的docker container deployment也是通过写pipeline workflow来实现的,但是当我在将jenkins迁往kubernetes的过程中,还是踩了不少的坑,这里记录下来。</p>
</blockquote>
<!--more-->
<p>该流程包含了 <code class="highlighter-rouge">checkout scm</code> –&gt; <code class="highlighter-rouge">build artifacts</code> –&gt; <code class="highlighter-rouge">build image</code> –&gt; <code class="highlighter-rouge">deploy to k8s</code></p>
<p>流程相对简单,而且并没有涉及到代码分支,集中测试,蓝绿部署等等</p>
<h3 id="一集群以及必要组件的搭建">一、集群以及必要组件的搭建</h3>
<p>请参考<a href="https://kevinguo.me/categories/#kubernetes">手动搭建kubernetes HA集群</a>,<a href="https://kevinguo.me/categories/#ceph">kubernetes ceph笔记</a></p>
<h3 id="二jenkins各个yaml文件">二、jenkins各个yaml文件</h3>
<p>所有文件都放在<a href="https://github.com/chinakevinguo/kubernetes-jenkins.git">这里</a>,我们搭建的时候只需将对应的位置修改成自己的即可</p>
<h3 id="三配置jenkins">三、配置jenkins</h3>
<blockquote>
<p>jenkins 部署成功之后,我们需要安装对应的插件,配置和kubernetes的关联,这里除了必要的插件之外,我们额外需要安装一个kubernetes Plugin</p>
</blockquote>
<p>kubernetes cloud的配置相对简单,我们只需要指定<code class="highlighter-rouge">Kubernetes URL</code>以及<code class="highlighter-rouge">Jenkins URL</code>即可,因为jenkins在kubernetes中,所以<code class="highlighter-rouge">Kubernetes URL</code>和<code class="highlighter-rouge">Jenkins URL</code>均为内部service就行了,如下图</p>
<p><img src="/images/posts/kubernetes-cloud.png" alt="" /></p>
<h3 id="四新建pipeline-job-测试">四、新建pipeline job 测试</h3>
<blockquote>
<p>jenkins kubernetes cloud配置成功之后,我们就需要来新建一个pipeline job测试一下,这里我新建了一个<code class="highlighter-rouge">learn-groovy</code>的job</p>
</blockquote>
<p>新建job更加的简单,只需要指定你的<code class="highlighter-rouge">Jenkinsfile</code>的地址即可,如下图</p>
<p><img src="/images/posts/jenkins-pipeline.png" alt="" /></p>
<blockquote>
<p>所有的工作都在<code class="highlighter-rouge">Jenkinsfile</code>中定义完成,这就是pipeline了</p>
</blockquote>
<p>关于当前这个example项目的对应配置文件有如下几个</p>
<ul>
<li>app-deploy.yaml 当前项目部署所需的yaml文件</li>
<li>Jenkinsfile 当前项目部署流程所需文件</li>
<li>Jenkinsfile.yaml 当前项目构建部署过程中可变参数的变量文件</li>
<li>Dockerfile 构建image所需文件</li>
</ul>
<p>以上所有文件在<a href="https://github.com/chinakevinguo/learn-groovy.git">这里</a></p>
<p>我们的job构建成功后,最终的结果如下</p>
<p><img src="/images/posts/jenkins-kubernetes-result.png" alt="" /></p>
<p><img src="/images/posts/jenkins-kubernetes-result-2.png" alt="" /></p></content><author><name>KevinGuo</name></author><summary type="html">jenkins CI/CD用了有很长一段时间了,包括现公司的docker container deployment也是通过写pipeline workflow来实现的,但是当我在将jenkins迁往kubernetes的过程中,还是踩了不少的坑,这里记录下来。</summary></entry><entry><title type="html">kubernetes RBAC 概念</title><link href="https://kevinguo.me/2017/12/01/kubernetes-rbac-concept/" rel="alternate" type="text/html" title="kubernetes RBAC 概念" /><published>2017-12-01T00:00:00+08:00</published><updated>2017-12-01T00:00:00+08:00</updated><id>https://kevinguo.me/2017/12/01/kubernetes-rbac-concept</id><content type="html" xml:base="https://kevinguo.me/2017/12/01/kubernetes-rbac-concept/"><blockquote>
<p>注:全文转载于https://jimmysong.io/kubernetes-handbook/guide/rbac.html
主要是为了避免以后想查看概念的时候找不到位置,望作者见谅
以下所有内容是 <a href="https://github.com/xingzhou">xingzhou</a> 对 kubernetes 官方文档的翻译,原文地址 https://k8smeetup.github.io/docs/admin/authorization/rbac/</p>
</blockquote>
<!--more-->
<h1 id="rbac基于角色的访问控制">RBAC——基于角色的访问控制</h1>
<p>基于角色的访问控制(Role-Based Access Control, 即”RBAC”)使用”rbac.authorization.k8s.io” API Group实现授权决策,允许管理员通过Kubernetes API动态配置策略。</p>
<p>截至Kubernetes 1.6,RBAC模式处于beta版本。</p>
<p>要启用RBAC,请使用<code class="highlighter-rouge">--authorization-mode=RBAC</code>启动API Server。</p>
<h2 id="api概述">API概述</h2>
<p>本节将介绍RBAC API所定义的四种顶级类型。用户可以像使用其他Kubernetes API资源一样 (例如通过<code class="highlighter-rouge">kubectl</code>、API调用等)与这些资源进行交互。例如,命令<code class="highlighter-rouge">kubectl create -f (resource).yml</code> 可以被用于以下所有的例子,当然,读者在尝试前可能需要先阅读以下相关章节的内容。</p>
<h3 id="role与clusterrole">Role与ClusterRole</h3>
<p>在RBAC API中,一个角色包含了一套表示一组权限的规则。 权限以纯粹的累加形式累积(没有”否定”的规则)。 角色可以由命名空间(namespace)内的<code class="highlighter-rouge">Role</code>对象定义,而整个Kubernetes集群范围内有效的角色则通过<code class="highlighter-rouge">ClusterRole</code>对象实现。</p>
<p>一个<code class="highlighter-rouge">Role</code>对象只能用于授予对某一单一命名空间中资源的访问权限。 以下示例描述了”default”命名空间中的一个<code class="highlighter-rouge">Role</code>对象的定义,用于授予对pod的读访问权限:</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">kind</span><span class="pi">:</span> <span class="s">Role</span>
<span class="na">apiVersion</span><span class="pi">:</span> <span class="s">rbac.authorization.k8s.io/v1beta1</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="na">namespace</span><span class="pi">:</span> <span class="s">default</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">pod-reader</span>
<span class="na">rules</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">apiGroups</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">"</span><span class="pi">]</span> <span class="c1"># 空字符串""表明使用core API group</span>
<span class="na">resources</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">pods"</span><span class="pi">]</span>
<span class="na">verbs</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">get"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">watch"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">list"</span><span class="pi">]</span>
</code></pre></div></div>
<p><code class="highlighter-rouge">ClusterRole</code>对象可以授予与<code class="highlighter-rouge">Role</code>对象相同的权限,但由于它们属于集群范围对象, 也可以使用它们授予对以下几种资源的访问权限:</p>
<ul>
<li>集群范围资源(例如节点,即node)</li>
<li>非资源类型endpoint(例如”/healthz”)</li>
<li>跨所有命名空间的命名空间范围资源(例如pod,需要运行命令<code class="highlighter-rouge">kubectl get pods --all-namespaces</code>来查询集群中所有的pod)</li>
</ul>
<p>下面示例中的<code class="highlighter-rouge">ClusterRole</code>定义可用于授予用户对某一特定命名空间,或者所有命名空间中的secret(取决于其<a href="https://k8smeetup.github.io/docs/admin/authorization/rbac/#rolebinding-and-clusterrolebinding">绑定</a>方式)的读访问权限:</p>
<pre><code class="language-Yaml">kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
# 鉴于ClusterRole是集群范围对象,所以这里不需要定义"namespace"字段
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]
</code></pre>
<h3 id="rolebinding与clusterrolebinding">RoleBinding与ClusterRoleBinding</h3>
<p>角色绑定将一个角色中定义的各种权限授予一个或者一组用户。 角色绑定包含了一组相关主体(即subject, 包括用户——User、用户组——Group、或者服务账户——Service Account)以及对被授予角色的引用。 在命名空间中可以通过<code class="highlighter-rouge">RoleBinding</code>对象授予权限,而集群范围的权限授予则通过<code class="highlighter-rouge">ClusterRoleBinding</code>对象完成。</p>
<p><code class="highlighter-rouge">RoleBinding</code>可以引用在同一命名空间内定义的<code class="highlighter-rouge">Role</code>对象。 下面示例中定义的<code class="highlighter-rouge">RoleBinding</code>对象在”default”命名空间中将”pod-reader”角色授予用户”jane”。 这一授权将允许用户”jane”从”default”命名空间中读取pod。</p>
<pre><code class="language-Yaml"># 以下角色绑定定义将允许用户"jane"从"default"命名空间中读取pod。
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: jane
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
</code></pre>
<p><code class="highlighter-rouge">RoleBinding</code>对象也可以引用一个<code class="highlighter-rouge">ClusterRole</code>对象用于在<code class="highlighter-rouge">RoleBinding</code>所在的命名空间内授予用户对所引用的<code class="highlighter-rouge">ClusterRole</code>中 定义的命名空间资源的访问权限。这一点允许管理员在整个集群范围内首先定义一组通用的角色,然后再在不同的命名空间中复用这些角色。</p>
<p>例如,尽管下面示例中的<code class="highlighter-rouge">RoleBinding</code>引用的是一个<code class="highlighter-rouge">ClusterRole</code>对象,但是用户”dave”(即角色绑定主体)还是只能读取”development” 命名空间中的secret(即<code class="highlighter-rouge">RoleBinding</code>所在的命名空间)。</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># 以下角色绑定允许用户"dave"读取"development"命名空间中的secret。</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">RoleBinding</span>
<span class="na">apiVersion</span><span class="pi">:</span> <span class="s">rbac.authorization.k8s.io/v1beta1</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">read-secrets</span>
<span class="na">namespace</span><span class="pi">:</span> <span class="s">development</span> <span class="c1"># 这里表明仅授权读取"development"命名空间中的资源。</span>
<span class="na">subjects</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">kind</span><span class="pi">:</span> <span class="s">User</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">dave</span>
<span class="na">apiGroup</span><span class="pi">:</span> <span class="s">rbac.authorization.k8s.io</span>
<span class="na">roleRef</span><span class="pi">:</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">ClusterRole</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">secret-reader</span>
<span class="na">apiGroup</span><span class="pi">:</span> <span class="s">rbac.authorization.k8s.io</span>
</code></pre></div></div>
<p>最后,可以使用<code class="highlighter-rouge">ClusterRoleBinding</code>在集群级别和所有命名空间中授予权限。下面示例中所定义的<code class="highlighter-rouge">ClusterRoleBinding</code> 允许在用户组”manager”中的任何用户都可以读取集群中任何命名空间中的secret。</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># 以下`ClusterRoleBinding`对象允许在用户组"manager"中的任何用户都可以读取集群中任何命名空间中的secret。</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">ClusterRoleBinding</span>
<span class="na">apiVersion</span><span class="pi">:</span> <span class="s">rbac.authorization.k8s.io/v1beta1</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">read-secrets-global</span>
<span class="na">subjects</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">kind</span><span class="pi">:</span> <span class="s">Group</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">manager</span>
<span class="na">apiGroup</span><span class="pi">:</span> <span class="s">rbac.authorization.k8s.io</span>
<span class="na">roleRef</span><span class="pi">:</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">ClusterRole</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">secret-reader</span>
<span class="na">apiGroup</span><span class="pi">:</span> <span class="s">rbac.authorization.k8s.io</span>
</code></pre></div></div>
<h3 id="对资源的引用">对资源的引用</h3>
<p>大多数资源由代表其名字的字符串表示,例如”pods”,就像它们出现在相关API endpoint的URL中一样。然而,有一些Kubernetes API还 包含了”子资源”,比如pod的logs。在Kubernetes中,pod logs endpoint的URL格式为:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>GET /api/v1/namespaces/{namespace}/pods/{name}/log
</code></pre></div></div>
<p>在这种情况下,”pods”是命名空间资源,而”log”是pods的子资源。为了在RBAC角色中表示出这一点,我们需要使用斜线来划分资源 与子资源。如果需要角色绑定主体读取pods以及pod log,您需要定义以下角色:</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">kind</span><span class="pi">:</span> <span class="s">Role</span>
<span class="na">apiVersion</span><span class="pi">:</span> <span class="s">rbac.authorization.k8s.io/v1beta1</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="na">namespace</span><span class="pi">:</span> <span class="s">default</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">pod-and-pod-logs-reader</span>
<span class="na">rules</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">apiGroups</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">"</span><span class="pi">]</span>
<span class="na">resources</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">pods"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">pods/log"</span><span class="pi">]</span>
<span class="na">verbs</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">get"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">list"</span><span class="pi">]</span>
</code></pre></div></div>
<p>通过<code class="highlighter-rouge">resourceNames</code>列表,角色可以针对不同种类的请求根据资源名引用资源实例。当指定了<code class="highlighter-rouge">resourceNames</code>列表时,不同动作 种类的请求的权限,如使用”get”、”delete”、”update”以及”patch”等动词的请求,将被限定到资源列表中所包含的资源实例上。 例如,如果需要限定一个角色绑定主体只能”get”或者”update”一个configmap时,您可以定义以下角色:</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">kind</span><span class="pi">:</span> <span class="s">Role</span>
<span class="na">apiVersion</span><span class="pi">:</span> <span class="s">rbac.authorization.k8s.io/v1beta1</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="na">namespace</span><span class="pi">:</span> <span class="s">default</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">configmap-updater</span>
<span class="na">rules</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">apiGroups</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">"</span><span class="pi">]</span>
<span class="na">resources</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">configmap"</span><span class="pi">]</span>
<span class="na">resourceNames</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">my-configmap"</span><span class="pi">]</span>
<span class="na">verbs</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">update"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">get"</span><span class="pi">]</span>
</code></pre></div></div>
<p>值得注意的是,如果设置了<code class="highlighter-rouge">resourceNames</code>,则请求所使用的动词不能是list、watch、create或者deletecollection。 由于资源名不会出现在create、list、watch和deletecollection等API请求的URL中,所以这些请求动词不会被设置了<code class="highlighter-rouge">resourceNames</code> 的规则所允许,因为规则中的<code class="highlighter-rouge">resourceNames</code>部分不会匹配这些请求。</p>
<h4 id="一些角色定义的例子">一些角色定义的例子</h4>
<p>在以下示例中,我们仅截取展示了<code class="highlighter-rouge">rules</code>部分的定义。</p>
<p>允许读取core API Group中定义的资源”pods”:</p>
<pre><code class="language-Yaml">rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
</code></pre>
<p>允许读写在”extensions”和”apps” API Group中定义的”deployments”:</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">rules</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">apiGroups</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">extensions"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">apps"</span><span class="pi">]</span>
<span class="na">resources</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">deployments"</span><span class="pi">]</span>
<span class="na">verbs</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">get"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">list"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">watch"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">create"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">update"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">patch"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">delete"</span><span class="pi">]</span>
</code></pre></div></div>
<p>允许读取”pods”以及读写”jobs”:</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">rules</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">apiGroups</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">"</span><span class="pi">]</span>
<span class="na">resources</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">pods"</span><span class="pi">]</span>
<span class="na">verbs</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">get"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">list"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">watch"</span><span class="pi">]</span>
<span class="pi">-</span> <span class="na">apiGroups</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">batch"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">extensions"</span><span class="pi">]</span>
<span class="na">resources</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">jobs"</span><span class="pi">]</span>
<span class="na">verbs</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">get"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">list"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">watch"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">create"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">update"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">patch"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">delete"</span><span class="pi">]</span>
</code></pre></div></div>
<p>允许读取一个名为”my-config”的<code class="highlighter-rouge">ConfigMap</code>实例(需要将其通过<code class="highlighter-rouge">RoleBinding</code>绑定从而限制针对某一个命名空间中定义的一个<code class="highlighter-rouge">ConfigMap</code>实例的访问):</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">rules</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">apiGroups</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">"</span><span class="pi">]</span>
<span class="na">resources</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">configmaps"</span><span class="pi">]</span>
<span class="na">resourceNames</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">my-config"</span><span class="pi">]</span>
<span class="na">verbs</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">get"</span><span class="pi">]</span>
</code></pre></div></div>
<p>允许读取core API Group中的”nodes”资源(由于<code class="highlighter-rouge">Node</code>是集群级别资源,所以此<code class="highlighter-rouge">ClusterRole</code>定义需要与一个<code class="highlighter-rouge">ClusterRoleBinding</code>绑定才能有效):</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">rules</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">apiGroups</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">"</span><span class="pi">]</span>
<span class="na">resources</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">nodes"</span><span class="pi">]</span>
<span class="na">verbs</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">get"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">list"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">watch"</span><span class="pi">]</span>
</code></pre></div></div>
<p>允许对非资源endpoint “/healthz”及其所有子路径的”GET”和”POST”请求(此<code class="highlighter-rouge">ClusterRole</code>定义需要与一个<code class="highlighter-rouge">ClusterRoleBinding</code>绑定才能有效):</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">rules</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">nonResourceURLs</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">/healthz"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">/healthz/*"</span><span class="pi">]</span> <span class="c1"># 在非资源URL中,'*'代表后缀通配符</span>
<span class="na">verbs</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">get"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">post"</span><span class="pi">]</span>
</code></pre></div></div>
<h3 id="对角色绑定主体subject的引用">对角色绑定主体(Subject)的引用</h3>
<p><code class="highlighter-rouge">RoleBinding</code>或者<code class="highlighter-rouge">ClusterRoleBinding</code>将角色绑定到<em>角色绑定主体</em>(Subject)。 角色绑定主体可以是用户组(Group)、用户(User)或者服务账户(Service Accounts)。</p>
<p>用户由字符串表示。可以是纯粹的用户名,例如”alice”、电子邮件风格的名字,如 “[email protected]” 或者是用字符串表示的数字id。由Kubernetes管理员配置<a href="https://k8smeetup.github.io/docs/admin/authentication/">认证模块</a> 以产生所需格式的用户名。对于用户名,RBAC授权系统不要求任何特定的格式。然而,前缀<code class="highlighter-rouge">system:</code>是 为Kubernetes系统使用而保留的,所以管理员应该确保用户名不会意外地包含这个前缀。</p>
<p>Kubernetes中的用户组信息由授权模块提供。用户组与用户一样由字符串表示。Kubernetes对用户组 字符串没有格式要求,但前缀<code class="highlighter-rouge">system:</code>同样是被系统保留的。</p>
<p><a href="https://k8smeetup.github.io/docs/tasks/configure-pod-container/configure-service-account/">服务账户</a>拥有包含 <code class="highlighter-rouge">system:serviceaccount:</code>前缀的用户名,并属于拥有<code class="highlighter-rouge">system:serviceaccounts:</code>前缀的用户组。</p>
<h4 id="角色绑定的一些例子">角色绑定的一些例子</h4>
<p>以下示例中,仅截取展示了<code class="highlighter-rouge">RoleBinding</code>的<code class="highlighter-rouge">subjects</code>字段。</p>
<p>一个名为”[email protected]”的用户:</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">subjects</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">kind</span><span class="pi">:</span> <span class="s">User</span>
<span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">[email protected]"</span>
<span class="na">apiGroup</span><span class="pi">:</span> <span class="s">rbac.authorization.k8s.io</span>
</code></pre></div></div>
<p>一个名为”frontend-admins”的用户组:</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">subjects</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">kind</span><span class="pi">:</span> <span class="s">Group</span>
<span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">frontend-admins"</span>
<span class="na">apiGroup</span><span class="pi">:</span> <span class="s">rbac.authorization.k8s.io</span>
</code></pre></div></div>
<p>kube-system命名空间中的默认服务账户:</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">subjects</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">kind</span><span class="pi">:</span> <span class="s">ServiceAccount</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">default</span>
<span class="na">namespace</span><span class="pi">:</span> <span class="s">kube-system</span>
</code></pre></div></div>
<p>名为”qa”命名空间中的所有服务账户:</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">subjects</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">kind</span><span class="pi">:</span> <span class="s">Group</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">system:serviceaccounts:qa</span>
<span class="na">apiGroup</span><span class="pi">:</span> <span class="s">rbac.authorization.k8s.io</span>
</code></pre></div></div>
<p>在集群中的所有服务账户:</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">subjects</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">kind</span><span class="pi">:</span> <span class="s">Group</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">system:serviceaccounts</span>
<span class="na">apiGroup</span><span class="pi">:</span> <span class="s">rbac.authorization.k8s.io</span>
</code></pre></div></div>
<p>所有认证过的用户(version 1.5+):</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">subjects</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">kind</span><span class="pi">:</span> <span class="s">Group</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">system:authenticated</span>
<span class="na">apiGroup</span><span class="pi">:</span> <span class="s">rbac.authorization.k8s.io</span>
</code></pre></div></div>
<p>所有未认证的用户(version 1.5+):</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">subjects</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">kind</span><span class="pi">:</span> <span class="s">Group</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">system:unauthenticated</span>
<span class="na">apiGroup</span><span class="pi">:</span> <span class="s">rbac.authorization.k8s.io</span>
</code></pre></div></div>
<p>所有用户(version 1.5+):</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">subjects</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">kind</span><span class="pi">:</span> <span class="s">Group</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">system:authenticated</span>
<span class="na">apiGroup</span><span class="pi">:</span> <span class="s">rbac.authorization.k8s.io</span>
<span class="pi">-</span> <span class="na">kind</span><span class="pi">:</span> <span class="s">Group</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">system:unauthenticated</span>
<span class="na">apiGroup</span><span class="pi">:</span> <span class="s">rbac.authorization.k8s.io</span>
</code></pre></div></div>
<h2 id="默认角色与默认角色绑定">默认角色与默认角色绑定</h2>
<p>API Server会创建一组默认的<code class="highlighter-rouge">ClusterRole</code>和<code class="highlighter-rouge">ClusterRoleBinding</code>对象。 这些默认对象中有许多包含<code class="highlighter-rouge">system:</code>前缀,表明这些资源由Kubernetes基础组件”拥有”。 对这些资源的修改可能导致非功能性集群(non-functional cluster)。一个例子是<code class="highlighter-rouge">system:node</code> ClusterRole对象。 这个角色定义了kubelets的权限。如果这个角色被修改,可能会导致kubelets无法正常工作。</p>
<p>所有默认的ClusterRole和ClusterRoleBinding对象都会被标记为<code class="highlighter-rouge">kubernetes.io/bootstrapping=rbac-defaults</code>。</p>
<h3 id="自动更新">自动更新</h3>
<p>每次启动时,API Server都会更新默认ClusterRole所缺乏的各种权限,并更新默认ClusterRoleBinding所缺乏的各个角色绑定主体。 这种自动更新机制允许集群修复一些意外的修改。由于权限和角色绑定主体在新的Kubernetes释出版本中可能变化,这也能够保证角色和角色 绑定始终保持是最新的。</p>
<p>如果需要禁用自动更新,请将默认ClusterRole以及ClusterRoleBinding的<code class="highlighter-rouge">rbac.authorization.kubernetes.io/autoupdate</code> 设置成为<code class="highlighter-rouge">false</code>。 请注意,缺乏默认权限和角色绑定主体可能会导致非功能性集群问题。</p>
<p>自Kubernetes 1.6+起,当集群RBAC授权器(RBAC Authorizer)处于开启状态时,可以启用自动更新功能.</p>
<h3 id="发现类角色">发现类角色</h3>
<table>
<thead>
<tr>
<th>默认ClusterRole</th>
<th>默认ClusterRoleBinding</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>system:basic-user</strong></td>
<td><strong>system:authenticated</strong> and <strong>system:unauthenticated</strong>groups</td>
<td>允许用户只读访问有关自己的基本信息。</td>
</tr>
<tr>
<td><strong>system:discovery</strong></td>
<td><strong>system:authenticated</strong> and <strong>system:unauthenticated</strong>groups</td>
<td>允许只读访问API discovery endpoints, 用于在API级别进行发现和协商。</td>
</tr>
</tbody>
</table>
<h3 id="面向用户的角色">面向用户的角色</h3>
<p>一些默认角色并不包含<code class="highlighter-rouge">system:</code>前缀,它们是面向用户的角色。 这些角色包含超级用户角色(<code class="highlighter-rouge">cluster-admin</code>),即旨在利用ClusterRoleBinding(<code class="highlighter-rouge">cluster-status</code>)在集群范围内授权的角色, 以及那些使用RoleBinding(<code class="highlighter-rouge">admin</code>、<code class="highlighter-rouge">edit</code>和<code class="highlighter-rouge">view</code>)在特定命名空间中授权的角色。</p>
<table>
<thead>
<tr>
<th>默认ClusterRole</th>
<th>默认ClusterRoleBinding</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>cluster-admin</strong></td>
<td><strong>system:masters</strong> group</td>
<td>超级用户权限,允许对任何资源执行任何操作。 在<strong>ClusterRoleBinding</strong>中使用时,可以完全控制集群和所有命名空间中的所有资源。 在<strong>RoleBinding</strong>中使用时,可以完全控制RoleBinding所在命名空间中的所有资源,包括命名空间自己。</td>
</tr>
<tr>
<td><strong>admin</strong></td>
<td>None</td>
<td>管理员权限,利用<strong>RoleBinding</strong>在某一命名空间内部授予。 在<strong>RoleBinding</strong>中使用时,允许针对命名空间内大部分资源的读写访问, 包括在命名空间内创建角色与角色绑定的能力。 但不允许对资源配额(resource quota)或者命名空间本身的写访问。</td>
</tr>
<tr>
<td><strong>edit</strong></td>
<td>None</td>
<td>允许对某一个命名空间内大部分对象的读写访问,但不允许查看或者修改角色或者角色绑定。</td>
</tr>
<tr>
<td><strong>view</strong></td>
<td>None</td>
<td>允许对某一个命名空间内大部分对象的只读访问。 不允许查看角色或者角色绑定。 由于可扩散性等原因,不允许查看secret资源。</td>
</tr>
</tbody>
</table>
<h3 id="core-component-roles">Core Component Roles</h3>
<h3 id="核心组件角色">核心组件角色</h3>
<table>
<thead>
<tr>
<th>默认ClusterRole</th>
<th>默认ClusterRoleBinding</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>system:kube-scheduler</strong></td>
<td><strong>system:kube-scheduler</strong> user</td>
<td>允许访问kube-scheduler组件所需要的资源。</td>
</tr>
<tr>
<td><strong>system:kube-controller-manager</strong></td>
<td><strong>system:kube-controller-manager</strong> user</td>
<td>允许访问kube-controller-manager组件所需要的资源。 单个控制循环所需要的权限请参阅<a href="https://k8smeetup.github.io/docs/admin/authorization/rbac/#controller-roles">控制器(controller)角色</a>.</td>
</tr>
<tr>
<td><strong>system:node</strong></td>
<td><strong>system:nodes</strong> group (deprecated in 1.7)</td>
<td>允许对kubelet组件所需要的资源的访问,<strong>包括读取所有secret和对所有pod的写访问</strong>。 自Kubernetes 1.7开始, 相比较于这个角色,更推荐使用<a href="https://kubernetes.io/docs/admin/authorization/node/">Node authorizer</a> 以及<a href="https://kubernetes.io/docs/admin/admission-controllers#NodeRestriction">NodeRestriction admission plugin</a>, 并允许根据调度运行在节点上的pod授予kubelets API访问的权限。 自Kubernetes 1.7开始,当启用<code class="highlighter-rouge">Node</code>授权模式时,对<code class="highlighter-rouge">system:nodes</code>用户组的绑定将不会被自动创建。</td>
</tr>
<tr>
<td><strong>system:node-proxier</strong></td>
<td><strong>system:kube-proxy</strong> user</td>
<td>允许对kube-proxy组件所需要资源的访问。</td>
</tr>
</tbody>
</table>
<h3 id="其它组件角色">其它组件角色</h3>
<table>
<thead>
<tr>
<th>默认ClusterRole</th>
<th>默认ClusterRoleBinding</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>system:auth-delegator</strong></td>
<td>None</td>
<td>允许委托认证和授权检查。 通常由附加API Server用于统一认证和授权。</td>
</tr>
<tr>
<td><strong>system:heapster</strong></td>
<td>None</td>
<td><a href="https://github.com/kubernetes/heapster">Heapster</a>组件的角色。</td>
</tr>
<tr>
<td><strong>system:kube-aggregator</strong></td>
<td>None</td>
<td><a href="https://github.com/kubernetes/kube-aggregator">kube-aggregator</a>组件的角色。</td>
</tr>
<tr>
<td><strong>system:kube-dns</strong></td>
<td><strong>kube-dns</strong> service account in the <strong>kube-system</strong>namespace</td>
<td><a href="https://k8smeetup.github.io/docs/admin/dns/">kube-dns</a>组件的角色。</td>
</tr>
<tr>
<td><strong>system:node-bootstrapper</strong></td>
<td>None</td>
<td>允许对执行<a href="https://k8smeetup.github.io/docs/admin/kubelet-tls-bootstrapping/">Kubelet TLS引导(Kubelet TLS bootstrapping)</a>所需要资源的访问.</td>
</tr>
<tr>
<td><strong>system:node-problem-detector</strong></td>
<td>None</td>
<td><a href="https://github.com/kubernetes/node-problem-detector">node-problem-detector</a>组件的角色。</td>
</tr>
<tr>
<td><strong>system:persistent-volume-provisioner</strong></td>
<td>None</td>
<td>允许对大部分<a href="https://k8smeetup.github.io/docs/user-guide/persistent-volumes/#provisioner">动态存储卷创建组件(dynamic volume provisioner)</a>所需要资源的访问。</td>
</tr>
</tbody>
</table>
<h3 id="控制器controller角色">控制器(Controller)角色</h3>
<p><a href="https://k8smeetup.github.io/docs/admin/kube-controller-manager/">Kubernetes controller manager</a>负责运行核心控制循环。 当使用<code class="highlighter-rouge">--use-service-account-credentials</code>选项运行controller manager时,每个控制循环都将使用单独的服务账户启动。 而每个控制循环都存在对应的角色,前缀名为<code class="highlighter-rouge">system:controller:</code>。 如果不使用<code class="highlighter-rouge">--use-service-account-credentials</code>选项时,controller manager将会使用自己的凭证运行所有控制循环,而这些凭证必须被授予相关的角色。 这些角色包括:</p>