azure-aks - Redis 集群 StatefulSet 的 Pod 删除不会恢复 redis 的集群状态
问题描述
我在 statefulset 中使用了 redis:5.0.1-alpine,有状态集有 6 个 pod,redis 集群的形成是使用以下命令完成的
redis-cli --cluster create {IPlist 放在这里} --cluster-replicas 1
现在,如果 Pod 被意外删除或 AKS 停止服务,那么在 AKS 恢复后创建的 Pod 将具有不同的 IP。
我尝试故意删除 pod,当重新创建 pod 时,集群状态更改为“失败”(最初创建集群时“正常”)
此外,当我尝试将旧数据集放入集群时,会出现一条消息,告知“集群已关闭”
我已经展示了用于集群创建的 redis.conf 文件的代码
apiVersion: v1
kind: ConfigMap
metadata:
name: redis-cluster
namespace: redis
data:
update-node.sh: |
#!/bin/sh
REDIS_NODES="/data/nodes.conf"
sed -i -e "/myself/ s/[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-
9]\{1,3\}/${POD_IP}/" ${REDIS_NODES}
exec "$@"
redis.conf: |+
cluster-enabled yes
cluster-require-full-coverage no
cluster-node-timeout 15000
cluster-config-file /data/nodes.conf
cluster-migration-barrier 1
appendonly yes
protected-mode no
Redis Cluster Nodes and Slots 相关数据作为附加的 Redis 集群节点 和插槽
解决方案
当您重新启动单个 pod 时,该 pod 会使用一个新 IP 启动,将其发布到其他 pod,它们都会更新有关 IP 更改的配置。
如果所有 pod 同时关闭和启动(例如,如果集群中的所有节点都重新启动),则 pod 无法相互通信,因为它们的 node.conf 中的 IP 是错误的。
一个可能的解决方案是更新所有正在运行的 pod 上的 nodes.conf 中的 IP,并一个接一个地重新启动它们。
我通过在每个 pod 中植入这个脚本来做到这一点:
恢复-pod.sh
#!/bin/sh
set -e
REDIS_NODES_FILE="/data/nodes.conf"
for redis_node_ip in "$@"
do
redis_node_id=`redis-cli -h $redis_node_ip -p 6379 cluster nodes | grep myself | awk '{print $1}'`
sed -i.bak -e "/^$redis_node_id/ s/[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/${redis_node_ip}/" ${REDIS_NODES_FILE}
done
并从 Kubernetes 节点之一运行它:
恢复-cluster.sh
#!/bin/bash
for i in {0..5}
do
echo "Updating the correct IPs in nodes.conf on redis-cluster-redis-cluster-statefulset-$i"
kubectl exec -it redis-cluster-redis-cluster-statefulset-$i /readonly-config/recover-pod.sh $(kubectl get pods -l app=redis-cluster -o jsonpath='{range.items[*]}{.status.podIP} ' )
done
kubectl patch statefulset redis-cluster-redis-cluster-statefulset --patch '{"spec": {"template": {"metadata": {"labels": {"date": "'`date +%s`'" }}}}}'
这会导致 Redis 集群恢复健康状态。
推荐阅读
- javascript - json中的意外令牌D?
- r - stat_compare_means 选定组的方差分析
- php - “无法访问站点”Socket.IO
- spotfire - 设置选项卡在数据表属性中不可用
- python - axes.set_xticklabels 打破日期时间格式
- spring - 在 Spring Data JPA 中使用超类
- php - 如何使用 CURL PHP 从 Google Business 获取评论
- mysql - 加入两个表以获得人的最大登录时间
- php - GNU Parallel 作为具有命名管道的作业队列
- javascript - 替换图库图像的 Ajax 调用后 lightGallery 无法正常工作