1

我正在 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

1 回答 1

1

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

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

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

在应用程序容器上进行此测试,以消除等式中的所有可能。

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设置不正确。因此,您可能还想在命令行中对其进行测试。

nc $REDIS_SERVER 6379
于 2021-09-29T16:57:41.860 回答