You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何从Redis Sentinel获取主节点主机名?TLS证书匹配问题咨询

解决Redis Sentinel返回IP导致TLS证书不匹配的问题

我之前在Node.js项目里也碰到过一模一样的坑——Sentinel返回Redis主节点的IP,结果TLS连接因为证书绑定的是主机名直接报错。结合官方文档说Sentinel配置不能用主机名的限制,给你几个实用的解决方案:

方案1:在Node.js客户端层做IP到主机名的映射

既然Sentinel返回的是IP,我们可以在客户端连接环节把IP替换成对应的主机名。以常用的ioredis客户端为例,你可以利用它的resolveSentinel钩子来改写返回的地址:

const Redis = require('ioredis');

// 维护Redis节点IP与主机名的映射表
const redisHostMap = {
  '192.168.1.100': 'redis-master.example.com',
  '192.168.1.101': 'redis-slave-01.example.com'
};

const redisClient = new Redis({
  sentinels: [
    { host: 'sentinel-01.example.com', port: 26379 },
    { host: 'sentinel-02.example.com', port: 26379 }
  ],
  name: 'my-redis-master', // 你的Sentinel监控的主节点名称
  tls: {
    servername: 'redis-master.example.com'
  },
  resolveSentinel: (addr) => {
    // 检查当前地址是否在映射表中,替换为主机名
    if (redisHostMap[addr.host]) {
      return { host: redisHostMap[addr.host], port: addr.port };
    }
    // 不在映射表中的地址(比如Sentinel自己的地址)直接返回
    return addr;
  }
});

这个方法的好处是不需要改动Redis或Sentinel的配置,适合无法修改服务器配置的场景。缺点是如果Redis节点的IP发生变化,你需要同步更新映射表,否则会连接失败。

方案2:配置Redis节点主动宣告主机名

虽然Sentinel本身不能用主机名配置,但Redis主从节点可以通过announce-hostname配置,让Sentinel获取到节点的主机名而不是IP。具体步骤:

  1. 在Redis主节点的配置文件中添加:
    # 宣告节点的主机名,Sentinel会用这个地址返回给客户端
    announce-hostname redis-master.example.com
    # 可选:同时宣告IP,确保Sentinel能正常连接节点(如果Sentinel无法解析主机名的话)
    announce-ip 192.168.1.100
    
  2. 重启Redis主节点,等待Sentinel完成节点信息刷新(或者手动在Sentinel执行SENTINEL FLUSHCONFIG命令强制更新)。

这样Sentinel后续返回给客户端的主节点地址就会是你配置的主机名,Node.js客户端用主机名连接时就能匹配TLS证书了。这个方案是从根源解决问题,推荐在你有权限修改Redis配置的场景下使用,但要确保Sentinel服务器能解析这个主机名(可以通过配置hosts文件或内部DNS实现)。

方案3:临时关闭证书主机名验证(不推荐生产环境)

如果是测试环境临时应急,你可以在TLS配置中跳过主机名验证,但这会带来安全风险,绝对不建议在生产环境使用:

const redisClient = new Redis({
  // 其他配置...
  tls: {
    checkServerIdentity: () => undefined // 跳过主机名验证
  }
});

内容的提问来源于stack exchange,提问作者SNR

火山引擎 最新活动