Kubernetes + metallb + traefik: как получить реальный ip клиента? - PullRequest
0 голосов
/ 29 мая 2018

traefik.toml :

defaultEntryPoints = ["http", "https"]

[entryPoints]
  [entryPoints.http]
  address = ":80"
    [entryPoints.http.forwardedHeaders]
      trustedIPs = ["0.0.0.0/0"]
    [entryPoints.http.redirect]
      entryPoint = "https"
  [entryPoints.https]
  address = ":443"
    [entryPoints.https.tls]
    [entryPoints.https.forwardedHeaders]
      trustedIPs = ["0.0.0.0/0"]
[api]

traefik Service :

kind: Service
apiVersion: v1
metadata:
  name: traefik-ingress-service
  namespace: kube-system
spec:
  selector:
    k8s-app: traefik-ingress-lb
  ports:
    - protocol: TCP
      port: 80
      name: http
    - protocol: TCP
      port: 443
      name: https
  type: LoadBalancer

Затем:

kubectl run source-ip-app --image=k8s.gcr.io/echoserver:1.4
deployment "source-ip-app" created

kubectl expose deployment source-ip-app --name=clusterip --port=80 --target-port=8080
service "clusterip" exposed

kubectl get svc clusterip
NAME        TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
clusterip   ClusterIP   10.5.55.102   <none>        80/TCP    2h

Создание входа для clusterip:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: clusterip-ingress
  namespace: default
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
  - host: clusterip.staging
    http:
      paths:
      - backend:
          serviceName: clusterip
          servicePort: 80

clusterip.staging ip: 192.168.0.69

С другого компьютера с ip: 192.168.0.100:

wget -qO - clusterip.staging

и получите результаты:

CLIENT VALUES:
client_address=10.5.65.74
command=GET
real path=/
query=nil
request_version=1.1
request_uri=http://clusterip.staging:8080/

SERVER VALUES:
server_version=nginx: 1.10.0 - lua: 10001

HEADERS RECEIVED:
accept=text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
accept-encoding=gzip, deflate, br
accept-language=ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
cache-control=max-age=0
host=clusterip.staging
upgrade-insecure-requests=1
x-forwarded-for=10.5.64.0
x-forwarded-host=clusterip.staging
x-forwarded-port=443
x-forwarded-proto=https
x-forwarded-server=traefik-ingress-controller-755cc56458-t8q9k
x-real-ip=10.5.64.0
BODY:
-no body in request-

kubectl get svc --all-namespaces

NAMESPACE     NAME                      TYPE           CLUSTER-IP    EXTERNAL-IP    PORT(S)                                                 AGE
default       clusterip                 NodePort       10.5.55.102   <none>         80:31169/TCP                                            19h
default       kubernetes                ClusterIP      10.5.0.1      <none>         443/TCP                                                 22d
kube-system   kube-dns                  ClusterIP      10.5.0.3      <none>         53/UDP,53/TCP                                           22d
kube-system   kubernetes-dashboard      ClusterIP      10.5.5.51     <none>         443/TCP                                                 22d
kube-system   traefik-ingress-service   LoadBalancer   10.5.2.37     192.168.0.69   80:32745/TCP,443:30219/TCP                              1d
kube-system   traefik-web-ui            NodePort       10.5.60.5     <none>         80:30487/TCP                                            7d

Как получить реальный IP (192.168.0.100) в моей установке?Почему x-real-ip 10.5.64.0?

PS Извините за возможно глупый вопрос.Я новичок, я не смог найти ответы в документации.

1 Ответ

0 голосов
/ 30 мая 2018

Когда kube-proxy использует режим iptables, он использует NAT для отправки данных на узел, где работает полезная нагрузка, и в этом случае вы теряете исходный адрес SourceIP.

Как я понял,вы используете Matallb за входной службой Traefik (потому что ее тип LoadBalancer).Это означает, что трафик от клиента к бэкэнду идет следующим образом:

Client -> Metallb -> Traefik LB -> Traefik Service -> Backend pod.

Traefik работает правильно и добавляет заголовки x-*, включая x-forwarded-for и x-real-ip, которые содержатподдельный адрес, и именно поэтому:

Из Metallb документации :

MetalLB понимает опцию externalTrafficPolicy службы и реализует различные режимы объявлений в зависимости отвыбранный вами протокол политики и объявления.

  • Layer2

    Эта политика приводит к равномерному распределению трафика по всем модулям службы.Однако kube-proxy будет скрывать исходный IP-адрес соединения при балансировке нагрузки, поэтому ваши журналы модуля будут показывать, что внешний трафик, по-видимому, поступает от ведущего узла кластера.

  • BGP

    • Политика трафика «Кластер»

      С политикой трафика Кластера по умолчаниюкаждый узел в вашем кластере будет привлекать трафик для службы IP.На каждом узле трафик подвергается второму уровню балансировки нагрузки (предоставляемому kube-proxy), который направляет трафик на отдельные модули.

      ......

      Другим недостатком политики «Кластер» является то, что kube-proxy будет скрывать IP-адрес источника соединения, когда оно выполняет балансировку нагрузки, поэтому ваши журналы модуля будут показывать, что внешний трафик, по-видимому, поступаетот узлов вашего кластера.

    • «Локальная» политика трафика

      При локальной политике трафика узлы будут привлекать трафик только в том случае, если они работают.или более локально.Маршрутизаторы BGP будут балансировать нагрузку входящего трафика только между теми узлами, на которых в данный момент размещается служба.На каждом узле трафик kube-proxy пересылается только локальным модулям, между узлами отсутствует «горизонтальный» поток трафика.

      Эта политика обеспечивает наиболее эффективный поток трафика для вашей службы.Более того, поскольку kube-proxy не нужно отправлять трафик между узлами кластера, ваши модули могут видеть реальный IP-адрес источника входящих соединений.

Наконец, единственный способ получить реальный IP-адрес источника - это использовать «Локальный» режим TrafficPolicy.

. Если вы настроите его, вы получите то, что хотите.

...