启用 Istio 后 GCP Memorystore Redis 连接被拒绝

GCP Memorystore Redis Connection refused after enabling Istio

我们有一个现有的 GKE 集群 (1.16.9-gke.6),其中一些服务与 GCP Memorystore Redis 实例通信。然而,在那些 pods 上启用 Istio(版本 1.16.3)后,我们开始看到 redis 实例的连接被拒绝错误。 由于我们刚刚开始使用 Istio,我们允许来自服务内部网格的所有外部流量,使用:

meshConfig:
 outboundTrafficPolicy:
      mode: ALLOW_ANY

所有出站流量都进入 PassthroughCluster,如预期和观察到的 Kiali + Istio 代理日志。

另外,我的app容器和istio代理容器以及netcat都可以成功登录到redis实例。

我还尝试在我们的 helm chart 模板中为 redis 实例添加一个服务条目:

apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: gcp-memorystore-redis
spec:
  # note, host field is ignored for tcp
  hosts:
    - gcp-memorystore-redis
  addresses:
    - {{ .Values.redis.cidr }}
  endpoints:
    - address: {{ .Values.redis.nodeAddress }}
  ports:
    - number: 6379
      name: tcp-redis
      protocol: TCP
  resolution: STATIC
  location: MESH_EXTERNAL

但是,我继续收到连接被拒绝的错误。我们使用 Redisson java 客户端库,不确定这是否重要。

作为一种解决方法,我通过使用 global.proxy.includeIPRanges 添加我们的 cidr ip 范围并设置 enableProtocolSniffingForOutbound: false 来绕过 Istio 代理,这目前有效,但我真的希望将其配置为 ServiceEntry因为我最终希望通过 Egress 网关路由我的流量。

在我们的应用程序中用 ServiceEntry 指定 redis uri/ nodeAddresses 的正确格式是什么。这似乎不起作用:redis://gcp-memorystore-redis:6379

感谢任何帮助!

对于来到这里的任何其他人,我能够通过添加建议的 hack 来解决这个问题 https://github.com/istio/istio/issues/11130 before starting the app container. Similarly adding a preStop hook on Proxy container as mentioned: https://github.com/istio/istio/issues/7136

values:
  global:
    proxy:
      lifecycle:
          preStop:
            exec:
              command: [
                "/bin/sh", "-c",
                "while [ $(netstat -plunt | grep tcp | grep -v envoy | wc -l | xargs) -ne 0 ]; do printf 'Waiting for App Server to shutdown'; sleep 1; done; echo 'App server shutdown, shutting down proxy...'"
              ]

将来,if/when 这个 PR:https://github.com/istio/istio/pull/24737 被合并,事情会少一些 hacky。