Files
kubernetes/redes_internet.md
2025-08-11 00:49:24 +02:00

336 lines
7.9 KiB
Markdown

# 1. Guía avanzada de Multus en Kubernetes
## 1.1 Instala Multus (opcional, para múltiples redes)
Multus permite que un pod tenga más de una interfaz de red (multi-homed), útil para appliances, firewalls, balanceadores, gateways, etc. Instálalo si necesitas conectar pods a varias redes físicas o VLANs (por ejemplo, mediante bridges y NADs).
**Instalación:**
```bash
kubectl apply -f https://raw.githubusercontent.com/k8snetworkplumbingwg/multus-cni/master/deployments/multus-daemonset.yml
```
**Verifica:**
```bash
kubectl get pods -n kube-system | grep multus
```
---
## 1.2 (Opcional) Quita el taint del nodo master para poder programar pods en él
Por defecto, Kubernetes no programa pods de usuario en el nodo principal (control-plane). Elimina este bloqueo para poder desplegar aplicaciones ahí.
```bash
kubectl taint nodes --all node-role.kubernetes.io/control-plane-
kubectl taint nodes --all node-role.kubernetes.io/master-
```
---
## 1.3 Crea el bridge físico en todos los nodos
Para que Multus pueda conectar pods a una red física o VLAN, debes crear un bridge Linux con el mismo nombre en **todos** los nodos del clúster. Ejemplo usando NetworkManager/nmcli:
```bash
# 1. Crear el bridge (br-srv) y ponerle IP si quieres conectividad L3
nmcli con add type bridge ifname br-srv con-name br-srv
nmcli con mod br-srv ipv4.addresses 192.168.200.1/22
nmcli con mod br-srv ipv4.method manual
nmcli con up br-srv
# 2. Crear la VLAN asociada (vlan20) sobre el bond
nmcli con add type vlan ifname vlan20 dev bond0 id 20 con-name vlan20
nmcli con mod vlan20 ipv4.method disabled ipv6.method ignore
nmcli con mod vlan20 master br-srv connection.slave-type bridge
nmcli con up vlan20
```
* **IMPORTANTE:** Repite en todos los nodos, y asigna una IP distinta del mismo rango a cada uno si es posible.
* El bridge debe estar **UP y con IP activa** para funcionar correctamente a nivel L2/L3.
---
## 1.4 Crea la NetworkAttachmentDefinition (NAD)
Ejemplo:
```yaml
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: br-srv
namespace: default
spec:
config: '{
"cniVersion": "0.3.1",
"type": "bridge",
"bridge": "br-srv",
"ipam": {
"type": "host-local",
"subnet": "192.168.200.0/22",
"rangeStart": "192.168.200.100",
"rangeEnd": "192.168.200.200"
}
}'
```
Despliega:
```bash
kubectl apply -f multus/nad-br-servicios.yaml
```
---
## 1.5 Despliega pods multi-homed de prueba
```yaml
apiVersion: v1
kind: Pod
metadata:
name: multus-test
annotations:
k8s.v1.cni.cncf.io/networks: br-srv
spec:
containers:
- name: alpine
image: alpine
command: ["sleep", "infinity"]
securityContext:
capabilities:
add: ["NET_ADMIN"]
```
---
## 1.6 Verifica la conectividad L2/L3 entre pods
```bash
kubectl exec -it multus-test -- sh
ip a
```
* Deberías ver dos interfaces: una de Flannel (eth0) y una de la red secundaria (net1).
* **IMPORTANTE:** Si el bridge físico (`br-srv`) está up pero SIN IP, la conectividad entre pods en nodos diferentes **NO funcionará**. Los bridges deben tener una IP asignada y activa.
### **¿Por qué es necesario que el bridge tenga IP?**
* El bridge sólo se comporta como una red L2 completa entre nodos cuando está “activo”, es decir, con una IP asociada en todos los hosts.
* Si no tiene IP, sólo funcionará el tráfico entre pods del mismo nodo (unicast y broadcast entre nodos puede no funcionar).
* Al asignar una IP al bridge, Linux activa la tabla ARP y gestiona correctamente los vecinos y el reenvío entre interfaces del bridge.
---
## 1.7 Limpieza de recursos
```bash
kubectl delete pod multus-test
kubectl delete pod multus-test2
kubectl delete -f multus/nad-br-servicios.yaml
```
---
## 1.8 Ejemplo de estructura de archivos
```
multus/
├── nad-br-servicios.yaml
├── test-multus-pod.yaml
├── test-multus-pod2.yaml
└── readme.md
```
---
## 1.9 Resumen rápido
* Multus + bridge = pods multi-homed en redes físicas.
* El bridge **debe estar vivo y con IP** en todos los nodos.
* Sin IP en el bridge, no hay tráfico entre pods en nodos distintos.
* Puedes crear tantas NAD como bridges/VLANs requieras.
---
# 2. Instalación y configuración de MetalLB (LoadBalancer local)
MetalLB permite asignar IPs flotantes de tu red LAN a servicios `LoadBalancer`, igual que hacen los clústeres en la nube. Es fundamental si quieres exponer servicios como ingress, dashboards, etc., accesibles desde tu red local.
---
## 2.1 Instalar MetalLB
```bash
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.14.5/config/manifests/metallb-native.yaml
```
Esto crea el namespace `metallb-system` y despliega los pods necesarios.
---
## 2.2 Habilitar `strictARP` en kube-proxy (obligatorio en L2)
Para evitar problemas de **ARP flapping** y garantizar que solo el nodo que anuncia la IP responda a las peticiones ARP, es necesario activar `strictARP` en kube-proxy.
```bash
kubectl -n kube-system edit configmap kube-proxy
```
En la sección `config.conf` busca la línea `strictARP` y cámbiala a:
```yaml
strictARP: true
```
Guarda y reinicia kube-proxy:
```bash
kubectl -n kube-system rollout restart daemonset kube-proxy
```
---
## 2.3 Eliminar la etiqueta que excluye los nodos de anunciar LoadBalancer
Por defecto, Kubernetes etiqueta los nodos `control-plane` con:
```text
node.kubernetes.io/exclude-from-external-load-balancers
```
Esto impide que MetalLB anuncie servicios desde esos nodos.
Para eliminarla de todos los nodos:
```bash
kubectl label node --all node.kubernetes.io/exclude-from-external-load-balancers-
```
Verifica que ya no aparece:
```bash
kubectl get nodes -L node.kubernetes.io/exclude-from-external-load-balancers
```
---
## 2.4 Definir un pool con múltiples rangos
En lugar de crear múltiples `IPAddressPool` por separado, puedes declarar varios rangos de IP en un **solo** `IPAddressPool`.
**Ejemplo: `metallb/ipaddresspool.yaml`**
```yaml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: pool-general
namespace: metallb-system
spec:
addresses:
- 192.168.1.100-192.168.1.110 # Rango 1: producción
- 192.168.2.100-192.168.2.110 # Rango 2: laboratorio
```
**Ejemplo: `metallb/l2advertisement.yaml`**
```yaml
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: advert-general
namespace: metallb-system
spec: {}
```
**Kustomization:**
```yaml
resources:
- ipaddresspool.yaml
- l2advertisement.yaml
```
Para aplicar:
```bash
kubectl apply -k metallb/
```
---
## 2.5 Asignar una IP concreta al Service (`loadBalancerIP`)
Puedes indicar directamente la IP deseada usando el campo `loadBalancerIP`.
### ✅ Ejemplo 1: Asignación explícita con `loadBalancerIP`
```yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-prod
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
type: LoadBalancer
loadBalancerIP: 192.168.1.105 # IP concreta del pool
```
### ✅ Ejemplo 2: Sin IP explícita (MetalLB elige una disponible)
```yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-lab
spec:
selector:
app: nginx
ports:
- port: 8080
targetPort: 80
type: LoadBalancer
```
---
## 2.6 Verificar el funcionamiento
Prueba con el manifiesto `test-lb.yaml`:
```bash
kubectl apply -f test-lb.yaml
kubectl -n lb-test get svc test-lb -w
```
Salida esperada:
```
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
test-lb LoadBalancer 10.104.58.240 192.168.1.100 80:30248/TCP 9s
```
Cuando termines:
```bash
kubectl delete -f test-lb.yaml
```
---
## 📜 Notas importantes
- Puedes declarar varios rangos en un solo `IPAddressPool`.
- No necesitas anotaciones para indicar qué pool usar si especificas directamente una IP con `loadBalancerIP`.
- Es buena práctica versionar todos los manifiestos en una carpeta `metallb/` dentro de tu repo Git.
- El uso de múltiples pools por separado sigue siendo válido, pero es innecesario si no quieres asignar pools por nombre con anotaciones.