最近遇到一个客户k8s测试集群经常崩溃,最终定位是etcd磁盘IO性能不足,最终替换成ssd盘解决,记录一下排查过程。
集群是跑在客户的共享虚机上,磁盘是机械硬盘,问题现象如下:
kube-system下涉及高可用的组件 kube-apiserver、kube-controller-manager、kube-scheduler 频繁重启,某些选主模式的组件、服务反复重启,频繁CrashLoopBackoff,查看其日志有"leaderelection lost",“timed out waiting for xxx”等字样
kubectl 反应慢,使用 kubectl get no --v=7,两三秒内才返回结果
查看kube-apiserver日志,看到有“etcdserver: request timed out”、“etcdserver:leader changed”等字样
查看etcd日志,有较多“xxx took too long”,“lost leader”等字样,time spent达到了几百ms,甚至两三秒
从现象上看,问题很可能出现在etcd上~
etcd性能瓶颈及稳定性分析链路图:
图片来源:极客时间《etcd实战课》
etcd集群性能受磁盘IO、时钟同步、master之间的网络以及节点负载影响,根据经验,磁盘IO导致的可能性较大。
1、时间同步验证
使用pssh工具,或ssh 机器执行date命令,对比时钟差异是否超过1s。时钟不同步,可以使用chrony或ntp或自建时钟源,将集群所有节点连接到同一时钟源,确保时钟同步。参考:Chrony详解:代替ntp的时间同步服务
2、master节点负载、CPU、MEM、IO、NET等检察,查看系统日志是否有明显报错,比如硬件报错,OOM(out of memory)等
使用top,iostat,iftop,iotop,sar,netstat,vmstat查看系统基础指标
使用scp,ipref,dd,fio等工具测试网络及磁盘性能:
# 制作1GB文件 dd if=/dev/zero of=/tmp/test-net bs=1M count=1000 # 测试传输速度 scp /tmp/test-net root@$master2:/tmp/ scp /tmp/test-net root@$master3:/tmp/
一般来说千兆带宽得达到约125MiB/s的传输速度;大规模集群( 500节点)需要兆带宽,网络需要达到约1250MiB/s的传输速度。
etcd应用层提供了节点之间网络统计的metrics指标,分别如下:
etcd_network_active_peer,表示peer之间活跃的连接数;
etcd_network_peer_round_trip_time_seconds,表示peer之间RTT延时;
etcd_network_peer_sent_failures_total,表示发送给peer的失败消息数;
etcd_network_client_grpc_sent_bytes_total,表示server发送给client的总字节数,通过这个指标我们可以监控etcd出流量;
etcd_network_client_grpc_received_bytes_total,表示server收到client发送的总字节数,通过这个指标可以监控etcd入流量。
可以使用监控系统监控etcd网络指标,使用相关工具查看是否出现丢包等错误。
# 4k写 fio -direct=1 -iodepth=128 -thread -rw=write -ioengine=libaio -bs=4k -size=1G -numjobs=1-runtime=600 -group_reporting -name=mytest -filename=/var/lib/etcd/iotest # 4k读 fio -direct=1 -iodepth=128 -thread -rw=read -ioengine=libaio -bs=4k -size=1G -numjobs=1-runtime=600 -group_reporting -name=mytest -filename=/var/lib/etcd/iotest # 4K随机写: fio -direct=1 -iodepth=128 -thread -rw=randwrite -ioengine=libaio -bs=4k -size=1G -numjobs=1-runtime=600 -group_reporting -name=mytest -filename=/var/lib/etcd/iotest # 4K 随机读 fio -direct=1 -iodepth=128 -thread -rw=randread -ioengine=libaio -bs=4k -size=1G -numjobs=1-runtime=600 -group_reporting -name=mytest -filename=/var/lib/etcd/iotest # 1M写 fio -direct=1 -iodepth=64 -thread -rw=write -ioengine=libaio -bs=1M -size=8G -numjobs=1-runtime=600 -group_reporting -name=mytest -filename=/var/lib/etcd/iotest # 1M读 fio -direct=1 -iodepth=64 -thread -rw=read -ioengine=libaio -bs=1M -size=8G -numjobs=1-runtime=600 -group_reporting -name=mytest -filename=/var/lib/etcd/iotest
Master配置一块独立块设备:SSD是首选,推荐 [SSD 4K IOPS>=3300] 或 [企业级SAS硬盘rpm>=10000,最好15000] 或 [更高配置的NVMe)],参考:Linux系统下查看硬盘转速
3、kubectl descrbe node查看节点负载信息,在输出中检查 Allocated Resources 和 Conditions 部分,可以将占用高的无状态应用迁走,减轻master节点压力
最后排查发现master节点网络、节点负载、时间同步都正常,环境由于是共享虚拟机环境,机器IO性能很可能存在欺骗现象。
etcd性能不足原因定位:
1、检查 etcd 状态:
kubectl get pods -n kube-system -l component=etcd
2、查看 etcd 日志: