Связь с сервером Redis из контейнера за Envoy

Я развернул контейнеры посланников как часть развертывания Istio на k8s. Каждый прокси-контейнер Envoy устанавливается как дополнительный элемент рядом с контейнером приложения в модуле k8s.

Я могу инициировать 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

Спасибо


person Zvika    schedule 29.08.2017    source источник


Ответы (1)


Попадание в envoy (istio proxy):

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, и это должно решить проблему :)

person Effi Bar-She'an    schedule 30.08.2017