0
点赞
收藏
分享

微信扫一扫

k8s故障处理-使用kubectl exec无法进入pod

故障现象

在一次运维k8s集群的时候,需要进入pod内部执行命令,kubectl exex <pod_name> -it bash,

出现报错,无法进入容器内部。报错信息如下:

k8s故障处理-使用kubectl exec无法进入pod_github

类似于这样:

kubectl exec -it -n my-ns my-pod sh
error: unable to upgrade connection: error dialing backend: dial tcp 127.0.0.1:37751: connect: connection refused

其他的pod可以正常进入。十分费解。但是可以确认的是,能够进入的pod配置了对应的service包暴露服务,而不能进入的pod配置是nodeport方式暴露.


kubectl exec原理与问题分析

为了解决这个问题,就需要对kubectl exex原理有所了解。

以下是一个大致的kubectl exec请求流程。

k8s故障处理-使用kubectl exec无法进入pod_重启_02

  • 客户端 kubectl exec -i -t ...
  • kube-apiserver 向 Kubelet 发送流式请求 /exec/
  • Kubelet 通过 CRI 接口向 CRI Shim 请求 Exec 的 URL
  • CRI Shim 向 Kubelet 返回 Exec URL
  • Kubelet 向 kube-apiserver 返回重定向的响应
  • kube-apiserver 重定向流式请求到 Exec URL,接着就是 CRI Shim 内部的 Streaming Server 跟 kube-apiserver 进行数据交互,完成 Exec 的请求和响应

查询了网上的资料,说kubelte为了处理attach容器,监听的port,这个port是随机linseten的,因为port随机,极有可能是pod对应的service使用了nodeport随机暴露的端口与容器的streaming server随机端口冲突,因此streaming server端口占用,与kubelete通信异常,无法响应,自然就无法进入 pod了。

在github同样找到了有类似的问题。详细见

​​https://github.com/kubernetes/kubernetes/issues/85418​​

解决办法

1.修改node节点的linux内核,修改net.ipv4.ip_local_port_range参数,因为nodeport端口范围是3000-32767,指定可以使用net.ipv4.ip_local_port_range = 1024 20000(范围需要评估下)来限制kubelet随机端口的使用范围。需要重启kubelet让其重新在这个范围监听端口。需要重启node

  1. 修改nodeport的范围。 Master 节点上会有一个文件 /etc/kubernetes/manifests/kube-apiserver.yaml​,修改此文件,向其中添加 --service-node-port-range=20000-22767 ,避免冲突,需要重启master
  2. 直接修改 pod对应的service的yaml文件指定nodeport端口,避免冲突,如下所示:

k8s故障处理-使用kubectl exec无法进入pod_重定向_03

需要重启service

4 直接修改service的类型,由nodeport改为port,

k8s故障处理-使用kubectl exec无法进入pod_重定向_04

需要重启service

举报

相关推荐

0 条评论