Служба балансировки нагрузки k8s с externalTrafficPolicy=local проходит через IP-адрес клиента на IPv4, скрывает его на IPv6
У меня возникли проблемы с передачей службы Kubernetes IPv6 через правильный исходный IP-адрес модулям. Он отлично работает на родственном IPv4.SingleStack
LoadBalancer
который передает трафик на те же модули.
Кластер представляет собой двухстековый кластер v1.21.1 без операционной системы, созданный с помощьюkubeadm
и использует Calico v3.18 в качестве cni и MetalLB для выделения IP-адресов балансировщика нагрузки службам, настроенным с помощьюtype: 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
и оказываетсяclusterIP
адрес службы IPv6. Кажется, что что-то здесь действительно выполняет какое-то TCP-проксирование (ipvs?), но неясно, почему оно так себя ведет. Я бы ожидал этого, если бы - фактически, если бы я изменил службы с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 ответ
Оказывается, у меня была запущена старая установка, которая была настроена на ошибочное наттинг IPv6-трафика как внутри, так и вне кластера. Я понял это, посмотрев правила и увидев кучуMASQUERADE
правила, которые были заполненыip-masq-agent
.
Удаление этого развертывания из кластера и перезагрузка узлов для удаленияip6tables
правила решили проблему.