从 Envoy 后面的容器与 Redis 服务器通信

Communicating with Redis server from a container behind Envoy

我已经部署了 Envoy 容器作为 Istio 部署的一部分,通过 k8s。 每个 Envoy 代理容器都作为 "sidecar" 安装在 k8s 的 pod 中的应用程序容器旁边。

我能够从应用程序内部启动 HTTP 流量,但是当我尝试联系 Redis 服务器(另一个带有另一个 envoy 代理的容器)时,我无法连接并接收来自 HTTP/1.1 400 Bad Request 的消息特使.

在检查特使的日志时,只要此连接通过特使,我就会看到以下消息:HTTP/1.1" 0 - 0 0 0 "_"."_"."_"."_""

据我了解,Redis 命令是使用纯 TCP 传输 w/o HTTP 发送的。 Envoy 是否可能只希望看到 HTTP 流量并拒绝仅 TCP 流量? 假设我的理解是正确的,有没有办法使用 Istio 更改此行为并接受和处理通用 TCP 流量?

以下是我的相关部署yaml文件:

apiVersion: v1
kind: Service
metadata:
  name: redis
  namespace: default
  labels:
    component: redis
    role: client
spec:
  selector:
    app: redis
  ports:
  - name: http
    port: 6379
    targetPort: 6379
    protocol: TCP
  type: ClusterIP

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: redis-db
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - name: redis
        image: redis:3.2-alpine
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 6379

谢谢

进入特使(istio 代理):

kubectl exec -it my-pod -c proxy bash

查看特使配置:

cat /etc/envoy/envoy-rev2.json

您将看到它生成一个 TCP 代理过滤器,它只处理 TCP 流量。 Redis 示例:

"address": "tcp://10.35.251.188:6379",
  "filters": [
    {
      "type": "read",
      "name": "tcp_proxy",
      "config": {
        "stat_prefix": "tcp",
        "route_config": {
          "routes": [
            {
              "cluster": "out.cd7acf6fcf8d36f0f3bbf6d5cccfdb5da1d1820c",
              "destination_ip_list": [
                "10.35.251.188/32"
              ]
            }
          ]
        }
      }

在您的情况下,将 http 添加到 Redis 服务 port name(Kubernetes 部署文件)中,生成 http_connection_manager 不处理行 TCP 的过滤器。

istio docs:

Kubernetes Services are required for properly functioning Istio service. Service ports must be named and these names must begin with http or grpc prefix to take advantage of Istio’s L7 routing features, e.g. name: http-foo or name: http is good. Services with non-named ports or with ports that do not have a http or grpc prefix will be routed as L4 traffic.

最重要的是,只需从 Redis 服务中删除 port name 即可解决问题:)