-
Nacos健康检查是由什么参数控制的?
-
k8s service健康检查配置是由什么参数控制的?
-
如果k8s deployment滚动更新,在endpoint中会立即把对应需要替换的某一个pod给删除吗?
-
旧版本的 Pod 被标记为 Terminating 的时间点是一个新的pod恰好ready的时候吗?
Tips:文末有思考题
Nacos健康检查
在 Nacos 中,服务实例可能会在某些条件下自动下线(即被标记为不健康,并从可用实例列表中移除)。这种行为通常由以下机制控制:
服务实例自动下线的条件
心跳超时(主要原因)
-
Nacos 客户端需要定期向服务端发送心跳信息,告知其状态为健康。
-
如果在指定时间内(超时时间)未收到心跳,Nacos 服务端会将该实例标记为 不健康,并从负载均衡的候选列表中移除。
实例注销
-
客户端显式调用
deregisterInstance()
方法,主动注销服务实例。 -
应用进程在启动或关闭时也可能触发实例的注册和注销。
服务端检测异常
- 服务端主动健康检查(如 TCP 或 HTTP 探针)失败,实例被标记为不健康。
网络异常
-
客户端与 Nacos 服务端之间的网络连接中断。
-
客户端宕机或网络不通导致心跳发送失败。
相关参数控制服务实例下线
1. 客户端心跳相关参数
这些参数主要配置在客户端( application.yml
或代码中)。
-
nacos.naming.heartbeat.interval
描述:客户端发送心跳的间隔时间。
默认值:5000 毫秒(5秒)。
控制作用:降低心跳间隔可以减少误判实例下线的可能性。
示例配置:
properties
nacos:
naming:
heartbeat:
interval: 3000 # 心跳间隔为 3 秒
nacos.naming.health-check.retry
描述:在实例标记为不健康之前,允许的心跳重试次数。
默认值:3 次。
示例配置:
properties
nacos:
naming:
health-check:
retry: 5 # 尝试重试 5 次
nacos.naming.health-check.timeout
描述:服务端判断实例下线的超时时间。
默认值:15,000 毫秒(15秒)。
示例配置:
properties
nacos:
naming:
health-check:
timeout: 20000 # 超时时间设置为 20 秒
2. 服务端健康检查相关参数
这些参数主要配置在 Nacos 服务端( application.properties
文件)。
server.health-check.task.interval
-
描述:服务端执行健康检查任务的时间间隔。
-
默认值:5000 毫秒(5秒)。
-
示例配置:
bash
server.health-check.task.interval=3000 # 每 3 秒执行一次健康检查任务
server.health-check.timeout-ms
-
描述:服务端允许实例心跳的最大超时时间。
-
默认值:15000 毫秒(15秒)。
-
控制作用:心跳超时后,服务端会将实例标记为不健康。
-
示例配置:
bash
server.health-check.timeout-ms=20000 # 心跳超时设置为 20 秒
server.health-check.retry
-
描述:服务端重试健康检查的次数。
-
默认值:3 次。
-
示例配置:
ruby
server.health-check.retry=5 # 允许 5 次重试
3. 服务实例元数据相关参数
在服务注册时,通过元数据可以设置一些特定健康检查参数。
元数据设置健康检查(例如 HTTP 探针)
-
Nacos 支持在实例元数据中指定健康检查探针。
-
示例:
sql
metadata:
check: "http"
check_url: "http://127.0.0.1:8080/health"
timeout: 5000 # 超时时间 5 秒
ephemeral
参数
-
描述:实例是否为临时实例。
-
临时实例依赖心跳维持状态,超时会自动下线;而非临时实例不会因心跳超时而被移除,需手动注销。
-
配置:
ruby
namingService.registerInstance("service-name", "127.0.0.1", 8080, "DEFAULT", true); // true 表示临时实例
其他注意事项
服务端与客户端时间一致性
-
如果服务端和客户端的系统时间不一致,可能会导致心跳超时误判。
-
确保时间同步(如 NTP 配置正确)。
服务端性能
- 如果 Nacos 服务端负载过高,健康检查任务可能延迟,导致实例被错误标记为不健康。
网络抖动
- 在网络状况较差时,心跳包可能丢失,建议适当增加超时时间和重试次数。
总结
-
自动下线主要由心跳机制控制,客户端与服务端都需要正确配置心跳间隔、超时时间和重试次数。
-
客户端主要通过
heartbeat.interval
和health-check.timeout
控制心跳逻辑。 -
服务端通过
server.health-check.timeout-ms
和相关参数执行健康检查任务。 -
临时实例和非临时实例的健康检查行为不同,需根据场景合理选择。
k8s service健康检查配置是由什么参数控制的?
在 Kubernetes (K8s) 中,Service 的健康检查主要通过 Liveness Probe 、Readiness Probe 和 Startup Probe 来实现。这些探针的配置决定了 Pod 的健康状态,并间接影响 Service 的行为,例如负载均衡和流量分发。
探针的类型和作用
Liveness Probe
-
作用:检测 Pod 是否处于"活着"的状态。
-
不健康时动作:重启容器。
-
适用场景:应用进入死循环、卡死或内部错误时。
Readiness Probe
-
作用:检测 Pod 是否可以接收流量。
-
不健康时动作:从 Service 的负载均衡目标列表中移除。
-
适用场景:应用启动缓慢、依赖外部资源时。
Startup Probe
-
作用:检测应用是否启动完成。
-
不健康时动作:重启容器。
-
适用场景:应用启动时间较长,防止 Liveness Probe 误判。
健康检查的实现方式
健康检查通过以下方式执行,所有探针都支持这些方式:
HTTP GET 请求
-
向指定的 HTTP 端点发送 GET 请求,如果返回的状态码在 200--399 范围内,则为健康。
-
示例配置:
properties
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 3
periodSeconds: 5
TCP Socket
-
尝试连接到容器指定端口,如果能建立连接则认为健康。
-
示例配置:
properties
readinessProbe:
tcpSocket:
port: 3306
initialDelaySeconds: 10
periodSeconds: 5
命令执行(Exec)
-
在容器中运行指定命令,如果返回码为
0
则为健康。 -
示例配置:
properties
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
关键参数
以下参数控制探针行为:
initialDelaySeconds
-
描述:探针在容器启动后等待多少秒才开始探测。
-
适用场景:设置应用初始化所需的时间。
-
默认值:0。
periodSeconds
-
描述:探针的探测频率,单位为秒。
-
默认值:10 秒。
timeoutSeconds
-
描述:探针的超时时间。
-
默认值:1 秒。
successThreshold
-
描述:探针连续成功的次数,表示从不健康到健康的阈值。
-
默认值:
-
Readiness Probe:1。
-
Liveness Probe 和 Startup Probe:无效。
-
failureThreshold
-
描述:探针连续失败的次数,表示从健康到不健康的阈值。
-
默认值:3。
示例完整配置
以下是一个完整的探针配置示例:
properties
apiVersion: v1
kind: Pod
metadata:
name: probe-demo
spec:
containers:
- name: my-app
image: my-app:latest
ports:
- containerPort: 8080
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 1
failureThreshold: 3
readinessProbe:
httpGet:
path: /readyz
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 1
successThreshold: 1
failureThreshold: 3
startupProbe:
httpGet:
path: /startz
port: 8080
initialDelaySeconds: 0
periodSeconds: 10
timeoutSeconds: 1
failureThreshold: 60
Service 与健康检查的关系
-
Liveness Probe 和 Startup Probe 的状态不影响 K8s Service 的流量分发,仅用于控制 Pod 的重启。
-
Readiness Probe 的状态直接影响 Service 的流量分发。
-
当 Readiness Probe 检测为"不健康"时,Pod 将从 Endpoints 中移除,Service 不再向该 Pod 分发流量。
常见问题与优化
探针频率过高:
- 会增加容器和 K8s 控制平面的负载。调整
periodSeconds
和timeoutSeconds
平衡性能与可靠性。
初始延迟不足:
- 如果
initialDelaySeconds
设置过短,探针可能误判启动中的容器为不健康。
网络不稳定:
- 在使用 HTTP GET 或 TCP Socket 时,短暂网络抖动可能导致探针失败,适当提高
failureThreshold
。
通过探针配置,K8s 提供了灵活的健康检查机制,可以结合实际场景优化探针参数和探测方式,实现稳定可靠的服务状态监控。
如果k8s deployment滚动更新,在endpoint中会立即把对应需要替换的某一个pod给删除吗?
在 Kubernetes 中,滚动更新 (Rolling Update)是默认的部署策略,用于逐步替换旧版本的 Pod 为新版本的 Pod。关于是否会立即将需要替换的某一个 Pod 从 Endpoints 中删除,这取决于以下机制:
Endpoints 的处理流程
启动阶段:
-
在滚动更新中,新版本的 Pod 会先启动。
-
Kubernetes 会检测新 Pod 的 Readiness Probe 是否通过。
删除阶段:
-
在旧版本的 Pod 被标记为 Terminating 后,它的 Readiness Probe 会立即失效。
-
Endpoints Controller 会实时更新,移除对应 Pod 的 IP 地址。
-
即,Pod 会立即从 Endpoints 中移除,但实际的 Pod 删除过程可能稍后完成。
滚动更新中的行为
默认行为
-
Kubernetes 遵循"先启动新 Pod,再终止旧 Pod"的逻辑,具体由
maxUnavailable
和maxSurge
参数控制:-
maxUnavailable
:最大允许同时不可用的 Pod 数量。 -
maxSurge
:最大允许超出指定 Pod 副本数的新增 Pod 数量。
-
-
旧 Pod 在 Terminating 阶段会被从 Endpoints 中移除,因此流量不会再分发给该 Pod。
Graceful Termination(优雅终止)
-
Pod 的终止过程遵循 TerminationGracePeriodSeconds 的配置(默认 30 秒)。
-
如果应用需要完成清理任务(如关闭连接或完成当前请求),可以在 Pod 的生命周期回调(如 preStop hook)中实现。
-
即使 Pod 尚未完全删除,只要 Readiness Probe 判定不健康,它的 IP 仍会被移除。
关键参数和行为
以下配置项会影响滚动更新过程中 Pod 在 Endpoints 中的处理方式:
readinessProbe
-
确保旧 Pod 的 Readiness Probe 失效后流量停止分发。
-
配置示例:
properties
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 3
periodSeconds: 5
Deployment 策略中的 maxUnavailable
和 maxSurge
-
maxUnavailable
:定义最多有多少个 Pod 可以同时不可用。 -
maxSurge
:定义最多可以多出多少个新 Pod。 -
配置示例:
properties
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
TerminationGracePeriodSeconds
-
Pod 在被标记为 Terminating 后的优雅终止时间,决定清理任务完成的时间。
-
配置示例:
properties
spec:
terminationGracePeriodSeconds: 30
Service 的 publishNotReadyAddresses
参数
-
默认情况下,未准备好的 Pod 地址(即 Readiness Probe 失败的 Pod)不会加入 Endpoints。
-
如果启用了
publishNotReadyAddresses:true
,即使 Pod 未准备好,仍会暴露在 Endpoints 中。 -
配置示例:
properties
spec:
publishNotReadyAddresses: true
总结
-
在滚动更新过程中,Pod 被替换时,旧 Pod 会立即从 Endpoints 中移除,但实际 Pod 的删除可能会等待优雅终止完成。
-
流量中断的防控:
-
配置合理的 Readiness Probe 和 TerminationGracePeriodSeconds。
-
设置合适的
maxUnavailable
和maxSurge
,保证服务有足够可用的 Pod。调试 Endpoints 的变化:
运行以下命令查看 Service 的 Endpoints:
cs
kubectl get endpoints <service-name> -o yaml
旧版本的 Pod 被标记为 Terminating 的时间点是一个新的pod恰好ready的时候吗?
在 Kubernetes 的滚动更新过程中,旧版本的 Pod 被标记为 Terminating
的时间点 和新 Pod 的状态(特别是 Ready
状态)之间的关系,取决于 Deployment 策略 和 参数配置。
默认情况下的行为
滚动更新的逻辑
-
Kubernetes Deployment 默认使用 RollingUpdate 策略。
-
控制 Pod 替换顺序的关键参数是:
-
maxUnavailable
:允许的最大不可用 Pod 数量。 -
maxSurge
:允许的最大超额新增 Pod 数量。
-
-
具体行为:
-
新 Pod 启动并等待变为
Ready
。 -
确保服务总的可用 Pod 数量不低于
replicas-maxUnavailable
。 -
一旦满足条件,旧 Pod 被标记为
Terminating
,并从 Endpoints 中移除。 -
Kubernetes 会继续这一过程,直到完成所有 Pod 的替换。
是否等待新 Pod 就绪(Ready)
-
默认情况下,滚动更新会等待一个新 Pod
Ready
后才开始终止一个旧 Pod。 -
这是因为
maxUnavailable
参数控制了同时不可用的 Pod 数量,默认为 1。
例外情况
maxUnavailable > 0
-
如果允许一定数量的不可用 Pod,则 Kubernetes 不需要等待新 Pod
Ready
,可能会同时终止旧 Pod 并启动新 Pod。 -
示例配置:
properties
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 2
maxSurge: 1
在这种情况下,旧 Pod 可能会提前进入 Terminating
状态,即便新 Pod 尚未完全 Ready
。
新 Pod 长时间未 Ready
-
如果新 Pod 因配置问题或资源不足而无法变为
Ready
,旧 Pod 的终止可能被延迟。 -
Kubernetes 依赖
ProgressDeadlineSeconds
参数定义超时时间。 -
如果在指定时间内更新未完成,Deployment 将进入失败状态。
-
默认值:600 秒。
-
配置示例:
makefile
spec:
progressDeadlineSeconds: 300 # 5分钟内未完成滚动更新则标记失败
优雅终止时间(Graceful Termination)影响
-
旧 Pod 的
TerminationGracePeriodSeconds
参数也会影响滚动更新的节奏: -
如果设置时间较长(默认 30 秒),即使新 Pod 已
Ready
,旧 Pod 也可能延迟退出。 -
配置示例:
properties
spec:
terminationGracePeriodSeconds: 60
总结:是否等新 Pod Ready
再终止旧 Pod
-
默认情况 :是的 ,滚动更新会等待一个新 Pod 变为
Ready
,再终止一个旧 Pod。 -
特殊情况:
-
如果设置了
maxUnavailable>0
或progressDeadlineSeconds
超时 ,可能会在新 Pod 未完全Ready
的情况下终止旧 Pod。 -
配置了较长的
TerminationGracePeriodSeconds
,可能会让旧 Pod 在新 Pod 已Ready
的情况下仍保持运行一段时间。
如何调试滚动更新状态
查看 Pod 状态
cs
kubectl get pods -w
- 可以实时观察新 Pod 的创建和旧 Pod 的
Terminating
状态变化。
查看 Deployment 策略
cs
kubectl get deployment <deployment-name> -o yaml
- 检查
rollingUpdate
的配置参数。
检查更新进度
xml
kubectl rollout status deployment <deployment-name>
- 查看更新是否卡住或超时。
通过合理配置参数,可以精确控制滚动更新过程,避免新旧 Pod 的流量切换产生中断问题。
思考:为什么流量打到了不健康的pod上?