5

我已经在 k8s 上部署了 envoy 容器作为 Istio 部署的一部分。每个 Envoy 代理容器都作为“sidecar”安装在 k8s 的 pod 中的应用容器旁边。

我能够从应用程序内部发起 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

谢谢

4

1 回答 1

2

进入 envoy(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 文档

Kubernetes 服务是正常运行的 Istio 服务所必需的。服务端口必须命名,并且这些名称必须以 http 或 grpc 前缀开头,以利用 Istio 的 L7 路由功能,例如 name: http-foo 或 name: http 是好的。具有未命名端口或端口没有 http 或 grpc 前缀的服务将作为 L4 流量路由。

底线,只需删除port name表单 Redis 服务,它应该可以解决问题:)

于 2017-08-30T12:16:01.593 回答