k8s-故障转移 livenessProbe & readinessProbe 学习总结

文章介绍了K8S中Pod的故障转移机制,包括物理机和程序故障的情况,并详细讲解了Pod的健康检查,如livenessProbe(存活探测)用于判断何时重启容器,以及readinessProbe(就绪探测)用于决定Pod何时能接受请求。这两种探测通过Exec、HTTP和TCP等方式检查容器健康,并有各自的检查周期、延迟和失败阈值。文中还提供了实例来展示如何配置和使用这些探测。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

k8s-故障转移学习总结

大纲

  • 概念
  • K8S中Pod健康检查
  • livenessProbe & readinessProbe
  • livenessProbe 存活探测实例
  • readinessProbe 就绪探测实例

概念

故障转移有哪些情况

  • 物理机故障
  • 程序故障

在计算机术语中,故障转移(英语:failover),即当活动的服务或应用意外终止时,快速启用冗余或备用的服务器、系统、硬件或者网络接替它们工作。

K8S中Pod健康检查

默认情况下,kubelet根据容器运行状态作为健康依据,不能监控容器中应用程序状态!

例如程序假死。这就会导致无法提供服务,丢失流量。因此引入健康检查机制确保容器健康存活。

Pod通过两类探针来检查容器的健康状态

  • LivenessProbe(存活探测)
  • ReadinessProbe(就绪探测)

启动(Startup)探针是另外的一个探测

官方资料: https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/

livenessProbe(存活探测)

kubelet 使用livenessProbe(存活探测)来确定什么时候要重启容器。 例如,存活探针可以探测到应用死锁(应用程序在运行,但是无法继续执行后面的步骤)情况。 重启这种状态下的容器有助于提高应用的可用性,即使其中存在缺陷。

存活探测将通过http、shell命令或者tcp等方式去检测容器中的应用是否健康,然后将检查结果返回给kubelet,
如果检查容器中应用为不健康状态提交给kubelet后,kubelet将根据Pod配置清单中定义的重启策略restartPolicy来对Pod进行重启。

readinessProbe(就绪探测)

kubelet 使用就绪探针可以知道容器何时准备好接受请求流量,当一个 Pod 内的所有容器都就绪时,才能认为该 Pod 就绪。 这种信号的一个用途就是控制哪个 Pod 作为 Service 的后端。 若 Pod 尚未就绪,会被从 Service 的负载均衡器中剔除。

如果容器或则Pod状态为(NoReady)状态,Kubernetes则会把该Pod从Service的后端endpoints Pod中去剔除。

livenessProbe(存活探测),readinessProbe(就绪探测),这两种探测都支持以下方式对容器进行健康检查

  • Exec(执行脚本):在容器中执行命令,命令执行后返回的状态为0则成功,表示我们探测结果正常
  • HTTP:根据容器IP、端口以及路径发送HTTP请求,返回码如果是200-400之间表示成功
  • TCPSocketAction:根据容器IP地址及特定的端口进行TCP检查,端口开放表示成功

以上每种检查动作都可能有以下三种返回状态

  • Success,表示通过了健康检查
  • Failure,表示没有通过健康检查
  • Unknown,表示检查动作失败

livenessProbe(存活探测)

livenessProbe(存活探测) 控制Pod的重启

livenessProbe: 
  # 会访问localhost:5555/health 这个http请求
  httpGet: 
     path: /health
     port: 5555
  initialDelaySeconds: 10 #延迟探测时间
  timeoutSeconds: 1
  periodSeconds: 10 #访问频率单位秒
  failureThreshold: 3 

配置说明

  • periodSeconds 字段指定了 kubelet 应该每几秒执行一次存活探测

  • initialDelaySeconds 字段告诉 kubelet 在执行第一次探测前应该等待 5 秒

  • failureThreshold 针对 HTTP 或 TCP 检测,可以通过将 failureThreshold * periodSeconds 参数设置为足够长的时间来应对启动时间过慢的情况

    例如
    failureThreshold: 3
    periodSeconds:10
    应用程序将会有最多 半分钟(3 * 10 = 30s)的时间来完成其启动过程

注意:使用livenessProbe(存活探测)时要注意程序的启动时间如果启动时间过长会导致健康检查失败 一直重启

可以使用startupProbe(启动探针)保护慢启动容器
startupProbe:
  httpGet:
    path: /health
    port: 5555
  failureThreshold: 30
  periodSeconds: 10

readinessProbe(就绪探测)

readinessProbe(就绪探测) 控制Service是否可以使用Pod

readinessProbe:
  # 会访问localhost:5555/health 这个http请求
  httpGet: 
     path: /startok
     port: 5555
     # 可以自定义请求头
     httpHeaders:
       - name: Custom-Header
         value: Awesome
  initialDelaySeconds: 5 #延迟探测时间
  timeoutSeconds: 1
  periodSeconds: 5 #访问频率
  failureThreshold: 3

livenessProbe 存活探测实例

step1 镜像与配合的代码

调整docker容器JVM堆内存大小,让java.lang.OutOfMemoryError来得快点

在这里插入图片描述

对应的controller代码

//定义一个列表保存数据    
private List<Object> list = new ArrayList<>();

@RequestMapping("/oop")
public boolean oop(){
	System.out.println(list.size());
    new Thread(()->{
    	while(true){
    	   //循环创建一个1M的数组 没有释放 让其触发OutOfMemoryError
    		list.add(new String[1024][1024]);
    		list.add(new String[1024][1024]);
    		list.add(new String[1024][1024]);
    		list.add(new String[1024][1024]);
	    	System.out.println("加数据");
    	}
    }).start();
	return true;
}

//健康检查接口 无法继续创建对象
@RequestMapping("/health")
public String health() {
	Health h = createHealth();
	return h.getStatus();
}

private Health createHealth(){
	Health h = new Health();
	h.setArry(new String[1024][1024]);
	h.setStatus("ok");
	return h;
}
step2 启动pod

http-health-check.yaml 关键配置如下:

 livenessProbe: 
	  # 会访问localhost:5555/health 这个http请求
	  httpGet: 
	     path: /health
	     port: 5555
	  initialDelaySeconds: 10 #延迟探测时间
	  timeoutSeconds: 1
	  periodSeconds: 10 #访问频率
	  failureThreshold: 3      

详情见《/yaml/http-health-check.yaml》

kubectl apply -f http-health-check.yaml 创建Pod

在这里插入图片描述

可以看到 RESTARTS是0 表示还没重启过

在这里插入图片描述

step3 测试故障转移

触发OOM异常

在这里插入图片描述
在这里插入图片描述

此时 springboot已经无法正常使用了

step4 k8s故障转移

k8s会自动的重启 Pod 让服务重新可用

在这里插入图片描述

可以看到Pod RESTARTS是1 表示已经重启过一次

注意: livenessProbe 存活探测只无法处理节点宕机的情况
在这里插入图片描述

readinessProbe就绪探测实例

就绪探测可以测试pod是否可以开始对外提供服务了,Service可以开始使用pod了

step1 代码改造

在这里插入图片描述

step2 启动pod

http-health-check.yaml 关键配置如下:

readinessProbe:
  # 会访问localhost:5555/health 这个http请求
  httpGet: 
     path: /startok
     port: 5555
     # 可以自定义请求头
     httpHeaders:
       - name: Custom-Header
         value: Awesome
  initialDelaySeconds: 5 #延迟探测时间
  timeoutSeconds: 1
  periodSeconds: 5 #访问频率
  failureThreshold: 3   

详情见《/yaml/http-health-check.yaml》

kubectl apply -f http-health-check.yaml 创建Pod

step3 测试就绪探测

Pod成功创建 ,使用Pod ip可以访问程序,但使用service ip 则无法访问

在这里插入图片描述

等待90s后

在这里插入图片描述
成功访问

&lt;think&gt;好的,用户现在问的是Kubernetes如何实现故障转移。之前他们问过拓扑域的自定义,现在可能是在深入集群管理的问题。首先,我需要回忆一下Kubernetes故障转移机制,包括自愈能力、控制器、探针这些基本概念。用户可能对Pod的重启、重新调度、负载均衡这些方面感兴趣,需要分步骤解释清楚。 用户可能是一个刚开始接触K8s的开发者或者运维,他们想了解如何确保应用的高可用性。之前的回答里提到了拓扑域和节点标签,这次的问题更偏向于故障恢复机制。需要明确故障转移的不同层面,比如Pod级别、节点级别、服务级别和存储级别,每个层面都有不同的机制。 要确保回答结构清晰,分点说明每个组件的作用。比如,Pod的重启策略由kubelet处理,而节点故障转移则涉及节点控制器和驱逐策略。服务层面的故障转移需要结合Service和Endpoint,而存储部分则涉及PV和PVC的重新绑定。 另外,用户可能对实际配置操作感兴趣,比如如何设置探针、定义PodDisruptionBudget,或者使用StatefulSet管理有状态应用。需要给出具体的配置示例,这样他们可以跟着操作。同时,注意事项部分要提醒用户一些常见问题,比如探针配置不当可能导致的问题,或者存储卷的注意事项。 要检查是否有遗漏的重要机制,比如HPA虽然不是直接的故障转移,但和整体高可用相关,是否需要提及?可能简要提到,但主要聚焦在故障转移本身。另外,用户可能没有考虑到网络分区的情况,或者存储持久化的挑战,这些在注意事项里可以补充。 最后,总结部分要强调K8s的多层次机制,以及需要用户根据应用需求合理配置,结合之前的拓扑域自定义,可能形成完整的解决方案。确保语言通俗易懂,避免过于技术化的术语,但又要准确无误。&lt;/think&gt;### Kubernetes 故障转移机制详解 Kubernetes 通过**多层次自愈机制**实现故障转移,确保应用在节点故障、Pod 异常等场景下自动恢复。以下是核心实现方式: --- ### 一、Pod 级别的故障转移 #### 1. **容器重启策略(RestartPolicy)** - **作用**:当容器异常退出时自动重启。 - **配置字段**:在 Pod 的 `spec.restartPolicy` 中定义: - `Always`(默认):总是重启 - `OnFailure`:仅在非0退出码时重启 - `Never`:不重启 ```yaml apiVersion: v1 kind: Pod metadata: name: myapp spec: restartPolicy: OnFailure # 自定义重启策略 containers: - name: main image: nginx ``` #### 2. **存活探针(Liveness Probe)** - **作用**:检测容器是否存活,若失败则触发重启。 - **探测方式**:HTTP 请求、TCP 端口检查、执行命令。 ```yaml containers: - name: web livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 15 # 容器启动后15秒开始探测 periodSeconds: 10 # 每10秒探测一次 failureThreshold: 3 # 连续失败3次后重启 ``` --- ### 二、节点级别的故障转移 #### 1. **节点状态监控** - **kubelet 心跳机制**:节点上的 kubelet 定期向控制平面发送心跳信号(默认每10秒一次)。 - **节点控制器(Node Controller)**: - 若节点超过 `--node-monitor-grace-period`(默认40秒)未上报状态,标记为 `NotReady`。 - 持续 `--pod-eviction-timeout`(默认5分钟)后,驱逐节点上的 Pod。 #### 2. **Pod 驱逐与重新调度** - **驱逐策略**:节点故障后,调度器将 Pod 重新分配到健康节点。 - **污点与容忍度(Taints/Tolerations)**: - 节点故障时自动添加 `node.kubernetes.io/unreachable` 污点。 - Pod 若无对应容忍度,会被驱逐。 --- ### 三、服务级别的故障转移 #### 1. **Service 负载均衡** - **Endpoint 动态更新**:Service 通过 Endpoint 对象实时跟踪 Pod IP。 - **故障 Pod 自动剔除**:kube-proxy 根据 Endpoint 变化更新 iptables/IPVS 规则,流量不再路由到异常 Pod。 #### 2. **就绪探针(Readiness Probe)** - **作用**:检测 Pod 是否准备好接收流量,若失败则从 Service 的 Endpoint 中移除。 ```yaml readinessProbe: exec: command: [&quot;/bin/check-service-ready&quot;] initialDelaySeconds: 5 periodSeconds: 5 ``` --- ### 四、有状态应用的故障转移 #### 1. **StatefulSet 控制器** - **有序部署**:按顺序创建/删除 Pod,确保唯一网络标识(如 `web-0`, `web-1`)。 - **持久卷(PersistentVolume)绑定**: - Pod 重新调度时自动绑定原有 PV,防止数据丢失。 ```yaml apiVersion: apps/v1 kind: StatefulSet metadata: name: mysql spec: serviceName: &quot;mysql&quot; replicas: 3 template: spec: volumes: - name: data persistentVolumeClaim: claimName: mysql-pvc ``` #### 2. **Operator 模式** - **自定义控制器**:如 etcd-operator、Prometheus-operator,实现复杂有状态应用的自愈逻辑。 --- ### 五、高级容错机制 #### 1. **PodDisruptionBudget(PDB)** - **作用**:限制维护性操作(如节点排水)导致的同时中断的 Pod 数量。 ```yaml apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: zk-pdb spec: minAvailable: 2 # 至少保持2个Pod可用 selector: matchLabels: app: zookeeper ``` #### 2. **多副本与反亲和性** - **跨节点/区域部署**:通过 `podAntiAffinity` 强制 Pod 分散在不同拓扑域。 ```yaml affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: [&quot;critical-app&quot;] topologyKey: &quot;kubernetes.io/hostname&quot; # 确保每个节点只运行一个实例 ``` --- ### 六、故障转移流程图解 ``` 节点故障检测 │ ▼ 节点标记为 NotReady(Node Controller) │ ▼ Pod 驱逐(kube-controller-manager) │ ▼ Pod 重新调度(kube-scheduler) │ ▼ 新 Pod 绑定原有存储卷(PV/PVC) │ ▼ 服务流量切换至新 Pod(kube-proxy + Endpoint) ``` --- ### 七、注意事项 1. **存储卷持久化**:无状态应用可直接重建,有状态应用需确保 PV 支持 `ReadWriteOnce` 或 `ReadWriteMany`。 2. **探针配置优化**: - 避免过于敏感的存活探针导致频繁重启 - 就绪探针超时时间需大于服务启动时间 3. **集群规模影响**: - 大规模集群中,故障转移可能引发&ldquo;惊群效应&rdquo;(大量 Pod 同时调度) - 可通过 `--large-cluster` 参数调整控制器性能 --- ### 八、总结 Kubernetes 通过以下核心机制实现故障转移: 1. **自愈**:容器重启、探针检测、Pod 驱逐 2. **调度**:自动重新绑定存储、跨节点/区域调度 3. **服务发现**:动态 Endpoint 更新、负载均衡 4. **扩展性**:StatefulSet、Operator 支持复杂场景 实际应用中需结合监控(如 Prometheus)、日志(如 Loki)和告警(如 Alertmanager)构建完整的高可用体系。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寂寞的4角钱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值