redis / go-redis

Redis Go client
https://redis.uptrace.dev
BSD 2-Clause "Simplified" License
19.6k stars 2.31k forks source link

Unable to connect to Redis cluster client using kubectl port-forward #3027

Open jppade opened 2 weeks ago

jppade commented 2 weeks ago

What do we want to do? Connect to a Redis cluster (consisting of 3 masters and 3 slaves) running in Kubernetes using kubectl port-forward to localhost:6379. The client looks as follows:

func GetRedisClient() *redis.ClusterClient {
    var redisClusterClient *redis.ClusterClient
    password := utils.Getenv("REDISPASSWORD", "")
    addresses := strings.Split(utils.Getenv("REDIS_ADDRS", "localhost:6379"), ",")
    redisClusterClient = redis.NewClusterClient(&redis.ClusterOptions{
        Password:    password,
        Addrs:       addresses,
    })
    pong, err := redisClusterClient.Ping(context.Background()).Result()
    if err != nil {
        log.Error("NewDataStore redis: ", err)
    }
    log.Debug("redisFailoverClient", pong)
    return redisClusterClient
}

Connection from localhost works fine with redis-cli -c -p 6379 -a redis_password using the port-forward.

Expected Behavior

Connect to remote redis cluster.

Current Behavior

The following error: dial tcp remote_ip:6379: connect: no route to host Where remote_ip is the ip address of a master node in the cluster, i.e. the first master obtained by cluster slots. It looks as if the cluster client library reroutes localhost:6379 to a cluster node and tries to reconnect, which obviously fails.

Possible Solution

Not a solution, but we tried adding

TLSConfig: &tls.Config{
    ServerName: "you domain",
},

to redis.Options in the cluster client such as proposed in https://github.com/redis/go-redis/issues/1698. This did not work though.

monkey92t commented 4 hours ago

I don't quite understand what it means. The go-redis connection to redis-cluster is different from a standalone Redis connection. It will use the node address returned by redis-cluster (CLUSTER NODES). If it's a local address, it won't be accessible from outside.