Я пытаюсь погрузиться в сетевая модель K8s, и я думаю, что до сих пор хорошо ее понимаю, но есть одна вещь, которую я не могу понять. В руководстве Cluster Networking упоминается следующее:
Kubernetes предъявляет следующие фундаментальные требования к любой сетевой реализации (запрещая любые политики преднамеренной сегментации сети):
- все контейнеры могут взаимодействовать со всеми другими контейнерами без NAT
- все узлы могут связываться со всеми контейнерами (и наоборот) без NAT
- IP-адрес, который контейнер видит в себе, - это тот же IP-адрес, который другие видят в нем.
Второй пункт указывает, что связь контейнера x-узла должна быть возможна без NAT. Однако это неверно, когда kube-proxy работает в режиме iptables
. Это дамп iptables с одного из моих узлов:
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
KUBE-POSTROUTING all -- anywhere anywhere /* kubernetes postrouting rules */
Chain KUBE-POSTROUTING (1 references)
target prot opt source destination
MASQUERADE all -- anywhere anywhere /* kubernetes service traffic requiring SNAT */ mark match 0x4000/0x4000
/* sample target pod chain being marked for MASQ */
Chain KUBE-SEP-2BKJZA32HM354D5U (1 references)
target prot opt source destination
KUBE-MARK-MASQ all -- xx.yyy.zzz.109 anywhere /* kube-system/heapster: */
DNAT tcp -- anywhere anywhere /* kube-system/heapster: */ tcp to:xx.yyy.zzz.109:8082
Chain KUBE-MARK-MASQ (156 references)
target prot opt source destination
MARK all -- anywhere anywhere MARK or 0x4000
Похоже, K8s меняет исходный IP-адрес отмеченных исходящих пакетов на IP-адрес узла (для службы ClusterIP). И они даже прямо упоминают об этом в Исходный IP-адрес для служб с Type = ClusterIP:
Пакеты, отправленные в ClusterIP из кластера, никогда не являются исходным NAT, если вы используете kube-proxy в режиме iptables, который используется по умолчанию, начиная с Kubernetes 1.2. Если клиентский модуль и серверный модуль находятся в одном узле, client_address является IP-адресом клиентского модуля. Однако, если клиентский модуль и серверный модуль находятся в разных узлах, client_address является фланельным IP-адресом узла клиентского модуля.
Это начинается с того, что пакеты в кластере никогда не используют SNAT, но затем переходит к утверждению, что пакеты, отправленные в модули на других узлах, на самом деле являются SNAT. Я сбит с толку - неправильно ли я интерпретирую, что все узлы могут связываться со всеми контейнерами (и наоборот) без требования NAT?