Kubernetes 上的 Redis 哨兵 HA

Kau*_*k S 4 redis redis-sentinel kubernetes

我正在尝试将 1 个 Redis 主服务器和 2 个 Redis 副本绑定到 Kubernetes 上的 3 个 Quorum Sentinel。我对 Kubernetes 非常陌生。

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

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

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

mat*_*t_j 12

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

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


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

$ wget https://raw.githubusercontent.com/bitnami/charts/master/bitnami/redis/values.yaml
Run Code Online (Sandbox Code Playgroud)

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

# values.yaml

global:
  redis:
    password: redispassword
...
replica:
  replicaCount: 3
...
sentinel:
  enabled: true
...
Run Code Online (Sandbox Code Playgroud)

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

$ helm install redis-sentinel bitnami/redis --values values.yaml
Run Code Online (Sandbox Code Playgroud)

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

安装完成后,检查redis StatefulSetPods(内部访问可以使用headless服务):Services

$ 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
Run Code Online (Sandbox Code Playgroud)

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

$ kubectl get pods redis-sentinel-node-0 -o jsonpath={.spec.containers[*].name}
redis sentinel
Run Code Online (Sandbox Code Playgroud)

我们可以检查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
...
Run Code Online (Sandbox Code Playgroud)

从上面的日志可以看到,redis-sentinel-node-0Pod是master,而redis-sentinel-node-1& redis-sentinel-node-2Pod是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
Run Code Online (Sandbox Code Playgroud)

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
...
Run Code Online (Sandbox Code Playgroud)