拨打 tcp <REMOTE-IP>:6379: 连接:连接被拒绝

dial tcp <REMOTE-IP>:6379: connect: connection refused

我正在 GKE (Google Kubernetes Engine) 上构建一个应用程序和一个使用 Redis 的 GCE 实例的系统。 当我尝试从 GKE 上的应用程序 pod 连接到 GCE 上的 Redis 时,连接被拒绝。(dial tcp <REMOTE-IP>:6379: connect: connection refused) 该应用程序是用 Go 编写的,redis 库是 go-redis(v8)。 为什么我无法连接?

连接部分和出错部分的源码如下

    redisServerName = os.Getenv("REDIS_SERVER") // "sample.com:6379"
    redisClient = redis.NewClient(&redis.Options{
        Addr:     redisServerName,
        Password: "",
        DB:       0,
    })

    p, err := redisClient.Ping(ctx).Result()
    log.Println(p, err)

主机名已解析,不是DNS问题,redis-cli命令可执行,看来不是防火墙问题。

#  redis-cli -h <REMOTE_IP> ping
PONG

这是 运行 来自带有 Go 应用程序的 Pod 命令的结果 运行

/# redis-cli -h redis.sample.com
redis.sample.com:6379>   // can connect

/# nc redis.sample.com 6379
// There is NO response.

我断言容器中的每个应用程序都将具有相同的第 4 层(对于 Redis、TCP)网络访问权限。由于 Redis 不提供重要的访问控制,这意味着如果您容器上的一个应用程序可以通过网络访问 Redis 服务器,则同一容器上的所有其他应用程序也可以。如果一个人无法联系到 Redis,另一个人也不会。

在同一个容器上。这是测试变得棘手的地方,因为在此处重现您的 k8s 和 gke 配置没有帮助或不可行。

ICMP Ping 与tcp/6379 不同。仅仅因为 ping 有效,并不意味着 Redis 可以,反之亦然。而且不同的容器在k8s和gke中会有不同的网络访问。

app 容器上进行此测试,以排除一切可能的情况。

apk add redis 仅拉入几个包,只有 8MB,并在我测试时提供 redis-cli,但您不需要任何 redis 客户端应用程序;它很简单,可以用 netcat 来完成 .您也不必发出有效的 redis cmd - 如果您收到 -ERR unknown command 响应,则您知道网络正常工作:

/ # echo "hi, redis!" |nc localhost 6379
-ERR unknown command `hi,`, with args beginning with: `redis!`,

如果它在那里工作而不是在 Go 中,可能是因为环境变量 REDIS_SERVER 设置不正确。因此,您可能还想在命令行中测试 that

nc $REDIS_SERVER 6379