![Enrutar el tráfico al clúster de Kubernetes mediante iptables](https://rvso.com/image/782618/Enrutar%20el%20tr%C3%A1fico%20al%20cl%C3%BAster%20de%20Kubernetes%20mediante%20iptables.png)
Tengo un clúster de Kubernetes (actualmente solo 1 nodo) ejecutándose en mi servidor raíz (netcup) e intento enrutar el tráfico hacia él. Soy bastante malo en networking así que espero que alguien pueda ayudarme.
en el racimometallbEstá instalado y calico según CNI. Metallb es responsable de la asignación y el anuncio de direcciones IP a K8s-LoadBalancers, lo que funciona bien internamente. Entonces puedo alcanzar un servicio de carga equilibrada desde el servidor. Sólo expongo un único servicio con una IP interna fija (proxy inverso)
Ahora quiero exponerlo al exterior enrutando el tráfico directamente a la dirección IP desde metalb usandoiptables
Se aplicaron las siguientes reglas en 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)
(Tal vez los comandos no sean 100% correctos porque los extraje de mi script ansible. Puede encontrar la parte ansible en la parte inferior)
Hasta donde tengo entendido, esto debería enviar todo el tráfico TCP entrante a la IP interna usando DNAT y todo el tráfico saliente tendrá la dirección del servidor público usando SNAT. Entonces, para un cliente que se conecta, ¿debería parecer que está hablando directamente con el puerto/IP público?
Desafortunadamente, intentar acceder al servicio desde Internet produce lo siguiente:
$> curl <public-server-ip>
curl: (7) Failed to connect to <public-server-ip> port 80 after 647 ms: Network is down
El acceso desde el servidor funciona:
$> curl <metallb-ip>
404 page not found # which the expected answer since its a blank Traefik reverse proxy
Un escaneo de puerto nmap arroja actualmente lo siguiente:
$> 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!
Pero está funcionando desde que estoy conectado vía SSH.
Actualmente no hay ninguno ufw
habilitado.
Agradezco cualquier ayuda ya que como dije no soy muy bueno haciendo networking. ;)
Guión 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
ACTUALIZAR: Con la ayuda deesteartículo traté de entender el flujo. Se agregaron declaraciones de registro para investigar dónde van mal las cosas. Esto es lo que encontré hasta ahora:
Para comprobar dónde se pierden los paquetes, agregué las siguientes reglas:
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
Solo debajo de las declaraciones de registro raw
y mangle
que aparecen. Entonces parece que el nat
paso no se activa. Verificando las reglas de manipulación con:
sudo iptables -t mangle -L
pero no pude identificar ningún problema aquí.
El reenvío de IP está habilitado:
$> sudo sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1
Entonces, ¿por qué los paquetes no llegan al nat
paso?
$> 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