如何配置Kubernetes startupProbe且不阻塞集群组建入站流量?
解决Kubernetes中Apache Ignite集群启动探针死锁问题
问题根源在于:Kubernetes的startupProbe未通过时,Pod不会被纳入Service的端点列表,导致Ignite节点无法与集群内其他节点通信,自然无法加入基线拓扑,形成"探针等节点入基线,节点等网络权限"的死锁。以下是几种可行的解决思路:
方案1:拆分探针职责,分离节点启动与基线就绪
将startupProbe仅用于确认Ignite节点自身已启动并能对外通信,把基线拓扑检查放到readinessProbe中。这样startupProbe通过后,Pod即可被Service识别,节点能和集群其他节点通信完成基线加入,之后readinessProbe通过,Pod进入完全就绪状态。
修改后的启动探针脚本(check_node_started.sh)
#!/bin/bash apk add --no-cache curl jq NODE_HOSTNAME=$(hostname) # 仅检查Ignite REST API可用且能获取当前节点ID NODE_ID=$(curl -s "http://localhost:8080/ignite?cmd=top" | \ jq -r --arg node_hostname "$NODE_HOSTNAME" '.response[] | select(.tcpHostNames[] | startswith($node_hostname)) | .consistentId') if [ -z "$NODE_ID" ]; then echo "Ignite node not started yet." exit 1 else echo "Ignite node started, node ID: $NODE_ID" exit 0 fi
对应的Kubernetes探针配置
startupProbe: exec: command: - /bin/sh - -c - /scripts/check_node_started.sh initialDelaySeconds: 10 periodSeconds: 5 failureThreshold: 12 # 最多等待60秒节点启动 readinessProbe: exec: command: - /bin/sh - -c - /scripts/check_baseline.sh # 复用你原有的基线检查脚本 initialDelaySeconds: 20 periodSeconds: 10 failureThreshold: 30 # 给足够时间让节点加入基线
方案2:启用Ignite自动基线激活
在Ignite配置中开启自动基线激活,当集群节点数达到预设的最小数量时自动激活基线,节点加入后会自动被纳入基线拓扑,减少手动检查的依赖。
Ignite配置示例
在Ignite的XML配置文件中添加:
<property name="autoActivate" value="true"/> <!-- 可选:设置自动激活所需的最小节点数 --> <property name="minNumberNodesForAutoActivation" value="3"/>
或者通过启动参数传递:
ignite.sh -J-DIGNITE_AUTO_ACTIVATE=true -J-DIGNITE_MIN_NODES_FOR_AUTO_ACTIVATION=3
方案3:调整基线检查逻辑,允许节点临时通过启动探针
修改原脚本,在节点启动初期(前N次检查)仅验证节点自身状态,之后再检查基线,让节点先获得网络访问权限,再等待加入基线。
修改后的检查脚本
#!/bin/bash apk add --no-cache curl jq NODE_HOSTNAME=$(hostname) CHECK_COUNT_FILE="/tmp/baseline_check_count" # 初始化检查计数 if [ ! -f "$CHECK_COUNT_FILE" ]; then echo 0 > "$CHECK_COUNT_FILE" fi CHECK_COUNT=$(cat "$CHECK_COUNT_FILE") # 前10次检查仅验证节点是否启动 if [ "$CHECK_COUNT" -lt 10 ]; then NODE_ID=$(curl -s "http://localhost:8080/ignite?cmd=top" | \ jq -r --arg node_hostname "$NODE_HOSTNAME" '.response[] | select(.tcpHostNames[] | startswith($node_hostname)) | .consistentId') if [ -z "$NODE_ID" ]; then echo "Ignite node not started yet. Check count: $CHECK_COUNT" exit 1 else echo "Ignite node started, waiting to join baseline. Check count: $CHECK_COUNT" echo $((CHECK_COUNT + 1)) > "$CHECK_COUNT_FILE" exit 0 fi fi # 10次后检查基线状态 NODE_ID=$(curl -s "http://localhost:8080/ignite?cmd=top" | \ jq -r --arg node_hostname "$NODE_HOSTNAME" '.response[] | select(.tcpHostNames[] | startswith($node_hostname)) | .consistentId') BASELINE=$(curl -s "http://localhost:8080/ignite?cmd=baseline" | \ jq -r --arg node_id "$NODE_ID" '.response.baseline[] | select(. == $node_id)') if [ -z "$BASELINE" ]; then echo "Node is NOT part of the baseline topology yet." exit 1 else echo "Node is part of the baseline topology." exit 0 fi
内容的提问来源于stack exchange,提问作者Алексей
相关产品推荐
相关产品推荐

