Служба балансировки нагрузки k8s с externalTrafficPolicy = local проходит через IP-адрес клиента на IPv4, скрывает его на IPv6

У меня проблемы с получением службы kubernetes IPv6 SingleStack LoadBalancer , проходящей через правильный исходный IP-адрес в поды. Он отлично работает на родственном IPv4 SingleStack LoadBalancer , который передает трафик в те же модули.

Кластер представляет собой двухстековый кластер v1.21.1 без операционной системы, созданный с помощью kubeadm и использующий Calico v3.18 в качестве cni и MetalLB для выделения IP-адресов балансировщика нагрузки службам, настроенным с типом : LoadBalancer . Затем Calico настраивается для объявления IP-адресов балансировщика нагрузки локальному маршрутизатору через BGP. Взяв игрушечный пример развертывания одного nginx с двумя службами (один для IPv4, один для IPv6), если я скручиваю IP через адрес IPv4, журнал доступа nginx печатает правильный IP-адрес клиента в 192.168.2.0/24 :

192.168.2.128 - - [01/Jun/2021:19:32:37 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.64.1" "-"

Но при свертывании IPv6-адреса от того же клиента в 2001: 8b0: c8f: e8b0 :: / 64 , nginx показывает IP-адрес клиента fd5a: 1111: 1111 :: f31f

fd5a:1111:1111::f31f - - [01/Jun/2021:19:34:23 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.64.1" "-"

Этот адрес взят из serviceSubnet кластера из fd5a: 1111: 1111 :: / 112 и является IP-адресом кластера. адрес службы IPv6.Похоже, что-то здесь действительно выполняет какое-то TCP-проксирование (ipvs?), Но непонятно, почему это так. Я бы ожидал этого, если бы externalTrafficPolicy был Cluster - фактически, если я изменю службы с Local на Cluster , я получу локальный IP-адрес узла кластера, пересылающего запрос по IPv4 (как и ожидалось), и тот же IP-адрес кластера по IPv6. externalTrafficPolicy , похоже, не действует в случае IPv6.

Я упускаю что-то очевидное, или эти службы должны вести себя так же, как друг друга?

Манифест теста:

---
apiVersion: v1
kind: Service
metadata:
  name: test-service-source-ip-v4
  namespace: default
  labels:
    k8s-app: test-service-source-ip
spec:
  selector:
    k8s-app: test-service-source-ip
  type: LoadBalancer
  ipFamilies:
    - IPv4
  ipFamilyPolicy: SingleStack
  loadBalancerIP: 192.168.254.11
  externalTrafficPolicy: "Local"
  ports:
    - name: http-tcp
      protocol: TCP
      port: 80
---
apiVersion: v1
kind: Service
metadata:
  name: test-service-source-ip-v6
  namespace: default
  labels:
    k8s-app: test-service-source-ip
spec:
  selector:
    k8s-app: test-service-source-ip
  type: LoadBalancer
  ipFamilies:
    - IPv6
  ipFamilyPolicy: SingleStack
  loadBalancerIP: 2001:8b0:c8f:e8b1:beef:f00d::11
  externalTrafficPolicy: "Local"
  ports:
    - name: http-tcp
      protocol: TCP
      port: 80

---
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: default
  name: test-service-source-ip
  labels:
    k8s-app: test-service-source-ip
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: test-service-source-ip
  template:
    metadata:
      labels:
        k8s-app: test-service-source-ip
    spec:
      containers:
        - name: test-service-source-ip
          image: nginx:1
          ports:
            - containerPort: 80
              protocol: TCP
-1
задан 1 June 2021 в 22:51
1 ответ

Оказывается, у меня была запущена старая установка ip-masq-agent , которая была настроена на ошибочную обработку входящего и исходящего IPv6-трафика. кластера. Я понял это, просмотрев правила ip6tables и увидев группу правил MASQUERADE , которые были заполнены ip-masq-agent .

Удаление этого развертывания из кластера и перезагрузка узлов для удаления правил ip6tables решила проблему.

1
ответ дан 28 July 2021 в 15:22

Теги

Похожие вопросы