这可能是一个 Serverfault 或 Stack Overflow 问题,我还不确定:
我设置了一个简单的三节点 Redis 系统,包括一个主节点和两个副本节点,并使用 Redis Sentinel 管理故障转移。Redis 和 Sentinel 网络流量使用 Redis 内置的 TLS 支持和常规 CA 颁发的证书进行保护。
每个 Sentinel 实例都配置为公布其主机名并解析 DNS:
sentinel resolve-hostnames yes
sentinel announce-hostnames yes
sentinel announce-ip "redistest2.mydomain.com"
我们有一个使用 Servicestack 连接到 Sentinel 实例的 Web 服务。只要我们不验证 TLS 证书和主机名,一切就都正常:Web 服务可以看到 Redis Sentinel 侦听器,当我们终止当前主节点时,Redis 集群会投票选出新的主节点,然后 Web 服务会切换到新的可写 Redis 节点。
然而,虽然原始主节点使用其 FQDN 进行报告,但两个备份节点似乎仅使用其 IP 地址向 ServiceStack 报告。
Sentinel 日志摘录表明备份节点似乎使用了其主机名:
28011:X 15 Feb 2023 15:23:10.817 * +sentinel sentinel <hex-string> redistest2.mydomain.com 26379 @ redistest redistest1.mydomain.com 6379
28011:X 15 Feb 2023 15:23:10.821 * Sentinel new configuration saved on disk
28011:X 15 Feb 2023 15:23:10.897 * +sentinel sentinel <other-hex-string> redistest3.mydomain.com 26379 @ redistest redistest1.mydomain.com 6379
28011:X 15 Feb 2023 15:23:10.901 * Sentinel new configuration saved on disk
然而 ServiceStack 坚持只接收从服务器组返回的服务器 IP 地址:
Starting with sentinel.
Sentinel hosts: redistest1.mydomain.com:26379?ssl=true, redistest2.mydomain.com:26379?ssl=true, redistest3.mydomain.com:26379?ssl=true
Sentinel created
Host filter set.
Hostfilter: redistest1.mydomain.com:6379
Hostfilter: 10.100.60.72:6379
Hostfilter: 10.100.60.73:6379
RedisManager started.
Redis sentinel info: redistest primary: redistest1.mydomain.com:6379, replicas: 10.100.60.72:6379, 10.100.60.73:6379
Hostfilter: 10.100.60.72:6379
Hostfilter: 10.100.60.73:6379
Ping error with read only client: ServiceStack.Redis.RedisException: [14:23:47.626] Unable to Connect: sPort: 0, Error: One or more errors occurred.
(...)
---> System.AggregateException: One or more errors occurred. ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.
我可以在 Redis 和/或 Sentinel 配置方面做些什么来确保 ServiceStack 收到 Redis 节点的实际主机名,以便我们正确验证所使用的证书?
答案1
ServiceStack 日志包含了出错的必要线索:Sentinel 做了它应该做的事情,但是 Redis 备份节点是通过 IP 地址引用的。
与 Sentinel 可以在配置语句中返回包含 FQDN 的字符串类似sentinel announce-ip
,Redis 可以对配置语句执行相同操作replica-announce-ip
。
解决方案是在所有备份主机上的 Redis 配置文件中添加以下行:
replica-announce-ip servername.mydomain.com
在这种情况下,服务器名称当然是运行此特定备份节点的机器的主机名。