闲谈线上俩k8s环境同等limits下pod启动时间不一样解决过程

线上用的k8s版本是1.6.7非常老,而且HA有问题,上个月研发想把里面的一些服务迁出来到一个新集群里,新集群的搭建是我负责的。上周开始陆陆续续的迁移过来了,但是同等limit下部分pod在测试环境上(测试环境和老环境部署是一样的,下文的老环境和测试环境可以理解为一样)启动非常快,在我搭建的新k8s环境上启动非常慢,研发他们应用都是java+springboot,这里不谈jvm无法识别cgroup,已经加选项识别到了还有那个随机熵的选项肯定也是加了的。
因为之前一次有个用户反映他们本地虚机启动springboot应用20s,我们云上启动就三分钟,后面漠然大佬教我加java的启动参数输出log,帮我远程debug找到原因是zk客户端会解析hosts,加条localhost的hosts就解决了。在得知他们用的也是springboot后一开始就怀疑是他们代码问题(毕竟java),建议他们去开debug自己看log。

四五天之前研发那边和我对接k8s的同事详细的探讨了启动不一致的问题,我询问了哪个pod可以随意启停,然后在新环境上把该pod的command改成sh和 tty:true
,去掉就绪和生存探针手动进去启动进程,启动的时候加了java的运行参数打印一系列的更详细的log,把log发给qingmu.io大佬,大佬看了说了句你这cpu限制得太厉害了吧。我才发现新环境上pod的cpu限制得比老环境还小,然后改成老环境一样就非常快了。

然后今天研发同事又说启动慢,限制一样的还是启动慢,这里放下他说的原话: 相同资源下,A环境服务比测试环境启动慢上一倍-3倍,当cpu3核时,启动时间差距就没那么大了
,这个话和qingmu.io大佬之前看到日志说cpu限制得太厉害了是提示了我找到原因的关键。
然后同事截图了下pod的limit,我看到cpu是1,这不刚好3倍吗,毕竟k8s的容器cpu限制是基于时间占比的,寻思着cpu是不是不一样,叫同事把他们那边测试环境的lscpu输出截图

$ lscpu
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                24
On-line CPU(s) list:   0-23
Thread(s) per core:    1
Core(s) per socket:    1
Socket(s):             24
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            15
Model:                 6
Model name:            Intel(R) Xeon(R) Gold 5118 CPU @ 2.30GHz
Stepping:              3
CPU MHz:               2700.017
BogoMIPS:              4589.20
Hypervisor vendor:     KVM
Virtualization type:   full
L1d cache:             32K
L1i cache:             32K
L2 cache:              4096K
L3 cache:              16384K
NUMA node0 CPU(s):     0-23
Flags:                 fpu de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 syscall nx lm constant_tsc nopl xtopology eagerfpu pni cx16 x2apic hypervisor lahf_lm

下面这个是新环境的lscpu输出

Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                56
On-line CPU(s) list:   0-55
Thread(s) per core:    2
Core(s) per socket:    14
Socket(s):             2
NUMA node(s):          2
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 85
Model name:            Intel(R) Xeon(R) Gold 6132 CPU @ 2.60GHz
Stepping:              4
CPU MHz:               999.914
CPU max MHz:           3700.0000
CPU min MHz:           1000.0000
BogoMIPS:              5200.00
Virtualization:        VT-x
L1d cache:             32K
L1i cache:             32K
L2 cache:              1024K
L3 cache:              19712K
NUMA node0 CPU(s):     0-13,28-41
NUMA node1 CPU(s):     14-27,42-55

这一对比就发现了问题所在,新环境的cpu频率平均稳定在999.914,也就是 CPU MHz
,测试环境是虚机,虽说它没max和min Mhz(应该是虚拟化相关的设置导致没有的)但是它的平均频率也约等于新环境平均频率的三倍,寻思着应该是cpu的省电模式之类的,一对比发现每个核心频率都很低

$  grep -i mhz /proc/cpuinfo 
cpu MHz     : 999.914
cpu MHz     : 999.914
cpu MHz     : 999.914
cpu MHz     : 1000.073
cpu MHz     : 999.914
cpu MHz     : 999.914
cpu MHz     : 999.914
cpu MHz     : 999.914
cpu MHz     : 999.914
cpu MHz     : 999.914
cpu MHz     : 1000.073
cpu MHz     : 999.914
cpu MHz     : 999.914
cpu MHz     : 1000.073
cpu MHz     : 1000.073
cpu MHz     : 1000.073
cpu MHz     : 999.914
cpu MHz     : 999.914
cpu MHz     : 999.914
cpu MHz     : 999.914
cpu MHz     : 999.914
cpu MHz     : 999.914
cpu MHz     : 999.914
cpu MHz     : 999.914
cpu MHz     : 999.914
cpu MHz     : 1000.073
cpu MHz     : 999.914
cpu MHz     : 999.914
cpu MHz     : 999.914
cpu MHz     : 1000.231
cpu MHz     : 1298.889
cpu MHz     : 1001.025
cpu MHz     : 1000.073
cpu MHz     : 1000.390
cpu MHz     : 1000.390
cpu MHz     : 1000.231
cpu MHz     : 1000.073
cpu MHz     : 1000.708
cpu MHz     : 1001.025
cpu MHz     : 1000.231
cpu MHz     : 999.914
cpu MHz     : 1000.231
cpu MHz     : 1000.073
cpu MHz     : 1000.073
cpu MHz     : 1382.519
cpu MHz     : 1327.929
cpu MHz     : 999.914
cpu MHz     : 1157.653
cpu MHz     : 1121.313
cpu MHz     : 1000.073
cpu MHz     : 1193.518
cpu MHz     : 1000.073
cpu MHz     : 1000.231
cpu MHz     : 1000.390
cpu MHz     : 1000.390
cpu MHz     : 1000.073

然后查找了下设置cpu什么最小频率的命令给找到了下面信息.
在Linux中,内核的开发者定义了一套框架模型来完成CPU频率动态调整这一目的,它就是CPU Freq系统。尽管在各个Linux发行版中,前端软件稍有差异,但其最终都会通过Linux内核的CPU Freq系统来实现CPU频率动态调整的功能。这些软件都会提供如下CPU模式(governor参数)
使用下列命令查看cpu的模式(governor参数)

$ cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
powersave
powersave
....

  • ondemand:系统默认的超频模式,按需调节,内核提供的功能,不是很强大,但有效实现了动态频率调节,平时以低速方式运行,当系统负载提高时候自动提高频率。以这种模式运行不会因为降频造成性能降低,同时也能节约电能和降低温度。一般官方内核默认的方式都是ondemand。
  • interactive:交互模式,直接上最高频率,然后看CPU负荷慢慢降低,比较耗电。Interactive 是以 CPU 排程数量而调整频率,从而实现省电。InteractiveX 是以 CPU 负载来调整 CPU 频率,不会过度把频率调低。所以比 Interactive 反应好些,但是省电的效果一般。
  • conservative:保守模式,类似于ondemand,但调整相对较缓,想省电就用他吧。Google官方内核,kang内核默认模式。
  • smartass:聪明模式,是I和C模式的升级,该模式在比interactive 模式不差的响应的前提下会做到了更加省电。
  • performance:性能模式!只有最高频率,从来不考虑消耗的电量,性能没得说,但是耗电量。
  • powersave 省电模式,通常以最低频率运行。
  • userspace:用户自定义模式,系统将变频策略的决策权交给了用户态应用程序,并提供了相应的接口供用户态应用程序调节CPU 运行频率使用。也就是长期以来都在用的那个模式。可以通过手动编辑配置文件进行配置
  • Hotplug:类似于ondemand, 但是cpu会在关屏下尝试关掉一个cpu,并且带有deep sleep,比较省电。

而新环境的cpu就是省电模式运行的,cpu频率极低,新环境不能重启,可能bios里有设置cpu工作模式选项,所以只能找在线修改的方法。查找了下设置模式的命令,最终找到了个靠谱的

$ cpupower -c all frequency-set -g performance
Setting cpu: 0
Setting cpu: 1
Setting cpu: 2
...
Setting cpu: 55
$ /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
performance
performance
performance
...

模式已经改变了,查看下工核心的作频率

grep -i mhz /proc/cpuinfo
cpu MHz     : 1870.495
cpu MHz     : 3127.331
cpu MHz     : 2348.156
cpu MHz     : 2160.900
cpu MHz     : 1918.896
cpu MHz     : 1756.237
cpu MHz     : 2635.388
cpu MHz     : 2115.673
cpu MHz     : 1989.196
cpu MHz     : 1708.312
cpu MHz     : 2226.916
cpu MHz     : 2683.471
cpu MHz     : 1654.199
cpu MHz     : 2696.643
cpu MHz     : 2258.020
cpu MHz     : 1957.299
cpu MHz     : 2357.360
cpu MHz     : 3345.214
cpu MHz     : 3096.704
cpu MHz     : 1361.413
cpu MHz     : 2991.650
cpu MHz     : 2209.777
cpu MHz     : 2505.102
cpu MHz     : 2493.359
cpu MHz     : 1823.999
cpu MHz     : 2132.812
cpu MHz     : 2622.058
cpu MHz     : 2049.340
cpu MHz     : 2217.871
cpu MHz     : 3294.592
cpu MHz     : 2478.442
cpu MHz     : 3284.436
cpu MHz     : 3279.199
cpu MHz     : 2265.002
cpu MHz     : 2650.622
cpu MHz     : 2250.720
cpu MHz     : 1804.797
cpu MHz     : 1626.269
cpu MHz     : 2827.404
cpu MHz     : 1602.783
cpu MHz     : 3270.312
cpu MHz     : 3283.166
cpu MHz     : 1676.257
cpu MHz     : 3270.312
cpu MHz     : 3331.726
cpu MHz     : 2591.748
cpu MHz     : 3323.950
cpu MHz     : 3312.683
cpu MHz     : 2978.002
cpu MHz     : 3251.269
cpu MHz     : 2968.005
cpu MHz     : 2234.216
cpu MHz     : 1717.199
cpu MHz     : 1733.227
cpu MHz     : 2282.458
cpu MHz     : 1455.358