k8s常见报错以及解决方法(一)

现阶段我们使用k8s集群越来越多,随之而来的是一系列的问题,接下来我向大家来介绍一下我遇到的一些问题以及解决方法

一.报错cannot allocate memory或者no space left on device,修复K8S内存泄露问题

问题描述

一.当k8s集群运行日久以后,有的node无法再新建pod,并且出现如下错误,当重启服务器之后,才可以恢复正常使用。查看pod状态的时候会出现以下报错

applying cgroup … caused: mkdir …no space left on device
或者在describe pod的时候出现cannot allocate memory

这时候你的k8s集群可能就存在内存泄露的问题了,当创建的pod越多的时候内存会泄露的越多,越快.

二.具体查看是否存在内存泄露

cat /sys/fs/cgroup/memory/kubepods/memory.kmem.slabinfo
当出现cat: /sys/fs/cgroup/memory/kubepods/memory.kmem.slabinfo: Input/output error则说明不存在内存泄露的情况
如果存在内存泄露会出现
slabinfo - version: 2.1
# name            <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>

解决方案

一.解决方法思路:关闭runc和kubelet的kmem,因为升级内核的方案改动较大,此处不采用.

二.kmem导致内存泄露的原因:

内核对于每个cgroup子系统的的条目数是有限制的,限制的大小定义在kernel/cgroup.c #L139,当正常在cgroup创建一个group的目录时,条目数就加1 .我们遇到的情况就是因为开启了kmem accounting功能,虽然cgroup的目录删除了,但是条目没有回收。这样后面就无法创建65535个cgroup了。也就是说,在当前内核版本下,开启了kmem accounting功能,会导致memory cgroup的条目泄漏无法回收。

具体实现

一.需要重新编译runc

  1. 配置go语言环境
wget https://dl.google.com/go/go1.12.9.linux-amd64.tar.gz
tar xf go1.12.9.linux-amd64.tar.gz -C /usr/local/写入bashrc
vim ~/.bashrc
export GOPATH="/data/Documents"
export GOROOT="/usr/local/go"
export PATH="$GOROOT/bin:$GOPATH/bin:$PATH"
export GO111MODULE=off验证
source ~/.bashrc
go env
  1. 下载runc源码
mkdir -p /data/Documents/src/github.com/opencontainers/
cd /data/Documents/src/github.com/opencontainers/
git clone https://github.com/opencontainers/runc
cd runc/
git checkout v1.0.0-rc9  # 切到v1.0.0-rc9 tag
  1. 编译
安装编译组件
sudo yum install libseccomp-devel
make BUILDTAGS='seccomp nokmem'
编译完成之后会在当前目录下看到一个runc的可执行文件,等kubelet编译完成之后会将其替换

二.编译kubelet

  1. 下载kubernetes源码
mkdir -p /root/k8s/
cd /root/k8s/
git clone https://github.com/kubernetes/kubernetes
cd kubernetes/
git checkout v1.15.3
  1. 制作编译环境的镜像(Dockerfile如下)
FROM centos:centos7.3.1611ENV GOROOT /usr/local/go
ENV GOPATH /usr/local/gopath
ENV PATH /usr/local/go/bin:$PATHRUN yum install rpm-build which where rsync gcc gcc-c++ automake autoconf libtool make -y \&& curl -L https://studygolang.com/dl/golang/go1.12.9.linux-amd64.tar.gz | tar zxvf - -C /usr/local
  1. 在制作好的go环境镜像中来进行编译kubelet
docker run  -it --rm   -v /root/k8s/kubernetes:/usr/local/gopath/src/k8s.io/kubernetes   build-k8s:centos-7.3-go-1.12.9-k8s-1.15.3   bash
cd /usr/local/gopath/src/k8s.io/kubernetes
#编译
GO111MODULE=off KUBE_GIT_TREE_STATE=clean KUBE_GIT_VERSION=v1.15.3 make kubelet GOFLAGS="-tags=nokmem"

三.替换原有的runc和kubelet

  1. 将原有runc和kubelet备份
mv /usr/bin/kubelet /home/kubelet
mv /usr/bin/docker-runc /home/docker-runc
  1. 停止docker和kubelet
systemctl stop docker
systemctl stop kubelet
  1. 将编译好的runc和kubelet进行替换
cp kubelet /usr/bin/kubelet
cp kubelet /usr/local/bin/kubelet
cp runc /usr/bin/docker-runc
  1. 检查kmem是否关闭前需要将此节点的pod杀掉重启或者重启服务器,当结果为0时成功
cat /sys/fs/cgroup/memory/kubepods/burstable/memory.kmem.usage_in_bytes
  1. 是否还存在内存泄露的情况
cat /sys/fs/cgroup/memory/kubepods/memory.kmem.slabinfo

二.k8s证书过期问题的两种处理方法

前情提要

​ 公司测试环境的k8s集群使用已经很长时间了,突然有一天开发联系我说k8s集群无法访问了,我开始以为是测试环境的机器磁盘空间不够了,导致组件异常或者把开发使用的镜像自动清理掉了,但是当我登上机器去查验的时候发现不是这个原因.当时觉得也很疑惑,因为开发环境没几个人在用,咋还会有问题呢,所以就去查验log的相关报错信息.

问题现象

​ 出现k8s api无法调取的现象,使用kubectl命令获取资源均返回如下报错:

Unable to connect to the server: x509: certificate has expired or is not yet valid

经网上搜索之后发现应该是k8s集群的证书过期了,使用命令排查证书的过期时间

kubeadm alpha certs check-expiration

发现确实是证书过期了

相关介绍以及问题解决

​ 因为我们是使用kubeadm部署的k8s集群,所以更新起证书来也是比较方便的,默认的证书时间有效期是一年,我们集群的k8s版本是1.15.3版本是可以使用以下命令来更新证书的,但是一年之后还是会到期,这样就很麻烦,所以我们需要了解一下k8s的证书,然后我们来生成一个时间很长的证书,这样我们就可以不用去总更新证书了.

kubeadm alpha certs renew all --config=kubeadm.yamlsystemctl restart kubeletkubeadm init phase kubeconfig all --config kubeadm.yaml然后将生成的配置文件替换,重启 kube-apiserver、kube-controller、kube-scheduler、etcd 这4个容器即可

另外 kubeadm 会在控制面板升级的时候自动更新所有证书,所以使用 kubeadm 搭建得集群最佳的做法是经常升级集群,这样可以确保你的集群保持最新状态并保持合理的安全性。但是对于实际的生产环境我们可能并不会去频繁得升级集群,所以这个时候我们就需要去手动更新证书。

下面我们通过调用k8s的api来实现更新一个10年的证书

首先在/etc/kubernetes/manifests/kube-controller-manager.yaml文件加入配置
spec:containers:- command:- kube-controller-manager# 设置证书有效期为 10年- --experimental-cluster-signing-duration=87600h - --client-ca-file=/etc/kubernetes/pki/ca.crt

修改完成后 kube-controller-manager 会自动重启生效。然后我们需要使用下面的命令为 Kubernetes 证书 API 创建一个证书签名请求。如果您设置例如 cert-manager 等外部签名者,则会自动批准证书签名请求(CSRs)。否者,您必须使用 kubectl certificate 命令手动批准证书。以下 kubeadm 命令输出要批准的证书名称,然后等待批准发生:

kubeadm alpha certs renew all --use-api --config kubeadm.yaml &

需要将全部pending的证书全部批准

我们还不能直接重启控制面板的几个组件,这是因为使用 kubeadm 安装的集群对应的 etcd 默认是使用的 /etc/kubernetes/pki/etcd/ca.crt 这个证书进行前面的,而上面我们用命令 kubectl certificate approve 批准过后的证书是使用的默认的 /etc/kubernetes/pki/ca.crt 证书进行签发的,所以我们需要替换 etcd 中的 ca 机构证书:

# 先拷贝静态 Pod 资源清单cp -r /etc/kubernetes/manifests/ /etc/kubernetes/manifests.bakvi /etc/kubernetes/manifests/etcd.yaml
......
spec:containers:- command:- etcd# 修改为 CA 文件- --peer-trusted-ca-file=/etc/kubernetes/pki/ca.crt- --trusted-ca-file=/etc/kubernetes/pki/ca.crt
......volumeMounts:- mountPath: /var/lib/etcdname: etcd-data- mountPath: /etc/kubernetes/pki  # 更改证书目录name: etcd-certsvolumes:- hostPath:path: /etc/kubernetes/pki  # 将 pki 目录挂载到 etcd 中去type: DirectoryOrCreatename: etcd-certs- hostPath:path: /var/lib/etcd type: DirectoryOrCreatename: etcd-data
......

由于 kube-apiserver 要连接 etcd 集群,所以也需要重新修改对应的 etcd ca 文件:

 vi /etc/kubernetes/manifests/kube-apiserver.yaml
......
spec:containers:- command:- kube-apiserver# 将etcd ca文件修改为默认的ca.crt文件- --etcd-cafile=/etc/kubernetes/pki/ca.crt
......

除此之外还需要替换 requestheader-client-ca-file 文件,默认是 /etc/kubernetes/pki/front-proxy-ca.crt 文件,现在也需要替换成默认的 CA 文件,否则使用聚合 API,比如安装了 metrics-server 后执行 kubectl top 命令就会报错:

 cp /etc/kubernetes/pki/ca.crt /etc/kubernetes/pki/front-proxy-ca.crtcp /etc/kubernetes/pki/ca.key /etc/kubernetes/pki/front-proxy-ca.key

这样我们就得到了一个10年证书的k8s集群,还可以通过重新编译kubeadm来实现一个10年证书的,这个我没有尝试,不过在初始化集群的时候也是一个方法.

k8s常见报错以及解决方法(一)相关推荐

  1. kubeadm常见报错和解决方法

    kubeadm常见报错和解决方法 参考文章: (1)kubeadm常见报错和解决方法 (2)https://www.cnblogs.com/only-me/p/10219903.html 备忘一下.

  2. Git常见报错及解决方法

    git常见报错解决方法 1.warning: LF will be replaced by CRLF in .idea/workspace.xml. git config --global core. ...

  3. 【全网最详细yolov6】yoloV6调试记录(含训练自己的数据集及常见报错及解决方法)--持续更新ing

    本文手把手教你如何调试最新的yolov6,复现运行COCO2017及训练自己的数据集,目前该项目刚发布,BUG会比较多,调起来一般不会那么顺利,本文含windows+ubuntu,并给出了一些常见问题 ...

  4. Weblogic常见报错以及解决方法[转载]

    最近组织内部进行安全升级,由于目前所接触的项目均使用weblogic中间件部署,出现了一系列问题小问题,再此转载一下常见的错误处理方式以便后续查询.转载 追风若水:https://my.oschina ...

  5. python+appium,常见报错与解决方法

    分享自己用python+appium写移动端自动化脚本出现的报错及解决方法,持续更新,希望对和我一样刚开始学习的同学有所帮助,加油ヾ(◍°∇°◍)ノ゙ 报错一: 关键字:Could not find ...

  6. maven jar包冲突常见报错及解决方法

    见到如下错误,可以想到是不是jar包冲突 1.java.lang.NoSuchMethodError 2.java.lang.ClassNotFoundException 3.java.lang.No ...

  7. ueditor百度编辑器常见报错的解决方法

    如果是第一次使用ueditor百度编辑器,或者对它不熟悉的情况下使用,会出现一些常见问题和报错.怎么使用建议参考ueditor官网,这里只谈一些常见错误. 问题:'UE' is not defind ...

  8. oracle常见报错及解决方法

    ORA-12514 : TNS: 无法解析指定的连接标识符 在程序中连接Oracle数据库的方式与其他常用数据库,如:MySql,Sql Server不同,这些数据库可以通过直接指定IP的方式连接,但 ...

  9. Keysight ADS常见报错及解决方法总结-1

    1. No source was found. Place one from the component palette, wire it up, and resimulate(F7) 故障原因: 扫 ...

最新文章

  1. Citrix Synergy 2014 重要信息快速一览
  2. go监听mysql事件更新,有没有一种方法可以“监听”数据库事件并实时更新页面?...
  3. mysql xml生成工具_自动生成po、dao、xml 工具:mybatis-generator
  4. 分布式RPC框架性能大比拼 dubbo、motan、rpcx、gRPC、thrift的性能比较
  5. 未来的数据中心(二)
  6. DataScience:风控场景之金融评分卡模型的构建(逻辑回归)开发(转评分卡)、使用过程(线上实现)之详细攻略
  7. raid5和raid6对比
  8. matlab中如何添加注释
  9. DeepMind开源面向对象的机器学习库Sonnet,请与TF配合服用
  10. JSON数据格式---JSON语法规则、JSON文件
  11. Intellij Idea打包jar
  12. lpush和rpush的区别_Redis系列(七):数据结构List双向链表中LPUSH、LPOP、RPUSH、RPOP、LLEN命令...
  13. js表单提交 php,提交表单:js中form表单是如何提交的
  14. java实现发送匿名邮件,帮帮忙!现在要实现邮件发送(还必须要匿名发送)!该怎么解决...
  15. flutter手写板2.0 橡皮擦
  16. client中周期性边界_周期性边界条件
  17. 北京的电竞学校的要求有哪些?
  18. 2038年问题 linux内核5.6,Linux Kernel 5.6 开发者已率先做好准备 应对 2038 年问题
  19. 卷积神经网络 - 汇聚层
  20. java 撤销恢复按钮_java文本的撤销和恢复

热门文章

  1. win7注册表修改默认浏览器
  2. [心得]被霏凡封的帖子,小红伞,趋势分析,五大杀毒引擎分
  3. include传参并且接参
  4. 中国移动发布5G+视频彩铃数智融媒平台 持续壮大“朋友圈”
  5. VsCode简单使用,配置c/c++编译环境,个人感受
  6. script 中的src
  7. App定时提醒(AlarmManager实现,适配不同版本)
  8. 编程复制文件到system32文件夹中
  9. 没有光驱,你能装系统吗?
  10. 1-1课:又回到最初的起点:软件和程序