处理一次k8s、calico无法分配podIP的心路历程

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 又一次偷偷化解了可能发生的重大事故。不想看过程的可以直接跳到末尾看处理方案。

又一次偷偷化解了可能发生的重大事故。不想看过程的可以直接跳到末尾看处理方案。

一个网络错误

某天,上kplcloud构建一个测试应用,构建完成之后发现新pod一直启动失败,并且抛出了以下错误信息:

Failed create pod sandbox: rpc error: code = Unknown desc = NetworkPlugin cni failed to set up pod "xxxxxx-fc4cb949f-gpkm2_xxxxxxx" network: netplugin failed but error parsing its diagnostic message "": unexpected end of JSON input

会k8s的运维同学早已不在,突然出问题了怎么办?

试着开始解决问题。

一、有没有可能是镜像拉取失败,开始找问题:

  1. 登录集群所有服务器查看空间是否占满(然而并没有占满)
  2. 查询集群所有服务器网络情况(也没有问题)
  3. 再启一个pod试试?(起不来)

这就尴尬了......,有没有可能是calico的问题?

二、查看服务器报错信息

尝试以下命令看服务器的报错信息:

$ journalctl -exf 

确实有一些错误信息:

这个错误太广泛了,继续尝试从其他地方找找问题。

此时已经开始在思考如何跑路的问题了...

要不尝试从重启能否解决?

风险太大,不能冒险。虽然很多时候重启能解决大部分问题,但重启docker、k8s在这种情况下不是最佳选择。

继续搜刮日志,猜测是无法分配IP的问题,那目标转向calico

从calico-node上面找问题

查询ip池是否用完。

使用calicoamd命令查询calico是否正常正常运行

$ calicoctl get ippools -o wide
CIDR            NAT    IPIP
172.20.0.0/16   true   false

$ calicoctl node status

似乎是没啥问题。

开始场外求助......

无果

既然calico-node都运行正常,应该不会是calico-etcd的问题吧。

试试calico-etcd

本着有疑问就查证试试的态度,下面开始对calico-etcd进行一顿骚操作。

为了减少代码量方便阅读,以下etcdctl所需要加的证书及endpoints,就不一一添加了,大家参考一下就好:

ETCDCTL_API=3 etcdctl --cacert=/etc/etcd/ssl/ca.pem \
--cert=/etc/etcd/ssl/etcd.pem \ 
--key=/etc/etcd/ssl/etcd-key.pem \  
--endpoints=http://10.xx.xx.1:2379,http://10.xx.xx.2:2379,http://10.xx.xx.3:2379

calico并没有问题,试试calico 所使用的 ETCD是否正常,进入calico-etcd集群:

$ ETCDCTL_API=3 etcdctl member list
bde98346d77cfa1: name=node-1 peerURLs=http://10.xx.xx.1:2380 clientURLs=http://10.xx.xx.1:2379 isLeader=true
299fcfbf514069ed: name=node-2 peerURLs=http://10.xx.xx.2:2380 clientURLs=http://10.xx.xx.2:2379 isLeader=false
954e5cdb2d25c491: name=node-3 peerURLs=http://10.xx.xx.3:2380 clientURLs=http://10.xx.xx.3:2379 isLeader=false

似乎集群也运行正常,get数据也正常。

一切看起来都感觉是多么的正常,似乎没有什么毛病。

算了,算了,还是先写会简历吧,换换脑子。

那尝试向ETCD写入一条数据试试?

$ ETCDCTL_API=3 etcdctl put /hello world

Error:  etcdserver: mvcc: database space exceeded

报了一个错Error: etcdserver: mvcc: database space exceeded???

似乎是找到原因了,既然定位到问题所在,那接下来就好办了。(不用跑路了(⁎⁍̴̛ᴗ⁍̴̛⁎))把简历先放一放。

感谢伟大的google,我从etcd官网找到了一些线索及解决方案,后面我贴上官网介绍,先解决问题:

使用etcdctl endpoint status查询etcd各个节点的使用状态:

$ ETCDCTL_API=3 etcdctl endpoint status
http://10.xx.xx.1:2379, 299fcfbf514069ed, 3.2.18, 2.1 GB, false, 7, 8701663
http://10.xx.xx.2:2379, bde98346d77cfa1, 3.2.18, 2.1 GB, true, 7, 8701683
http://10.xx.xx.3:2379, 954e5cdb2d25c491, 3.2.18, 2.1 GB, false, 7, 8701687

上面可以看到集群空间已经使用了2.1GB了,这个值需要留意一下。

查询etcd是否有告警信息使用命令etcdctl alarm list:

$ ETCDCTL_API=3 etcdctl alarm list
memberID:2999344297460918765 alarm:NOSPACE

显示了一个alerm:NOSPACE,这个表示没空间了,那是没什么空间呢?磁盘还是内存?先查询一下。

似乎磁盘、内存空间都足够的。从官网的信息了解到应该是etcd配额的问题,Etcd v3 的默认的 backend quota 2GB,也就是说etcd默认最大的配额是2GB,如果超过了则无法再写入数据,要么把旧数据删除,要么把数据压缩了。

参考官方的解决方案

ETCD官网参考:https://etcd.io/docs/v3.2.17/op-guide/maintenance/

  1. 获取etcd的旧版本号

    $ ETCDCTL_API=3 etcdctl endpoint status --write-out="json" | egrep -o '"revision":[0-9]*' | egrep -o '[0-9].*'
    5395771
    5395771
    5395771
  2. 压缩旧版本

    $ ETCDCTL_API=3 etcdctl compact 5395771
    compacted revision 5395771
  3. 整理碎片

    $ ETCDCTL_API=3 etcdctl defrag
    Finished defragmenting etcd member[http://10.xx.xx.1:2379]
    Finished defragmenting etcd member[http://10.xx.xx.2:2379]
    Finished defragmenting etcd member[http://10.xx.xx.3:2379]
  4. 关闭告警

    $ ETCDCTL_API=3 etcdctl alarm disarm
    memberID:2999344297460918765 alarm:NOSPACE
    
    $ ETCDCTL_API=3 etcdctl alarm list
  5. 测试数据是否可写入

    $ ETCDCTL_API=3 etcdctl put /hello world
    OK
    
    $ ETCDCTL_API=3 etcdctl get /hello
    OK

回到k8s这边,删除那个失败的pod,并查看是否可正常分配ip。

一切正确,完美。

为了避免后续再出现类似问题,需要设置自动压缩,启动自动压缩功能需要在etcd启动参考上加上xxxxx=1

https://skyao.gitbooks.io/learning-etcd3/content/documentation/op-guide/maintenance.html

etcd 默认不会自动 compact,需要设置启动参数,或者通过命令进行compact,如果变更频繁建议设置,否则会导致空间和内存的浪费以及错误。Etcd v3 的默认的 backend quota 2GB,如果不 compact,boltdb 文件大小超过这个限制后,就会报错:”Error: etcdserver: mvcc: database space exceeded”,导致数据无法写入。

产生这么多垃圾数据的原因就是因为频繁的调度,我们集群有大量CronJob在执行,并且执行的非常活跃,每次产生新的Pod都会被分配到ip。有可能是因为pod时间太短或没有及时注销而导致calico-etcd产生了大量垃圾数据。

尾巴

因calico-etcd集群的的使用配额满了,在创建pod时calico所分配的IP无法写入到etcd里,从而导致pod创建失败也就无法注册到CoreDNS了。

为了不采坑,监控是非常重要的,我们有etcd集群的监控,却忽略了etcd配额的监控,幸运的是当时并没有应用重启动或升级,没有造成损失。

最后的建议就是,没事上去点点,说不定会有您意想不到的惊喜(惊吓)。

 作者:宜信技术学院 王聪

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
1月前
|
Kubernetes 应用服务中间件 nginx
搭建Kubernetes v1.31.1服务器集群,采用Calico网络技术
在阿里云服务器上部署k8s集群,一、3台k8s服务器,1个Master节点,2个工作节点,采用Calico网络技术。二、部署nginx服务到k8s集群,并验证nginx服务运行状态。
535 1
|
3月前
|
Kubernetes 虚拟化 网络架构
在K8S中,flannel和calico的区别?
在K8S中,flannel和calico的区别?
|
3月前
|
边缘计算 人工智能 Kubernetes
边缘计算问题之理解 Kubernetes 节点资源的四层分配结构如何解决
边缘计算问题之理解 Kubernetes 节点资源的四层分配结构如何解决
32 1
|
3月前
|
存储 Kubernetes API
在K8S中,calico有哪些组件?都是做什么的?
在K8S中,calico有哪些组件?都是做什么的?
|
3月前
|
Kubernetes 安全 Linux
在K8S中,calico和cilium这两种cni有什么区别?cailico的ipip模型和ciliume的vxlan模型,两种不通模型性能也不同,它们怎么处理数据的?
在K8S中,calico和cilium这两种cni有什么区别?cailico的ipip模型和ciliume的vxlan模型,两种不通模型性能也不同,它们怎么处理数据的?
|
3月前
|
Kubernetes 数据中心 网络架构
在k8S中,flannel和calico的作用和区别是什么?
在k8S中,flannel和calico的作用和区别是什么?
|
3月前
|
Kubernetes 安全 Linux
在k8S中,Calico网络组件实现原理是什么?
在k8S中,Calico网络组件实现原理是什么?
|
3月前
|
存储 Kubernetes API
在K8S中,calico工作原理与网络模式是什么?
在K8S中,calico工作原理与网络模式是什么?
|
3月前
|
存储 Kubernetes 监控
在K8S中,calico有哪些组件?
在K8S中,calico有哪些组件?
|
5月前
|
Kubernetes 网络协议 Cloud Native
Kubernetes网络问题排查分享两则(1)——calico特定场景下的网络性能问题
在对Kubernetes项目[kosmos](https://github.com/kosmos-io/kosmos)与Calico网络性能进行对比测试时,发现kosmos在跨集群容器网络的性能显著优于Calico的集群内网络(约6Gbit/s对比2.9Gbit/s)。物理机网络测试达到9.38Gbit/s,显示Calico有68%的性能损耗。问题定位到网卡的checksum/offload参数,尝试用`ethtool`调整后虽短暂提升,但随后恢复原状。转载自:https://mp.weixin.qq.com/s/XsQZCSqZAXJK46zqc7IpLw
下一篇
无影云桌面