Bootstrap

16 K8S之容器健康监测

监测容器自身运行的API包括分别用于健康状态检测、指标、分布式跟踪和日志等实现类型。即便没有完全实现,至少容器化应用也应该提供用于健康状态检测(liveness和readiness)的API,以便编排系统能更准确地判定应用程序的运行状态。

存活状态检测用于判定容器是否处于“运行”状态;若此类检测未通过,kubelet将杀死容器并根据其restartPolicy决定是否将其重启;未定义存活性检测的容器的默认状态为Success。

就绪状态检测:用于判断容器是否准备就绪并可对外提供服务;未通过该检测时,端点控制器(例如Service对象)会将其IP地址从所有匹配到此Pod对象的Service对象的端点列表中移除;检测通过之后,会再次将其IP添加至端点列表中;未定义就绪状态检测的容器的默认状态为Success。

kubelet可在活动容器上分别执行由用户定义的启动状态检测(startupProbe)、存活状态检测(livenessProbe)和就绪状态检测(readinessProbe),定义在容器上的存活状态和就绪状态操作称为检测探针,它要通过容器的句柄(handler)进行定义。

ExecAction:通过在容器中执行一个命令并根据其返回的状态码进行的诊断操作称为Exec探测,状态码为0表示成功,否则即为不健康状态。

TCPSocketAction:通过与容器的某TCP端口尝试建立连接进行诊断,端口能够成功打开即为正常状态,否则为不健康状态。

HTTPGetAction:通过向容器IP地址的某指定端口的指定path发起http GET请求进行诊断,响应码为2xx或3xx即为成功,否则为失败。

一个容器之上仅能定义一种类型的探针,即exec、httpGet和tcpSocket三者互斥,它们不可在一个容器同时使用。

initialDelaySeconds 首次发出存活探测请求的延迟时长,即容器启动多久之后开始第一次探测操作,显示为delay属性;默认为0秒,即容器启动后便立刻进行探测;该参数值应该大于容器的最大初始化时长,以避免程序永远无法启动。

timeoutSeconds 存活探测的超时时长,显示为timeout属性,默认为1秒,最小值也为1秒;应该为此参数设置一个合理值,以避免因应用负载较大时的响应延迟导致Pod被重启。

periodSeconds 存活探测的频度,显示为period属性,默认为10秒,最小值为1秒;需要注意的是,过高的频率会给Pod对象带来较大的额外开销,而过低的频率又会使得对错误反应不及时。

successThreshold 处于失败状态时,探测操作至少连续多少次的成功才被认为通过检测,显示为#success属性,仅可取值为1。

failureThreshold处于成功状态时,探测操作至少连续多少次的失败才被视为检测不通过,显示为#failure属性,默认值为3,最小值为1;尽量设置宽容一些的失败计数,能有效避免一些场景中的服务级联失败。

HTTP探针这种检测方式仅对分层架构中的当前一层有效,例如,它能检测应用程序工作正常与否的状态,但重启操作却无法解决其后端服务(例如数据库或缓存服务)导致的故障。此时,容器可能会被反复重启,直到后端服务恢复正常。其他两种检测方式也存在类似的问题。

restartPolicy适用于Pod对象中的所有容器,而且它仅用于控制在同一个节点上重新启动Pod对象的相关容器。首次需要重启的容器,其重启操作会立即进行,而再次重启操作将由kubelet延迟一段时间后进行,反复的重启操作的延迟时长依次为10秒、20秒、40秒、80秒、160秒和300秒,300秒是最大延迟时长

就绪探针也支持Exec、HTTP GET和TCP Socket这3种探测方式,且它们各自的定义机制与存活探针相同。因而,将容器定义中的livenessProbe字段名替换为readinessProbe,并略做适应性修改即可定义出就绪性检测的配置来,甚至有些场景中的就绪探针与存活探针的配置可以完全相同。