Kubernetes 上的 Redis 哨兵 HA

时间:2021-06-08 12:25:27

标签: kubernetes redis redis-sentinel

我正在尝试将 1 个 redis master 和 2 个 redis 副本绑定到 Kubernetes 上的 3 个 Quorum Sentinel。我对 Kubernetes 很陌生。

我最初的计划是让主节点在与 1 个 Kubernetes SVC 相关联的 pod 上运行,而 2 个副本在与另一个 Kubernetes SVC 相关联的自己的 pod 上运行。最后,3 个 Sentinel pod 将绑定到它们自己的 SVC。副本将绑定到主 SVC(因为没有 svc,ip 会改变)。哨兵也将被配置并绑定到主和副本 SVC。但我不确定这是否可行,因为当主 pod 崩溃时,其中一个副本 pod 将如何移动到主 SVC 并成为主?这可能吗?

我采用的第二种方法是将 redis pod 包装在复制控制器中,哨兵也是如此。但是,我不确定如何使用复制控制器使 pod 中的一个主节点和其他副本。

这两种方法中的任何一种都有效吗?如果没有,我可以采用更好的设计吗?任何线索将不胜感激。

1 个答案:

答案 0 :(得分:1)

您可以使用 Helm 包管理器和 Redis Helm Chart 部署 Redis Sentinel。
如果您尚未安装 Helm3,可以使用此 documentation 进行安装。

我将提供一些解释来说明它是如何工作的。


首先,我们需要从 Redis Helm Chart 中获取 values.yaml 文件以自定义我们的安装:

$ wget https://raw.githubusercontent.com/bitnami/charts/master/bitnami/redis/values.yaml

我们可以在values.yaml文件中配置很多参数,但是为了演示目的我只启用了Sentinel并设置了redis密码:
注意:有关可在安装过程中配置的参数列表,请参阅 Redis Helm Chart Parameters 文档。

# values.yaml

global:
  redis:
    password: redispassword
...
replica:
  replicaCount: 3
...
sentinel:
  enabled: true
...

然后我们可以使用 values.yaml 文件中的配置来部署 Redis:
注意:它将部署一个由 StatefulSets 管理的三个 Pod 集群(一个主节点和两个从节点),每个 Pod 内运行一个 sentinel 容器。

$ helm install redis-sentinel bitnami/redis --values values.yaml

请务必仔细阅读图表安装输出的注意部分。它包含许多有用的信息(例如,如何从集群外部连接到您的数据库)

安装后,检查redis StatefulSetPodsServicesheadless service可以用于内部访问):

$ kubectl get pods -o wide
NAME                    READY   STATUS    RESTARTS   AGE     IP
redis-sentinel-node-0   2/2     Running   0          2m13s   10.4.2.21
redis-sentinel-node-1   2/2     Running   0          86s     10.4.0.10
redis-sentinel-node-2   2/2     Running   0          47s     10.4.1.10


$ kubectl get sts
NAME                  READY   AGE
redis-sentinel-node   3/3     2m41s

$ kubectl get svc
NAME                      TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)              AGE
redis-sentinel            ClusterIP   10.8.15.252   <none>        6379/TCP,26379/TCP   2m
redis-sentinel-headless   ClusterIP   None          <none>        6379/TCP,26379/TCP   2m

如您所见,每个 redis-sentinel-node Pod 包含 redissentinel 容器:

$ kubectl get pods redis-sentinel-node-0 -o jsonpath={.spec.containers[*].name}
redis sentinel

我们可以检查 sentinel 容器日志以找出哪个 redis-sentinel-node 是 master:

$ kubectl logs -f redis-sentinel-node-0 sentinel
...
1:X 09 Jun 2021 09:52:01.017 # Configuration loaded
1:X 09 Jun 2021 09:52:01.019 * monotonic clock: POSIX clock_gettime
1:X 09 Jun 2021 09:52:01.019 * Running mode=sentinel, port=26379.
1:X 09 Jun 2021 09:52:01.026 # Sentinel ID is 1bad9439401e44e749e2bf5868ad9ec7787e914e
1:X 09 Jun 2021 09:52:01.026 # +monitor master mymaster 10.4.2.21 6379 quorum 2
...
1:X 09 Jun 2021 09:53:21.429 * +slave slave 10.4.0.10:6379 10.4.0.10 6379 @ mymaster 10.4.2.21 6379
1:X 09 Jun 2021 09:53:21.435 * +slave slave 10.4.1.10:6379 10.4.1.10 6379 @ mymaster 10.4.2.21 6379
...

从上面的日志中可以看出,redis-sentinel-node-0 Pod 是主节点,redis-sentinel-node-1redis-sentinel-node-2 Pod 是从节点。

为了测试,让我们删除 master 并检查 sentinel 是否会将 master 角色切换到其中一个 slave:

    $ kubectl delete pod redis-sentinel-node-0
    pod "redis-sentinel-node-0" deleted
    
    $ kubectl logs -f redis-sentinel-node-1 sentinel
    ...                                                                                           
    1:X 09 Jun 2021 09:55:20.902 # Executing user requested FAILOVER of 'mymaster'
    ...
    1:X 09 Jun 2021 09:55:22.666 # +switch-master mymaster 10.4.2.21 6379 10.4.1.10 6379
    ...
    1:X 09 Jun 2021 09:55:50.626 * +slave slave 10.4.0.10:6379 10.4.0.10 6379 @ mymaster 10.4.1.10 6379
    1:X 09 Jun 2021 09:55:50.632 * +slave slave 10.4.2.22:6379 10.4.2.22 6379 @ mymaster 10.4.1.10 6379

已选择新的母版 (redis-sentinel-node-2 10.4.1.10),因此一切都按预期进行。

此外,我们可以通过连接到 Redis 节点之一来显示更多信息:

$ kubectl run --namespace default redis-client --restart='Never' --env REDIS_PASSWORD=redispassword --image docker.io/bitnami/redis:6.2.1-debian-10-r47 --command -- sleep infinity
pod/redis-client created
$ kubectl exec --tty -i redis-client --namespace default -- bash
I have no name!@redis-client:/$ redis-cli -h redis-sentinel-node-1.redis-sentinel-headless -p 6379 -a $REDIS_PASSWORD
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
redis-sentinel-node-1.redis-sentinel-headless:6379> info replication
# Replication
role:slave
master_host:10.4.1.10
master_port:6379
master_link_status:up
...