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

时间:2017-08-29 10:43:27

标签: http tcp kubernetes istio envoyproxy

我已经将envoy容器部署为k8s上的Istio部署的一部分。 每个Envoy代理容器都安装为" sidecar"在k8s的pod中的app容器旁边。

我能够从应用程序中启动HTTP流量,但在尝试联系Redis服务器(另一个容器和其他特使代理)时,我无法连接并接收HTTP/1.1 400 Bad Request来自特使的消息。

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

据我所知,Redis命令是使用纯TCP传输而不是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

由于

1 个答案:

答案 0 :(得分:0)

进入特使(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服务是正常运作的Istio服务所必需的。必须命名服务端口,并且这些名称必须以http或grpc前缀开头,以利用Istio的L7路由功能,例如:名称:http-foo或名称:http很好。具有非命名端口或没有http或grpc前缀的端口的服务将路由为L4流量。

从底线开始,只需删除port name表单Redis服务即可解决问题:)