4

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

 1 year ago
source link: https://blog.51cto.com/u_11555417/5507574
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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

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

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

类似于这样:

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK