Kubernetes 上的 Redis 哨兵 HA

Redis sentinel HA on Kubernetes

我正在尝试将 1 个 redis 主节点和 2 个 redis 副本绑定到 Kubernetes 上的 3 个 Quorum Sentinel。我是 Kubernetes 的新手。

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

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

这两种方法中的任何一种都行得通吗?如果没有,是否有更好的设计可以采用?任何潜在客户将不胜感激。

您可以使用 Helm package manager and the 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

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

安装完成后查看redisStatefulSetPodsServicesheadless 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 是主控:

$ 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 是 master,redis-sentinel-node-1 & redis-sentinel-node-2 Pods 是 slave。

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

    $ 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
...