![Направьте трафик в кластер Kubernetes с помощью iptables](https://rvso.com/image/782618/%D0%9D%D0%B0%D0%BF%D1%80%D0%B0%D0%B2%D1%8C%D1%82%D0%B5%20%D1%82%D1%80%D0%B0%D1%84%D0%B8%D0%BA%20%D0%B2%20%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%20Kubernetes%20%D1%81%20%D0%BF%D0%BE%D0%BC%D0%BE%D1%89%D1%8C%D1%8E%20iptables.png)
У меня есть кластер kubernetes (сейчас только 1 узел), работающий на моем корневом сервере (netcup), и я пытаюсь направить трафик на него. Я довольно плох в сетях, так что надеюсь, кто-нибудь сможет мне помочь.
На кластереметаллбустановлен и calico как CNI. Metallb отвечает за назначение и объявление IP-адресов для K8s-LoadBalancers, что прекрасно работает внутри. Таким образом, я могу получить доступ к службе балансировки нагрузки изнутри сервера. Я выставляю только одну службу с фиксированным внутренним IP (обратный прокси)
Теперь я хочу сделать его доступным для внешнего мира, направив трафик напрямую на IP-адрес из metallb, используяiptables
В iptables были применены следующие правила:
iptables -A PREROUTING -t nat -p tcp -m tcp -j DNAT --to-destination <metallb-ip> -i eth0 --destination-port 80 -m comment --comment Redirect web traffic to cluster (80)
iptables -A PREROUTING -t nat -p tcp -m tcp -j DNAT --to-destination <metallb-ip> -i eth0 --destination-port 443 -m comment --comment Redirect web traffic to cluster (443)
iptables -A POSTROUTING -t nat -p tcp -m tcp -j SNAT --to-source <public-server-ip> -o eth0 --destination-port 80 -m comment --comment Redirect web traffic from cluster (80)
iptables -A POSTROUTING -t nat -p tcp -m tcp -j SNAT --to-source <public-server-ip> -o eth0 --destination-port 443 -m comment --comment Redirect web traffic from cluster (443)
(возможно, команды не на 100% верны, потому что я извлек их из своего скрипта ansible. Часть ansible вы можете найти внизу)
Насколько я понимаю, это должно отправлять весь входящий трафик TCP на внутренний IP с использованием DNAT, а весь исходящий трафик будет иметь публичный адрес сервера с использованием SNAT. Так что для подключающегося клиента это должно выглядеть так, будто он напрямую общается с публичным IP/портом?
К сожалению, попытка доступа к сервису через Интернет приводит к следующему:
$> curl <public-server-ip>
curl: (7) Failed to connect to <public-server-ip> port 80 after 647 ms: Network is down
Доступ с сервера работает:
$> curl <metallb-ip>
404 page not found # which the expected answer since its a blank Traefik reverse proxy
В настоящее время сканирование портов nmap выдает следующее:
$> nmap -Pn -p 80,443 <public-server-ip>
Starting Nmap 7.93 ( https://nmap.org ) at 2022-12-15 15:57 CET
Strange SO_ERROR from connection to <public-server-ip> (50 - 'Network is down') -- bailing scan
QUITTING!
Но он работает, так как я подключился по SSH.
В настоящее время нет ufw
включенных.
Я буду признателен любой помощи, поскольку, как я уже сказал, я не очень хорош в налаживании связей. ;)
Скрипт Ansible:
- name: DNAT port 80 to cluster
iptables:
table: nat
chain: PREROUTING
in_interface: eth0
protocol: tcp
match: tcp
jump: DNAT # REDIRECT
to_destination: <metallb-ip>
destination_port: 80
comment: Redirect web traffic to cluster (80)
become: yes
- name: DNAT port 443 to cluster
iptables:
table: nat
chain: PREROUTING
in_interface: eth0
protocol: tcp
match: tcp
destination_port: 443
jump: DNAT # REDIRECT
to_destination: <metallb-ip>
comment: Redirect web traffic to cluster (443)
become: yes
- name: SNAT port 80 from cluster
iptables:
table: nat
chain: POSTROUTING
out_interface: eth0
protocol: tcp
match: tcp
destination_port: 80
jump: SNAT # REDIRECT
to_source: <public-server-ip>
comment: Redirect web traffic from cluster (443)
become: yes
- name: SNAT port 443 from cluster
iptables:
table: nat
chain: POSTROUTING
out_interface: eth0
protocol: tcp
match: tcp
destination_port: 443
jump: SNAT # REDIRECT
to_source: <public-server-ip>
comment: Redirect web traffic from cluster (443)
become: yes
- name: Configure IP Masquerading
iptables:
table: nat
chain: POSTROUTING
out_interface: eth0
jump: MASQUERADE
ОБНОВЛЯТЬ: С помощьюэтотстатья, в которой я пытался понять поток. Добавлены операторы регистрации, чтобы исследовать, где что-то идет не так. Вот что я нашел на данный момент:
Чтобы проверить, где теряются пакеты, я добавил следующие правила:
iptables -t raw -A PREROUTING -p tcp --dport 80 -j LOG --log-prefix "[raw:PREROUTING]: "
iptables -t mangle -A PREROUTING -p tcp --dport 80 -j LOG --log-prefix "[mangle:PREROUTING]: "
iptables -t nat -A PREROUTING -p tcp --dport 80 -j LOG --log-prefix "[nat:PREROUTING]: "
iptables -t mangle -A POSTROUTING -p tcp --sport 80 -j LOG --log-prefix "[mangle:PREROUTING]: "
iptables -t nat -A POSTROUTING -p tcp --sport 80 -j LOG --log-prefix "[nat:PREROUTING]: "
Под /var/log/kern.log
только raw
и mangle
лог-выражениями появляются. Так что, похоже, что nat
-шаг не срабатывает. Проверяю правила mangle с помощью:,
sudo iptables -t mangle -L
но не могу определить здесь никаких проблем.
IP-Forward включен:
$> sudo sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1
Так почему же пакеты не доходят до -шага nat
?
$> sudo iptables -t mangle -L
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
cali-PREROUTING all -- anywhere anywhere /* cali:6gwbT8clXdHdC1b1 */
LOG tcp -- anywhere anywhere tcp dpt:http LOG level warning prefix "[mangle:PREROUTING]: "
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
cali-POSTROUTING all -- anywhere anywhere /* cali:O3lYWMrLQYEMJtB5 */
Chain KUBE-IPTABLES-HINT (0 references)
target prot opt source destination
Chain KUBE-KUBELET-CANARY (0 references)
target prot opt source destination
Chain KUBE-PROXY-CANARY (0 references)
target prot opt source destination
Chain cali-from-host-endpoint (1 references)
target prot opt source destination
Chain cali-to-host-endpoint (1 references)
target prot opt source destination
Chain cali-PREROUTING (1 references)
target prot opt source destination
ACCEPT all -- anywhere anywhere /* cali:6BJqBjBC7crtA-7- */ ctstate RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere /* cali:KX7AGNd6rMcDUai6 */ mark match 0x10000/0x10000
cali-from-host-endpoint all -- anywhere anywhere /* cali:wNH7KsA3ILKJBsY9 */
ACCEPT all -- anywhere anywhere /* cali:Cg96MgVuoPm7UMRo */ /* Host endpoint policy accepted packet. */ mark match 0x10000/0x10000
Chain cali-POSTROUTING (1 references)
target prot opt source destination
RETURN all -- anywhere anywhere /* cali:NX-7roTexQ3fGRfU */ mark match 0x10000/0x10000
MARK all -- anywhere anywhere /* cali:nnqPh8lh2VOogSzX */ MARK and 0xfff0ffff
cali-to-host-endpoint all -- anywhere anywhere /* cali:nquN8Jw8Tz72pcBW */ ctstate DNAT
RETURN all -- anywhere anywhere /* cali:jWrgvDQ0xEZHmta3 */ /* Host endpoint policy accepted packet. */ mark match 0x10000/0x10000