linux cpu占用率如何看
327
2022-10-22
ETCD 应急方案
[TOC]
ETCD 应急方案
ETCD 常见 FAQ
基本概念
etcd 是一个分布式的、可靠的 key-value 存储系统,它用于存储分布式系统中的关键数据一个 etcd 集群,通常会由 3 个或者 5 个节点组成,多个节点之间通过 Raft 一致性算法的完成分布式一致性协同,算法会选举出一个主节点作为 leader,由 leader 负责数据的同步与数据的分发。当 leader 出现故障后系统会自动地选取另一个节点成为 leader,并重新完成数据的同步。客户端在多个节点中,仅需要选择其中的任意一个就可以完成数据的读写,内部的状态及数据协同由 etcd 自身完成。在 etcd 整个架构中,有一个非常关键的概念叫做 quorum,quorum 的定义是 (n+1)/2,也就是说超过集群中半数节点组成的一个团体,在 3 个节点的集群中,etcd 可以容许 1 个节点故障,也就是只要有任何 2 个节点可用,etcd 就可以继续提供服务。同理,在 5 个节点的集群中,只要有任何 3 个节点可用,etcd 就可以继续提供服务,这也是 etcd 集群高可用的关键。在允许部分节点故障之后继续提供服务,就需要解决一个非常复杂的问题:分布式一致性。在 etcd 中,该分布式一致性算法由 Raft 一致性算法完成,这个算法本身是比较复杂的有机会再详细展开,这里仅做一个简单的介绍以方便大家对其有一个基本的认知。Raft 一致性算法能够工作的一个关键点是:任意两个 quorum 的成员之间一定会有一个交集(公共成员),也就是说只要有任意一个 quorum 存活,其中一定存在某一个节点(公共成员),它包含着集群中所有的被确认提交的数据。正是基于这一原理,Raft 一致性算法设计了一套数据同步机制,在 Leader 任期切换后能够重新同步上一个 quorum 被提交的所有数据,从而保证整个集群状态向前推进的过程中保持数据的一致。
常见故障与方案
Etcd 节点无法启动
etcd一般以静态pod方式运行,先通过“journalctl -u kubelet”检查该节点kubelet是否运行正常如果kubelet正常,查看kubelet日志看是否有pod无法启动日志信息通过kubectl logs -f -n kube-system etcd-$HOSTNAME,检查etcd启动日志是否有错误信息,如该节点与集群其他etcd节点网络是否正常互通,该节点etcd数据库目录(一般为/var/lib/etcd)是否正常该节点etcd数据目录是否损坏,如日志显示数据目录损坏,可以参考备份与恢复的方法,用备份文件恢复该节点数据目录
Kube-api无法连接etcd集群
检查kube-apisever的yaml配置,确认kube-api与etcd连接的网络正常,kube-apiserver节点ping etcd的ip能通,且telnet也是通的kube-api连接etcd集群的证书是否过期,证书是否配置正确(证书需由 /etc/kubernetes/pki/etcd/ca.crt签发)检查etcd集群本身是否正常
Ectd Timeout
选举时间调优
(https://etcd.io/docs/v3.2/tuning/) etcd 中的默认设置应该适用于平均网络延迟较低的本地网络上的安装。但是,当跨多个数据中心或通过具有高延迟的网络使用 etcd 时,心跳间隔和选举超时设置可能需要调整。 每个请求和响应都可能受到领导者和追随者上慢速磁盘的影响。这些超时中的每一个都表示从请求到另一台机器成功响应的总时间。 底层分布式共识协议依赖于两个独立的时间参数,以确保节点在一个停止或离线时能够移交领导权
*Heartbeat Interval*:这是领导者通知追随者它仍然是领导者的频率,该参数应围绕成员之间的往返时间进行设置。默认情况下,etcd 使用100ms心跳间隔。*Election Timeout*:此超时是跟随者节点在尝试成为领导者之前将持续多长时间而没有听到心跳。默认情况下,etcd 使用1000ms选举超时。
快照时间调优
etcd 将所有关键更改附加到日志文件。该日志会永远增长,并且是对密钥所做的每次更改的完整线性历史记录。完整的历史记录适用于轻度使用的集群,但频繁使用的集群会携带大量日志。为了避免日志过大,etcd 会定期创建快照。这些快照为 etcd 提供了一种通过保存系统的当前状态并删除旧日志来压缩日志的方法etcd 将在每 10,000 次更改后生成快照。如果 etcd 的内存使用率和磁盘使用率过高,可设置降低快照阈值
磁盘与网络
etcd 集群对磁盘延迟非常敏感。由于 etcd 必须将提案保存到其日志中,因此来自其他进程的磁盘活动可能会导致较长的fsync延迟。结果是 etcd 可能会错过心跳,导致请求超时和临时领导者丢失。当赋予高磁盘优先级时,etcd 服务器有时可以与这些进程一起稳定运行。在 Linux 上,etcd 的磁盘优先级可以配置为ionice :
$ sudo ionice -c2 -n0 -p `pgrep etcd`
如果 etcd leader 有大量并发客户端请求,可能会因为网络拥塞而延迟处理 follower peer 请求。这表现为跟随节点上的发送缓冲区错误消息:
dropped MsgProp to 247ae21ff9436b2d since streamMsg's sending buffer is full dropped MsgAppResp to 247ae21ff9436b2d since streamMsg's sending buffer is full
这些错误可以通过将 etcd 的对等流量优先于其客户端流量来解决。在 Linux 上,可以使用流量控制机制对对等流量进行优先级排序:
tc qdisc add dev eth0 root handle 1: prio bands 3 tc filter add dev eth0 parent 1: protocol ip prio 1 u32 match ip sport 2380 0xffff flowid 1:1 tc filter add dev eth0 parent 1: protocol ip prio 1 u32 match ip dport 2380 0xffff flowid 1:1 tc filter add dev eth0 parent 1: protocol ip prio 2 u32 match ip sport 2739 0xffff flowid 1:1 tc filter add dev eth0 parent 1: protocol ip prio 2 u32 match ip dport 2739 0xffff flowid 1:1
Etcd 集群损坏且无备份
停掉全部节点的etcd进程
mv /etc/kubernetes/manifests/etcd.yaml /tmp # 适用kubelet静态pod启动etcd情况
备份全部etcd节点的数据目录 cp -rp /var/lib/etcd /data选取一个节点的/var/lib/etcd/member/snap/db作为备份文件,重建etcd集群。这个与etcd 恢复的区别在于:数据是从目录复制而来,没有完整性的 hash,所以在使用恢复命令,etcdctl snapshot restore命令生成恢复数据目录时,须加--skip-hash-check参数数据可能会产生丢失,或无法恢复
ETCD warning “apply entries took too long”
在大多数 etcd 成员同意提交请求后,每个 etcd 服务器将请求应用到其数据存储并将结果持久化到磁盘,应用请求通常需要不到 50 毫秒。如果平均应用持续时间超过 100 毫秒,etcd 将警告条目应用时间过长。通常这个问题是由慢速磁盘引起的。磁盘可能在 etcd 和其他应用程序之间发生争用.第二个最常见的原因是 CPU 不足。如果监控机器的 CPU 使用率显示使用率很高,则可能没有足够的计算能力用于 etcd。将 etcd 移至专用机器,增加进程资源隔离 cgroup,或将 etcd 服务器进程重新调整为更高的优先级通常可以解决问题。
超出数据库空间 mvcc: database space exceeded
etcd 中的多版本并发控制数据模型保留了键空间的准确历史记录。如果不定期压缩此历史记录(例如,通过设置--auto-compaction),etcd 最终将耗尽其存储空间。如果 etcd 存储空间不足,它会发出空间配额警报以保护集群免受进一步写入。只要发出警报,etcd 就会以 error 响应写入请求mvcc: database space exceeded。 从低空间配额警报中恢复:
压缩etcd 的历史。对每个 etcd 端点进行碎片整理。解除警报。
Etcd 备份与恢复
还原
# 使用docker 为底层的,请使用docker 命令# 每台的master节点 IP 和主机名需要修改# 停止集群mv /etc/kubernetes/manifests /etc/kubernetes/manifests.bak# 备份原有etcd数据 mv /u01/local/kube-system/etcd /u01/local/kube-system/etcd-`date '+%Y%m%d-%H:%M:%S'`#还原第一台masternerdctl -n k8s.io run --rm \-v '/tmp:/tmp' \ # 指定备份至本地的 /tmp 目录的数据-v '/u01/local/kube-system:/u01/local/kube-system' \-v '/etc/kubernetes/pki/etcd:/etc/kubernetes/pki/etcd' \--env ETCDCTL_API=3 \'docker.kedacom.com:15000/etcd:3.5.0-0' \/bin/sh -c "etcdctl snapshot restore \ /tmp/etcd-snapshot-.db \ --name node-vdua \ --endpoints=10.165.16.5:2379 \ --cert=/etc/kubernetes/pki/etcd/server.crt \ --key=/etc/kubernetes/pki/etcd/server.key \ --cacert=/etc/kubernetes/pki/etcd/ca.crt \ --initial-advertise-peer-urls=\ --initial-cluster=node-vdua=\ --data-dir=/u01/local/kube-system/etcd \ --skip-hash-check=true"
nerdctl -n k8s.io run --rm \-v '/tmp:/tmp' \-v '/u01/local/kube-system:/u01/local/kube-system' \-v '/etc/kubernetes/pki/etcd:/etc/kubernetes/pki/etcd' \--env ETCDCTL_API=3 \'docker.kedacom.com:15000/etcd:3.5.0-0' \/bin/sh -c "etcdctl snapshot restore \ /tmp/etcd-snapshot-.db \ --name node-5zv8 \ --endpoints=10.165.16.6:2379 \ --cert=/etc/kubernetes/pki/etcd/server.crt \ --key=/etc/kubernetes/pki/etcd/server.key \ --cacert=/etc/kubernetes/pki/etcd/ca.crt \ --initial-advertise-peer-urls=\ --initial-cluster=node-5zv8=\ --data-dir=/u01/local/kube-system/etcd \ --skip-hash-check=true" ============================================================nerdctl -n k8s.io run --rm \-v '/tmp:/tmp' \-v '/u01/local/kube-system:/u01/local/kube-system' \-v '/etc/kubernetes/pki/etcd:/etc/kubernetes/pki/etcd' \--env ETCDCTL_API=3 \'docker.kedacom.com:15000/etcd:3.5.0-0' \/bin/sh -c "etcdctl snapshot restore \ /tmp/etcd-snapshot-.db \ --name node-2iup \ --endpoints=10.165.16.7:2379 \ --cert=/etc/kubernetes/pki/etcd/server.crt \ --key=/etc/kubernetes/pki/etcd/server.key \ --cacert=/etc/kubernetes/pki/etcd/ca.crt \ --initial-advertise-peer-urls=\ --initial-cluster=node-2iup=\ --data-dir=/u01/local/kube-system/etcd \ --skip-hash-check=true"#恢复集群mv /etc/kubernetes/manifests.bak /etc/kubernetes/manifests
备份
nerdctl -n k8s.io run --rm \-v '/tmp:/tmp' \-v '/etc/kubernetes/pki/etcd:/etc/kubernetes/pki/etcd' \--env ETCDCTL_API=3 \'docker.kedacom.com:15000/etcd:3.5.0-0' \/bin/sh -c "etcdctl snapshot save \ /tmp/etcd-snapshot-134.db \ # 备份至本地的 /tmp 目录下 --endpoints=10.165.16.5:2379 \ --cert=/etc/kubernetes/pki/etcd/server.crt \ --key=/etc/kubernetes/pki/etcd/server.key \ --cacert=/etc/kubernetes/pki/etcd/ca.crt"
巡检脚本示例
下面的脚本利用 curl 命令,调用 etcd 的 endpoint 的 healt h接口,逐个检查是否返回 true
#!/bin/bashETCD_YAML="/etc/kubernetes/manifests/etcd.yaml"ETCD_ENDPOINTS=`cat ${ETCD_YAML}|grep -i "initial-cluster=" |awk -F'=|,' '{print $3,$5,$7}'|sed -e "s/2380/2379/g"`ETCD_CA="/etc/kubernetes/pki/etcd/ca.crt"ETCD_KEY="/etc/kubernetes/pki/etcd/peer.key"ETCD_CRT="/etc/kubernetes/pki/etcd/peer.crt"for i in $ETCD_ENDPOINTS do curl --key ${ETCD_KEY} --cert ${ETCD_CRT} --cacert ${ETCD_CA} $i/health |grep true if [ $? -eq 0 ]; then echo -e "\033[32m etcd node $i is checked health\033[0m" else echo -e "\033[31m etcd node $i is checked failed\033[0m" fi done
工具推荐
lucas - 一个基于 Web 的 kubernetes etcd3.0+ 集群的键值查看器。
# Simply use docker command docker run -d -p 8088:8080 -v /etc/kubernetes/pki/etcd/:/etc/kubernetes/pki/etcd/ -e CA_FILE=/etc/kubernetes/pki/etcd/ca.crt -e CERT_FILE=/etc/kubernetes/pki/etcd/server.crt -e KEY_FILE=/etc/kubernetes/pki/etcd/server.key -e ENDPOINTS="registry.cn-hangzhou.aliyuncs.com/ringtail/lucas:0.0.2# use yaml kubectl create -f kubernetes-deployment.yaml (Add master node deployment affinity)
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~