解决pod健康检查问题

引自:Solving the mystery of pods health checks failures in Kubernetes。原文中的某些描述并不清晰,本文作了调整。

很早以前,环境中的pod有时候会遇到健康检查失败的问题,但并没有什么明显表征,且几乎是立马就会恢复。由于这种情况很少发生,且不会对业务造成影响,因此起初并没有人关注该问题。

但后来发生的频率越来越高,导致开发人员频繁接收到deployment的健康告警。

第1步:查看日志

  • Kubernetes worker的系统日志 -- 无异常
  • kubelet 日志 -- 无异常
  • Containerd 日志 -- 无异常
  • CNI 日志 -- 无异常
  • 检查最近失败的pod日志 -- 无异常

通过检查相关日志,并没有发现什么异常

第2步:tcpdump

在抓取的流量中发现,当kubelet给pod发送TCP SYN之后,pod会回复SYN-ACK,但kubelet并没有发送TCP ACK。在一段时间的重试之后,Kubelet会建立起一条TCP会话,因此该问题是随机发生的。

为以防万一,我们检查了TCP中的seq和ack序列号,并没有发现问题。

此时怀疑worker可能存在问题:是不是Kubelet没有处理接收到的报文?

第3步:ss

每秒调用一次"ss -natp"来查看kubelet进程连接,此时发现失败的连接卡在了SYN-SENT阶段,说明kubelet并没有接收到pod发来的SYN-ACK报文。

第4步:conntrack

使用conntrack查看TCP网络连接跟踪,发现有的连接卡在SYN-SENT状态(kubelet侧),有的连接卡在SYN-RECV(pod侧),但连接的源端口号看起来都类似。

在我们的环境中,设定了一个较大的源端口可选范围:

net.ipv4.ip_local_port_range=12000 65001

出现问题的源端口为30XXX或31XXX,非常类似。

第5步:ipvs

通过ipvsadm命令查看ipvs配置发现,所有卡住的连接都使用了Kubernetes的nodeport 保留端口

根因分析

至此,问题已经明了。当Kubelet初始化一条TCP连接时,会随机选择一个源端口号,例如31055。当TCP SYN到达pod之后,pod会向31055端口号回复一个TCP SYN-ACK报文。当该报文到达IPVS之后,由于已经存在一个端口号为31055的nodeport(Kubernetes loadbalance service),此时会将TCP SYN-ACK报文转发到对应的后端(其他pod),这样就导致Kubelet无法接收到回复的报文,无法建立连接。

解决办法

解决方式也很简单,设置如下内核参数即可,这样Kubelet在建立连接时就不会选择30000–32768的端口作为TCP源端口:

net.ipv4.ip_local_reserved_ports="30000–32768"

Kubernetes的nodeport保留端口为30000-32767,因此设置的net.ipv4.ip_local_reserved_ports为30000–32768

TIPs

  • net.ipv4.ip_local_port_range的默认值为32768 60999,正好和Kubernetes的nodeport保留端口错开,本文中描述的问题的源头也是因为修改了该内核参数,因此非必要不要修改内核参数!

解决pod健康检查问题的更多相关文章

  1. kubernetes之pod健康检查

    目录 kubernetes之pod健康检查 1.概述和分类 2.LivenessProbe探针(存活性探测) 3.ReadinessProbe探针(就绪型探测) 4.探针的实现方式 4.1.ExecA ...

  2. 解决Tengine健康检查引起的TIME_WAIT堆积问题

    简介: 解决Tengine健康检查引起的TIME_WAIT堆积问题 一. 问题背景 "服务上云后,我们的TCP端口基本上都处于TIME_WAIT的状态"."这个问题在线下 ...

  3. Kubernetes Pod 健康检查

    参考文档: https://jimmysong.io/kubernetes-handbook/guide/configure-liveness-readiness-probes.html 一.Pod的 ...

  4. pod健康检查(liveness probe存活探针&&readiness probe 可读性探针)

    在Kubernetes集群当中,我们可以通过配置liveness probe(存活探针)和readiness probe(可读性探针)来影响容器的生存周期.参考文档:https://kubernete ...

  5. K8s中Pod健康检查源代码分析

    了解k8s中的Liveness和Readiness Liveness: 表明是否容器正在运行.如果liveness探测为fail,则kubelet会kill掉容器,并且会触发restart设置的策略. ...

  6. Kubernetes中Pod健康检查

    目录 1.何为健康检查 2.探针分类 2.1.LivenessProbe探针(存活性探测) 2.2.ReadinessProbe探针(就绪型探测) 3.探针实现方法 3.1.Container Exe ...

  7. Pod生命周期和健康检查

    Pod生命周期和健康检查 Pod的生命周期涵盖了前面所说的PostStart 和 PreStop在内 Pod phase Pod的status定义在 PodStatus对象中,其中有一个phase字段 ...

  8. Knative Serving 健康检查机制分析

    作者|  阿里云智能事业群技术专家牛秋霖(冬岛) 导读:从头开发一个Serverless引擎并不是一件容易的事情,今天咱们就从Knative的健康检查说起.通过健康检查这一个点来看看Serverles ...

  9. K8s-Pod健康检查原理与实践

    Pod健康检查介绍 默认情况下,kubelet根据容器运行状态作为健康依据,不能监视容器中应用程序状态,例如程序假死.这将会导致无法提供服务,丢失流量.因此重新健康检查机制确保容器健康幸存.Pod通过 ...

  10. k8s入坑之路(14)scheduler调度 kubelet管理及健康检查 更新策略

    kubelet 主要功能 Pod 管理 在 kubernetes 的设计中,最基本的管理单位是 pod,而不是 container.pod 是 kubernetes 在容器上的一层封装,由一组运行在同 ...

随机推荐

  1. decay_rate, decay_steps ,batchsize,iteration,epoch

    (96条消息) decay_rate, decay_steps ,batchsize,iteration,epoch_hellocsz的博客-CSDN博客_decay_steps (1)batchsi ...

  2. 微信小程序分享出去的页面再点进来,如何取值并且在新用户未授权的情况下,授权后跳到当前页面

    1.如何点击分享的页面进来,授权后跳转到当前页面 可以在授权成功后,将openid.头像.昵称入库成功之后,标记一下,及getStorageSync // 通过code获取openid getUser ...

  3. TensorFlow安装填坑之路(Windows环境)

    最近跟着简单粗暴 TensorFlow 2中的教学活动ML Study Jam 2020学习TensorFlow,记录下在Windows环境中安装TensorFlow时遇到的那些坑. TensorFl ...

  4. sql union 和 union all

    UNION 操作符用于合并两个或多个 SELECT 语句的结果集. 但是需要注意: 1.union内部的select语句必须拥有相同数量的列. 2.列必须拥有相似的数据类型. 3.每条select语句 ...

  5. 如何通过C++ 将数据写入 Excel 工作表

    直观的界面.出色的计算功能和图表工具,使Excel成为最流行的个人计算机数据处理软件.在独立的数据包含的信息量太少,而过多的数据又难以理清头绪时,制作成表格是数据管理的最有效手段之一.这样不仅可以方便 ...

  6. Web For Pentester File include

    File include(文件包含) Example 1 没有任何过滤 审计源码 没有对我们传参的page进行任何过滤,payload如下 http://172.16.1.104/fileincl/e ...

  7. 统一观测丨使用 Prometheus 监控 E-MapReduce,我们该关注哪些指标?

    作者:闻洪 开源大数据平台E-MapReduce(简称"EMR")是云原生开源大数据平台,向客户提供简单易集成的Hadoop.Hive.Spark.Flink.Presto.Cli ...

  8. JavaWeb笔记第一弹

    一.MYSQL的安装 1.MYSQL的安装 可以去官网找到与自身计算机向对应的版本进行下载 网址如下: MySQL :: Download MySQL Community Server 2.MYSQL ...

  9. Feign调用报错The bean 'XXX.FeignClientSpecification', defined in null, could not be registered....的解决办法

    问题描述: 创建了两个远程调用类,一个是调用退款的,一个是调用折扣的 但是两个调用类是调用的同一个微服务 都叫@FeignClient(value = "xxx-shop") 如何 ...

  10. 给宝宝的AC自动机启蒙指南(宝宝的第一本)

    AC自动机 根据已有经验,学完虚数会变虚,然后写出的代码就不是人能看的了 所以我们来学实树罢(喜) 以上为废话博客背景 有限状态自动机 首先我们来了解一下自动机是啥. 说的通俗一点,我们可以把自动机看 ...