记录在使用Kubernetes中遇到的各种问题及解决方案, 好记性不如烂笔头
不定期更新
原因: 这是因为[/metrics/resource/v1alpha1]是在v1.14中才新增的特性,而当前kubelet版本为1.13
解决: 升级k8s的版本,这里要注意的是 kubelet的版本不能为api-server的高,所以不能只升级kubelet.
原因: 排查两个方面,是否有psp,第二个是否启用了相关的admission
解决: 在本case中,因安全因素,开启了DenyEscalatingExec 这个admission,从api-server的配置–enable-admission-plugins中上去掉DenyEscalatingExec 即可
参考: https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/
1 |
[discovery] Successfully established connection with API Server "xxx.xxx.xxx.xxx:16443" |
原因: 127.0.0.1:16443是apiserver的VIP,从报错信息来看, 对127.0.0.1:16443的访问被拒绝了, 但是在apiserver本地curl这个地址又是没问题的,还是非常诡异,可以通过以下方式解决了
解决: 请确认好kubeadm join时会访问的两个配置文件中的apiserver地址是否正确
1 |
kubectl -n kube-system get cm kubeadm-config -oyaml |
参考: https://github.com/kubernetes/kubeadm/issues/1596
原因: CRD yaml文件中apiVersion与versions中的版本不对应
参考: https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definition-versioning/
原因: ns处于terminating时hang住了,使用 --grace-period=0 -- force
强制删除也无效
解决:
1 |
# 导出k8s访问密钥 |
解决: 在start docker前先执行 systemctl unmask docker.socket
即可
原因: 这个需要排查prometheus持久化目录中是否存在时间超出设置阈值的时间段的文件,删掉后重启即可
原因: 节点上kubelet的配置路径超过阈值会触发驱逐,默认情况下阈值是85%
解决: 或者清理磁盘释放资源,或者通过可修改kubelet的配置参数 imagefs.available
来提高阈值,然后重启kubelet.
参考: https://cloud.tencent.com/developer/article/1456389
原因: 目地机器的iptables对10250这个端口进行了drop,如下图
1 |
iptables-save -L INPUT –-line-numbers |
解决: 删除对应的规则
1 |
iptables -D INPUT 10 |
原因: 出现这种情况很奇怪,现象显示就是域名无法解析,全格式的域名能够解析是因为在pod的/etc/hosts中有全域名的记录,那么问题就出在于corddns解析上,coredns从日志来看,没有任何报错,但是从pod的状态来看,虽然处于Running状态,但是0/1可以看出coredns并未处于ready状态.
可以查看ep记录,会发现endpoint那一栏是空的,这也就证实了k8s把coredns的状态分为了notready状态,所以ep才没有记录,经过与其它环境比较后发现跟配置有关,最终定位在coredns的配置文件上,在插件上需要加上ready
解决: 在cm的配置上添加read插件,如下图
1 |
# ... 省略 |
关于coredns的ready插件的使用,可以参考 这里
总结起来就是使用ready来表明当前已准备好可以接收请求,从codedns的yaml文件也可以看到有 livenessProbe
原因: 这个跟本地的go环境有关
解决: 在使用kubectl前使用命令 export GODEBUG=x509ignoreCN=0
即可
原因: kube-system是集群中受保护的ns, 被禁止删除,主要是防止误操作,如果需要删除的话,可以使用–force
参考: https://github.com/kubernetes/kubernetes/pull/62167/files
原因: 提示这个错误的原因是资源对象是deployment, 而deployment本就是无状态的, 所以也就没有使用pv这一说法了,可以参考api
参考: deploymentspec-v1-apps
原因: CoreDNS所在的宿主机上 /etc/resolv.conf
中存在有127.0.xx的nameserver,这样会造成解析死循环.
解决: 修改宿主机 /etc/resolv.conf
或者将CoreDNS的configmap中的forward修改为一个可用的地址, 如 8.8.8.8
原因: 集群中存在psp禁止pod直接挂载hostpath.
解决: 通过添加以下的psp规则来允许或者删除存在的psp都可
1 |
apiVersion: extensions/v1beta1 |
原因: 这是由于在deploy中设置了 securityContext: runAsNonRoot: true
, 在这种情况下,当pod启动时,使用的默认用户,比如上面的grafana,k8s无法确定他是不是root用户
解决: 指定 securityContext:runAsUser: 1000`, 随便一个id号即可, 只要不是0(0代表root)
参考: https://stackoverflow.com/questions/51544003/using-runasnonroot-in-kubernetes
原因: /var/lib/kubelet/pod下的数据目录已经损坏.
解决: 删除对应的目录即可
原因: 这种情况下一般都是镜像损坏了
解决: 把相关的镜像删除后重新拉取
原因: 这个报错只是中间过程,真正的原因在于apiserver没有启动成功,导致会一直出现这个错误
解决: 排查kubelet与apiserver的连通是否正常
原因: 在path中没有nvidia-container-runtime-hook这个二进制文件,可能跟本人删除nvidia显卡驱动有关.
解决: nvidia-container-runtime-hook是docker nvidia的runtime文件,重新安装即可.
1 |
# kubectl get ingress |
会发现address中的ip是空的,而查看生产环境时却是有ip列表的.
原因: 这个其实不是一个错误,也不影响使用,原因在于测试环境中是不存在LoadBalance类型的svc, 如果需要address中显示ip的话需要做些额外的设置
解决:
-report-ingress-status
external-status-address: "10.164.15.220"
这样的话,在address中变会显示 10.164.15.220
了
参考:
https://github.com/nginxinc/kubernetes-ingress/issues/587
https://docs.nginx.com/nginx-ingress-controller/configuration/global-configuration/reporting-resources-status/
原因: 这种pod已经被删除了,但是volume还存在于disk中
解决: 删除对应的目录 /var/lib/kubelet/pods/3cd73...
参考: https://github.com/longhorn/longhorn/issues/485
原因: 宿主机上面跑的容器太多,导致pod无法在3m钟内完成生命周期检查
解决: PLEG(Pod Lifecycle Event Generator)用于kublet同步pod生命周期,本想着如果是因为时间短导致的超时,那是不是可以直接调整这个时间呢? 查看kubelet的源码发现不太行,3m时间是写在代码里的因此无法修改,当然修改再编译肯定没问题,但成本太大,所以只得优化容器的调度情况.
参考: https://developers.redhat.com/blog/2019/11/13/pod-lifecycle-event-generator-understanding-the-pleg-is-not-healthy-issue-in-kubernetes/
1 |
unable to fully collect metrics: [unable to fully scrape metrics from source kubelet_summary:k8s-node-49: unable to fetch metrics from Kubelet k8s-node-49 (xxx.xxx.xxx.49): Get http://xxx.xxx.xxx.49:10255/stats/summary?only_cpu_and_memory=true: dial tcp xxx.xxx.xxx.49:10255: connect: connection refused |
原因: 现在的k8s都默认禁用了kubelet的10255端口,出现这个错误是因此在kubelet启动命令中启用了该端口
解决: 将 - --kubelet-port=10255
注释
1 |
unable to fetch metrics from Kubelet k8s-node-234 (k8s-node-234): Get https://k8s-node-234:10250/stats/summary?only_cpu_and_memory=true: dial tcp: lookup k8s-node-234 on 10.96.0.10:53: no such host |
解决: 使用 kubelet-preferred-address-types=InternalIP,Hostname,InternalDNS,ExternalDNS,ExternalIP
参数
参考: https://github.com/kubernetes-sigs/metrics-server/blob/master/README.md
集群中新增了几台机器用于部署clickhouse用于做大数据分析,为了不让这类占用大量资源的Pod影响其它Pod,因此选择给机器打taint的形式控制该类Pod的调度, 创建Pod后发现这些Pod都会出现DNS解析异常,
原因; 要注意容器网络,比如这里使用的是flannel是否容忍了这些机器的taint,不然的话,flannel是无法被调度到这些机器的,因此容器间的通信会出现问题, 可以将类似flannel这些的基础POD容忍所有的NoScheule与NoExecute
解决: flannel的ds yaml中添加以下toleration,这样适用任何的场景
1 |
tolerations: |
原因: Yaml文件中使用了subPath, 但是mountPath指向了一个目录
解决: mountPath需要加上文件名
原因: yum安装的kubelet默认的是cgroupfs,而docker一般默认的是systemd。但是kubernetes安装的时候建议使用systemd, kubelet跟docker的不一致, 要么修改kubelet的启动参数 , 要么修改dokcer启动参数
解决:
docker的启动参数文件为: /etc/docker/daemon.json: "exec-opts": ["native.cgroupdriver=systemd”]
kubelet的启动参数文件为: /var/lib/kubelet/config.yaml: cgroupDriver: systemd
原因: 使用kubeadm reset 重复操作过, reset之后,之前flannel创建的bridge device cni0和网口设备flannel.1依然健在
解决: 添加之前需要清除下网络
1 |
kubeadm reset |
1 |
[preflight] Running pre-flight checks |
原因: kubeadm对资源一定的要求,如果是测试环境无所谓的话,可忽略
解决:
1 |
使用 --ignore-preflight-errors 忽略 |
原因: 还未部署网络插件容器,导致在/etc/cni下还没有文件
解决: 根据实际情况部署网络插件
原因: 从其它机器访问上述这些url确实出现 404
解决: 由于是在RKE上部署k8s, 所以可能会去访问google相关的url, 不影响业务,可以忽略
原因: 在api-server的启动参数enable-admission中设置了PodSecrityPolicy, 但是集群中又没有任何的podsecritypolicy,因此导致整个集群都无法新建出pod
解决: 删除相应的podsecritypolicy即可
原因: kubelet的启动参数少了x509认证方式
解决: 配置证书的路径, 加上重启kubelet即可
原因: 这是个kubectl的bug, 跟版本相关,kubernetes有意废除get cs命令
解决: 目前对集群的运行无影响, 可通过加-oyaml 查看状态
原因: 跟kubeadm没多大关系, 系统安装的有问题
解决: 执行以下命令修复
1 |
apt --fix-broken install |
现象: 从另一环境中把yaml文件导入到新环境后有些service访问不通
1 |
telnet mongodb-mst.external 27017 |
首先排除了域名、端口的配置问题。
会发现提示连接拒绝.可以确定的是集群内的DNS是正常的.
那么就是通过clusterIP无法到达realserver. 查看iptables规则
发现提示 default has no endpoints --reject-with icmp-port-unreachable
很奇怪, 提示没有endpoints, 但是使用 kubectl get ep
又能看到ep存在且配置没有问题
而且这个default是怎么来的.
为了方便部署, 很多配置是从别的环境导出的配置, 有些service访问是没问题的, 只有少部分 connection refused
结比一下发现一个很有趣的问题,先来看下不正常的yaml文件:
由于服务在集群外部署的, 因此这里使用了subset方式, 开始怀疑问题在这里, 但是后来知道这个不是重点
乍一看这个配置没什么问题, 部署也很正常, 但是对比正常的yaml文件,发现一个区别:
如果在services中的端口指定了名字, 那么在subsets中的端口也要带名字, 没有带名字的就会出现 connection refused
,这个确实之前从来没有关注过, 一个端口的情况下也不会指定名字
而且这面iptalbes中提示的default刚好就是这里的port name,虽然不敢相信,但是也只能试一试这个方法: 在subsets中也加了port name
重新部署一个,再次查看iptalbes规则
iptables-save|grep mongodb-mst
OMG, 居然可行, 再看下telnet的结果:
1 |
Trying 10.105.116.92... |
访问也是没问题, 那么原因就在于:
在service中指定了port name时, 也需要在ep中指定port name
今天遇到一个部署deployment出错的问题, yaml文件如下:
1 |
apiVersion: apps/v1 |
提示以下错误:
会提示 Unsupported value:spec.template.metadata.annotations.configHash
目的很简单: container中的环境变量中引用configHash变量, 这个值是当configmap变更时比对两个不同的sha值以此达到重启pod的目的, 但fieldPath显然不支持 spec.template.metadata.annotations.configHash
从报错提示来看, 支持列表有 metadata.name, metadata.namespace, metadata.uid, spec.nodeName,spec.serviceAccountName, status.hostIp, status.PodIP, status.PodIPs
这些值用于容器中需要以下信息时可以不从k8s的apiserver中获取而是可以很方便地从这些变量直接获得
参考:
https://www.magalix.com/blog/kubernetes-patterns-the-reflection-pattern
https://kubernetes.io/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/
- https://www.ibm.com/docs/en/cloud-private/3.2.0?topic=console-namespace-is-stuck-in-terminating-state
- https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definition-versioning/
- https://github.com/kubernetes/kubernetes/issues/19317
- http://www.xuyasong.com/?p=1725
- https://kubernetes.io/
- https://fuckcloudnative.io/
- https://www.cnblogs.com/breezey/p/8810039.html
- https://ieevee.com/tech/2018/04/25/downwardapi.html
- https://www.magalix.com/blog/kubernetes-patterns-the-reflection-pattern
- https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#deploymentspec-v1-apps
- https://kubernetes.io/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/
- https://github.com/kubernetes/kubernetes/pull/62167/files
- https://github.com/kubernetes-sigs/metrics-server/blob/master/README.md
- https://github.com/kubernetes/kubeadm/issues/1596