Проблема с сетью Kubernetes - Service nodePort недоступен извне

У меня есть кластер Kubernetes с 3 узлами: node1 (master), node2 и node3. У меня есть модуль, который в настоящее время запланирован на node3, и я хотел бы, чтобы он был доступен для внешнего кластера. Итак, у меня есть служба типа nodePort с параметром nodePort, установленным на 30080. Я могу успешно выполнять curl localhost:30080 локально на каждом узле: node1, node2 и node3. Но внешне curl nodeX:30080 работает только против node3. Два других таймаута. tcpdump подтверждает, что node1 и node2 получают запрос, но не отвечают.

Как я могу заставить эту работу работать для всех трех узлов, чтобы мне не приходилось отслеживать, на каком узле сейчас запланирован модуль? Я предполагаю, что это проблема iptables, когда мне не хватает правила iptables для трафика DNAT, если исходный IP-адрес не является localhost. При этом я понятия не имею, как устранить неполадки, чтобы подтвердить, что это проблема, а затем как ее исправить. Похоже, это правило должно быть автоматически.

Вот некоторая информация о моей настройке:
kube-ravi196: 10.163.148.196
kube-ravi197: 10.163.148.197
kube-ravi198: 10.163.148.198
CNI: Canal (фланель + бязь)
ОС хоста: Ubuntu 16.04
Кластер, настроенный с помощью kubeadm

$ kubectl get pods --namespace=kube-system -l "k8s-app=kube-registry" -o wide
NAME                     READY     STATUS    RESTARTS   AGE       IP              NODE
kube-registry-v0-1mthd   1/1       Running   0          39m       192.168.75.13   ravi-kube198

$ kubectl get service --namespace=kube-system -l "k8s-app=kube-registry"
NAME            CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kube-registry   10.100.57.109   <nodes>       5000:30080/TCP   5h

$ kubectl get pods --namespace=kube-system -l "k8s-app=kube-proxy" -o wide
NAME               READY     STATUS    RESTARTS   AGE       IP               NODE
kube-proxy-1rzz8   1/1       Running   0          40m       10.163.148.198   ravi-kube198
kube-proxy-fz20x   1/1       Running   0          40m       10.163.148.197   ravi-kube197
kube-proxy-lm7nm   1/1       Running   0          40m       10.163.148.196   ravi-kube196

Обратите внимание, что curl localhost с узла ravi-kube196 прошел успешно (404 - хорошо).

deploy@ravi-kube196:~$ curl localhost:30080/test
404 page not found

Но попытка свернуть IP с машины за пределами кластера не удалась:

ravi@rmac2015:~$ curl 10.163.148.196:30080/test
(hangs)

Затем попытка скрутить IP-адрес узла, на который запланирован модуль, работает:

ravi@rmac2015:~$ curl 10.163.148.198:30080/test
404 page not found

Вот мои правила iptables для этой службы / модуля на узле 196:

deploy@ravi-kube196:~$ sudo iptables-save | grep registry
-A KUBE-NODEPORTS -p tcp -m comment --comment "kube-system/kube-registry:registry" -m tcp --dport 30080 -j KUBE-MARK-MASQ
-A KUBE-NODEPORTS -p tcp -m comment --comment "kube-system/kube-registry:registry" -m tcp --dport 30080 -j KUBE-SVC-JV2WR75K33AEZUK7
-A KUBE-SEP-7BIJVD3LRB57ZVM2 -s 192.168.75.13/32 -m comment --comment "kube-system/kube-registry:registry" -j KUBE-MARK-MASQ
-A KUBE-SEP-7BIJVD3LRB57ZVM2 -p tcp -m comment --comment "kube-system/kube-registry:registry" -m tcp -j DNAT --to-destination 192.168.75.13:5000
-A KUBE-SEP-7QBKTOBWZOW2ADYZ -s 10.163.148.196/32 -m comment --comment "kube-system/glusterfs-dynamic-kube-registry-pvc:" -j KUBE-MARK-MASQ
-A KUBE-SEP-7QBKTOBWZOW2ADYZ -p tcp -m comment --comment "kube-system/glusterfs-dynamic-kube-registry-pvc:" -m tcp -j DNAT --to-destination 10.163.148.196:1
-A KUBE-SEP-DARQFIU6CIZ6DHSZ -s 10.163.148.198/32 -m comment --comment "kube-system/glusterfs-dynamic-kube-registry-pvc:" -j KUBE-MARK-MASQ
-A KUBE-SEP-DARQFIU6CIZ6DHSZ -p tcp -m comment --comment "kube-system/glusterfs-dynamic-kube-registry-pvc:" -m tcp -j DNAT --to-destination 10.163.148.198:1
-A KUBE-SEP-KXX2UKHAML22525B -s 10.163.148.197/32 -m comment --comment "kube-system/glusterfs-dynamic-kube-registry-pvc:" -j KUBE-MARK-MASQ
-A KUBE-SEP-KXX2UKHAML22525B -p tcp -m comment --comment "kube-system/glusterfs-dynamic-kube-registry-pvc:" -m tcp -j DNAT --to-destination 10.163.148.197:1
-A KUBE-SERVICES ! -s 192.168.0.0/16 -d 10.106.192.243/32 -p tcp -m comment --comment "kube-system/glusterfs-dynamic-kube-registry-pvc: cluster IP" -m tcp --dport 1 -j KUBE-MARK-MASQ
-A KUBE-SERVICES -d 10.106.192.243/32 -p tcp -m comment --comment "kube-system/glusterfs-dynamic-kube-registry-pvc: cluster IP" -m tcp --dport 1 -j KUBE-SVC-E66MHSUH4AYEXSQE
-A KUBE-SERVICES ! -s 192.168.0.0/16 -d 10.100.57.109/32 -p tcp -m comment --comment "kube-system/kube-registry:registry cluster IP" -m tcp --dport 5000 -j KUBE-MARK-MASQ
-A KUBE-SERVICES -d 10.100.57.109/32 -p tcp -m comment --comment "kube-system/kube-registry:registry cluster IP" -m tcp --dport 5000 -j KUBE-SVC-JV2WR75K33AEZUK7
-A KUBE-SVC-E66MHSUH4AYEXSQE -m comment --comment "kube-system/glusterfs-dynamic-kube-registry-pvc:" -m statistic --mode random --probability 0.33332999982 -j KUBE-SEP-7QBKTOBWZOW2ADYZ
-A KUBE-SVC-E66MHSUH4AYEXSQE -m comment --comment "kube-system/glusterfs-dynamic-kube-registry-pvc:" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-KXX2UKHAML22525B
-A KUBE-SVC-E66MHSUH4AYEXSQE -m comment --comment "kube-system/glusterfs-dynamic-kube-registry-pvc:" -j KUBE-SEP-DARQFIU6CIZ6DHSZ
-A KUBE-SVC-JV2WR75K33AEZUK7 -m comment --comment "kube-system/kube-registry:registry" -j KUBE-SEP-7BIJVD3LRB57ZVM2

логи kube-proxy с узла 196:

deploy@ravi-kube196:~$ kubectl logs --namespace=kube-system kube-proxy-lm7nm
I0105 06:47:09.813787       1 server.go:215] Using iptables Proxier.
I0105 06:47:09.815584       1 server.go:227] Tearing down userspace rules.
I0105 06:47:09.832436       1 conntrack.go:81] Set sysctl 'net/netfilter/nf_conntrack_max' to 131072
I0105 06:47:09.836004       1 conntrack.go:66] Setting conntrack hashsize to 32768
I0105 06:47:09.836232       1 conntrack.go:81] Set sysctl 'net/netfilter/nf_conntrack_tcp_timeout_established' to 86400
I0105 06:47:09.836260       1 conntrack.go:81] Set sysctl 'net/netfilter/nf_conntrack_tcp_timeout_close_wait' to 3600

person ravishi    schedule 05.01.2017    source источник
comment
Вы не сможете получить доступ к службе от мастера - можете ли вы подтвердить, что не можете получить доступ к службе с 10.163.148.197?   -  person kellanburket    schedule 05.01.2017
comment
Нет, таймаут для 197, а также для 196 (мастер). Почему вы говорите, что я не смогу получить доступ к услуге от мастера? Насколько я понимаю, все узлы должны проксировать службу на узел с запланированным модулем. И проксирование действительно работает, когда я запускаю curl localhost:30080 непосредственно на мастере или на любых узлах миньонов. Просто внешне это не удается.   -  person ravishi    schedule 05.01.2017
comment
Извините - вы правы насчет главного узла - моя ошибка.   -  person kellanburket    schedule 06.01.2017


Ответы (1)


Я нашел причину, по которой сервис не мог быть доступен извне. Это произошло из-за того, что цепочка iptables FORWARD отбрасывала пакеты. Я поднял проблему с кубернетами на странице https://github.com/kubernetes/kubernetes/issues/39658 с кучей подробностей там. (Плохой) обходной путь - изменить политику FORWARD по умолчанию на ACCEPT.

Обновление 1/10

Я поднял проблему с Canal, https://github.com/projectcalico/canal/issues/31, поскольку, похоже, это проблема, связанная с каналом. Трафик, перенаправляемый на интерфейс flannel.1, пропадает. Лучшее решение, чем изменение политики FORWARD по умолчанию на ACCEPT, - это просто добавить правило для интерфейса flannel.1. sudo iptables -A FORWARD -o flannel.1 -j ACCEPT.

person ravishi    schedule 10.01.2017