我有一个 Redis K8s 部署,链接到一个单独的服务,清单大幅减少,如下(如果需要更多信息,请告诉我):
apiVersion: apps/v1
kind: Deployment
spec:
replicas: 2
selector:
matchLabels:
app: cache
environment: dev
template:
metadata:
labels:
app: cache
environment: dev
spec:
containers:
- name: cache
image: marketplace.gcr.io/google/redis5
imagePullPolicy: IfNotPresent
livenessProbe:
exec:
command:
- redis-cli
- ping
initialDelaySeconds: 30
timeoutSeconds: 5
readinessProbe:
exec:
command:
- redis-cli
- ping
initialDelaySeconds: 30
timeoutSeconds: 5
volumes:
- name: data
nfs:
server: "nfs-server.recs-api.svc.cluster.local"
path: "/data"
Run Code Online (Sandbox Code Playgroud)
我想定期使用新数据集重新部署 Redis,而不是更新现有缓存。当执行 a 时kubectl rollout restart deployment/cache,旧的 Redis Pod 在新的 Redis Pod 准备好接受流量之前被终止。这些新的 Redis pod 被标记为 READY,并且正如预期的那样,旧的 pod 被终止,但是redis-cli ping在新的 Redis pod 上返回(error) LOADING Redis is loading the dataset in memory。目前,Redis 需要 5-10 分钟才能停止加载数据集并准备好接受连接,但此时它们已准备好相同的时间,并且随着旧 Pod 已终止,活动流量将定向到它们。
我的怀疑是,由于此响应的状态代码为 0,因此会readinessProbe触发READY 1/1并杀死旧的 pod,但是我一直无法找到合适的方法exec: command:来避免此问题。
redis-cli info有一条loading:0|1线,所以我测试了:
readinessProbe:
exec:
command: ["redis-cli", "info", "|", "grep loading:", "|", "grep 0"]
Run Code Online (Sandbox Code Playgroud)
希望对于非 0 加载值,grep 将提供非零状态代码并使 readinessProbe 失败,但这似乎不起作用,并且具有与redis-cli ping过早终止 pod 和服务丢失相同的行为,直到加载完成完全的。
redis-cli ping其他 readinessProbe 仍然触发新 Pod 的 READY 状态,尽管上有非零状态代码exec: command:谢谢!
我研究了 bitnami/redis 图表,并了解它们如何实现活性/就绪性探测。
他们根据图表创建了一个 health-configmap,其中包含一个 shell 脚本,使用 redis-cli ping 来检查 Redis 服务器的运行状况并处理响应。
这是定义的配置映射:
data:
ping_readiness_local.sh: |-
#!/bin/bash
{{- if .Values.usePasswordFile }}
password_aux=`cat ${REDIS_PASSWORD_FILE}`
export REDIS_PASSWORD=$password_aux
{{- end }}
{{- if .Values.usePassword }}
no_auth_warning=$([[ "$(redis-cli --version)" =~ (redis-cli 5.*) ]] && echo --no-auth-warning)
{{- end }}
response=$(
timeout -s 3 $1 \
redis-cli \
{{- if .Values.usePassword }}
-a $REDIS_PASSWORD $no_auth_warning \
{{- end }}
-h localhost \
{{- if .Values.tls.enabled }}
-p $REDIS_TLS_PORT \
--tls \
--cacert {{ template "redis.tlsCACert" . }} \
{{- if .Values.tls.authClients }}
--cert {{ template "redis.tlsCert" . }} \
--key {{ template "redis.tlsCertKey" . }} \
{{- end }}
{{- else }}
-p $REDIS_PORT \
{{- end }}
ping
)
if [ "$response" != "PONG" ]; then
echo "$response"
exit 1
fi
Run Code Online (Sandbox Code Playgroud)
并且在deployment/statefulset中,只需设置探针来执行这个shell脚本:
readinessProbe:
initialDelaySeconds: {{ .Values.redis.readinessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.redis.readinessProbe.periodSeconds }}
timeoutSeconds: {{ .Values.redis.readinessProbe.timeoutSeconds }}
successThreshold: {{ .Values.redis.readinessProbe.successThreshold }}
failureThreshold: {{ .Values.redis.readinessProbe.failureThreshold }}
exec:
command:
- sh
- -c
- /scripts/ping_readiness_local.sh {{ .Values.redis.readinessProbe.timeoutSeconds }}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13133 次 |
| 最近记录: |