TL;DR
En ciertos escenarios, los nodos de Kubernetes se benefician de contar con direcciones IP públicas estáticas dedicadas.
KubeIP, una utilidad de código abierto, cubre esa necesidad asignando IPs públicas estáticas a los nodos de Kubernetes. La última versión, KubeIP v2, amplía el soporte de GKE de Google Cloud a EKS de Amazon, con un diseño preparado para integrar otros proveedores de nube. Funciona como un DaemonSet, lo que aporta mayor confiabilidad, flexibilidad de configuración y facilidad de uso frente al método anterior basado en un controlador de Kubernetes. KubeIP v2 admite la asignación tanto de direcciones IPv4 como IPv6.
En este post profundizaremos en casos de uso concretos de KubeIP, lo compararemos con los cloud NAT gateways y exploraremos su arquitectura y configuración.
Casos de uso
KubeIP es útil en varios escenarios donde los nodos de Kubernetes necesitan IPs públicas estáticas.
Estos son algunos casos de uso comunes:
Aplicaciones de gaming
En escenarios de gaming, una consola puede necesitar una conexión directa con una VM en la nube para minimizar los saltos de red y la latencia. Asignar una IP pública dedicada al nodo que aloja el servidor de juego permite que la consola se conecte directamente. Esto puede mejorar la experiencia de juego al reducir la latencia y la pérdida de paquetes.
Whitelisting de IPs de agentes
Si tienes varios agentes o servicios corriendo en Kubernetes que requieren conexiones directas con un servidor externo, y ese servidor necesita autorizar las IPs de los agentes, usar KubeIP para asignar IPs públicas estables a los nodos vuelve más sencilla la gestión que habilitar rangos CIDR más amplios. Resulta especialmente útil cuando el servidor externo tiene controles de acceso estrictos basados en IP.
Evitar SNAT en pods específicos
Por defecto, a los pods se les asignan IPs privadas del rango CIDR de la VPC. Cuando se comunican con direcciones IPv4 externas, el plugin CNI de Amazon VPC traduce la IP del pod a la IP privada principal de la interfaz de red del nodo mediante SNAT (source network address translation).
A veces conviene evitar SNAT en ciertos pods para que los servicios externos vean las IPs reales de los pods. Esto se consigue asignando IPs públicas a los nodos con KubeIP y configurando hostNetwork: true en la especificación del pod. Así el pod puede comunicarse directamente con servicios externos usando la IP pública del nodo.
Conexiones entrantes directas y escenarios de red personalizados
Asignar IPs públicas a los nodos con KubeIP abre una variedad de escenarios de red. Por ejemplo, puedes redirigir tráfico directamente a los pods que corren en esos nodos, lo cual es útil cuando necesitas exponer servicios del nodo a Internet sin recurrir a un load balancer tradicional.
Un ejemplo sería ejecutar un servidor web en un pod y redirigir tráfico hacia él usando la IP pública del nodo.
Además, KubeIP sirve para implementar escenarios de red personalizados que requieran IPs públicas en los nodos. Por ejemplo, podrías crear un load balancer a medida que dirija tráfico a nodos específicos según la IP pública. Esta flexibilidad convierte a KubeIP en una herramienta potente para probar o desplegar soluciones de red personalizadas en Kubernetes.
Soporte de IPv6
KubeIP amplía su funcionalidad más allá de IPv4 al admitir también la asignación de direcciones IPv6 públicas estáticas a los nodos. Esta capacidad cobra cada vez más importancia conforme Internet avanza hacia IPv6 por el agotamiento de las direcciones IPv4.
Con el soporte de IPv6 en KubeIP, puedes asignar direcciones IPv6 públicas estáticas a tus nodos de Kubernetes para que se comuniquen directamente con servicios externos por IPv6. Esto resulta especialmente valioso para aplicaciones que requieren conectividad IPv6. Por ejemplo, si estás desarrollando o desplegando una aplicación que necesita soportar IPv6, puedes usar KubeIP para dar conectividad IPv6 a los pods que la ejecutan.
Además, IPv6 ofrece un espacio de direcciones más amplio, un formato de cabecera simplificado, mejor soporte para extensiones y opciones, mejor enrutamiento multicast y otras mejoras frente a IPv4.
Comparación con los cloud NAT gateways
Los NAT gateways son servicios gestionados en la nube que dan acceso saliente a Internet a los recursos de subredes privadas, traduciendo sus IPs privadas a IPs públicas. Están pensados para que los recursos de una red privada puedan iniciar conexiones salientes hacia Internet sin perder privacidad ni seguridad.
Sin embargo, los NAT gateways no admiten conexiones entrantes ni asignan IPs públicas directamente a los recursos. Es decir, son excelentes para ofrecer acceso saliente seguro, pero no están diseñados para escenarios que requieren conexiones entrantes o donde los recursos necesitan tener su propia IP pública.
KubeIP, en cambio, asigna IPs públicas estáticas directamente a los nodos de Kubernetes. Esto permite que las conexiones entrantes lleguen directamente a los pods que corren en esos nodos, redirigiendo el tráfico desde el nodo al pod. Resulta especialmente útil para aplicaciones que necesitan ser accesibles desde Internet o para escenarios de red personalizados.
Además, cuando hostNetwork está habilitado, los pods pueden iniciar conexiones salientes usando directamente la IP del host. Esto puede mejorar el rendimiento de red y simplificar el troubleshooting, aunque conviene usarlo con cuidado por las posibles implicaciones de seguridad.
En resumen, los NAT gateways son una excelente solución para acceso saliente seguro, mientras que KubeIP aporta flexibilidad y control adicionales sobre la conectividad entrante y saliente de pods y nodos específicos.
Comparación de costos: KubeIP vs. cloud NAT gateways
Hay varios factores que considerar al evaluar el costo de usar KubeIP frente a los cloud NAT gateways.
Costos de los cloud NAT gateways
Los cloud NAT gateways son un servicio gestionado, por lo que tienen un costo. Suele depender del volumen de datos procesados y del tiempo que el NAT gateway permanezca aprovisionado y disponible.
Por ejemplo, AWS cobra $0.045 por hora por un NAT gateway, más cargos por procesamiento de datos al momento de escribir esto. También se aplican los cargos estándar de transferencia de datos de AWS por todo el tráfico que pasa por el NAT gateway.
El modelo de Precios de Google Cloud NAT es similar.
Costos de KubeIP
KubeIP, por su parte, es una herramienta de código abierto, así que no hay costos directos asociados a su uso. Sin embargo, hay varios costos indirectos que conviene considerar:
- Direcciones IP públicas estáticas: tendrás que pagar por las IPs públicas estáticas que asignes a tus nodos. El costo varía según el proveedor de nube. Por ejemplo, AWS cobra $0.005 por hora por una Elastic IP, esté en uso o no. Google Cloud cobra el mismo monto por una IP estática.
- Transferencia de datos: aplican los cargos estándar de transferencia de datos por el tráfico que pasa por las IPs públicas estáticas asignadas. Estos costos dependerán de los Precios de transferencia de tu proveedor de nube.
- Workload adicional en el cluster: aunque KubeIP funciona como un DaemonSet y no consume muchos recursos en CPU y memoria, sigue siendo un workload adicional corriendo en tu cluster de Kubernetes. Esto podría afectar el rendimiento de otros workloads, sobre todo en clusters con recursos limitados. Aun así, en la mayoría de los casos el impacto es mínimo.
- Mantenimiento y soporte: al ser una herramienta de código abierto, KubeIP no incluye soporte dedicado. Cualquier mantenimiento, troubleshooting o actualización deberá gestionarlo tu equipo. Aunque esto no implica un costo directo, sí requiere tiempo y esfuerzo, lo que se traduce en un costo para tu organización.
En resumen, aunque KubeIP no tiene un costo directo, hay varios costos indirectos que considerar. Aun así, en muchos casos de uso, la flexibilidad y el control que ofrece KubeIP compensan estos costos.
Consideraciones de costo
Al evaluar la rentabilidad de KubeIP, es importante considerar tanto los costos directos como los indirectos. Estos incluyen el costo de las IPs públicas estáticas, los cargos por transferencia de datos, el posible impacto de ejecutar un workload adicional en tu cluster de Kubernetes y el tiempo y esfuerzo necesarios para mantenimiento y soporte.
Si bien KubeIP no tiene un costo directo, estos costos indirectos pueden sumar, sobre todo en clusters grandes. Sin embargo, la flexibilidad y el control que ofrece KubeIP pueden aportar un valor significativo, en especial para casos de uso que requieren conexiones entrantes directas o escenarios de red personalizados.
Los cloud NAT gateways, por su parte, son un servicio gestionado que simplifica la conectividad saliente para recursos en subredes privadas. Aunque tienen un costo asociado, incluyen ventajas como facilidad de uso, escalabilidad y confiabilidad.
En conclusión, la elección entre KubeIP y un cloud NAT gateway dependerá de tu caso de uso específico, del tamaño y los requisitos de tu cluster de Kubernetes y de tu presupuesto. Lo recomendable es calcular los costos en función de la transferencia de datos esperada, el número de nodos/IPs y las necesidades de mantenimiento para tomar una decisión informada.
Cómo funciona KubeIP
KubeIP corre como un DaemonSet en los nodos que elijas. En cada nodo:
- Descubre información sobre el nodo y el proveedor de nube mediante la Downward API de Kubernetes.
- Adquiere un lock a nivel de cluster para asegurar que solo un nodo asigne una IP a la vez, evitando race conditions y conflictos de IP.
- Selecciona una IP estática disponible del pool configurado mediante filtros y selectores.
- Asigna la IP a la interfaz de red principal del nodo usando la API del proveedor de nube.
- Si la asignación falla por un error, como una interrupción de red o un error de la API, KubeIP la reintenta hasta un límite configurado.
- Cuando se elimina un nodo, KubeIP libera la IP asignada y la devuelve al pool, dejándola disponible para otros nodos.
KubeIP admite direcciones IPv4 e IPv6, y se puede configurar para usar pools distintos para cada una. También admite pools de IPs personalizados para distintos nodos o grupos de nodos, lo que aporta flexibilidad en la gestión de IPs.
Arquitectura de KubeIP
KubeIP v2 está diseñado como un DaemonSet estándar de Kubernetes, lo que significa que se ejecuta en cada nodo del cluster.
Este diseño mejora la confiabilidad y la facilidad de uso frente al diseño anterior basado en un controlador. También simplifica el proceso de despliegue y garantiza que cada nodo obtenga una IP pública. Además, al aprovechar funciones estándar de Kubernetes como node selectors o node affinity, puedes controlar en qué nodos se despliega KubeIP. Esto permite un control granular sobre la asignación y asignar IPs públicas a nodos específicos según tus necesidades.
El diseño extensible de KubeIP v2 facilita la integración con otros proveedores de nube además de GKE y EKS, lo que lo convierte en una herramienta versátil para gestionar IPs públicas en entornos multicloud.
Configuración de KubeIP
KubeIP requiere una service account de Kubernetes con permisos para obtener nodos y gestionar leases.
Del lado de la nube, necesita un rol de IAM o una service account con permisos para asignar/desasignar y listar IPs públicas, así como para obtener información del nodo.
Aquí tienes un ejemplo de política IAM de AWS:
{
"Version": "2012-10-17",
"Statement": [\
{\
"Effect": "Allow",\
"Action": [\
"ec2:AssociateAddress",\
"ec2:DisassociateAddress",\
"ec2:DescribeInstances",\
"ec2:DescribeAddresses"\
],\
"Resource": "*"\
}\
]
}
Y un rol de IAM de Google Cloud:
title: "KubeIP Role"
description: "KubeIP required permissions"
stage: "GA"
includedPermissions:
- compute.instances.addAccessConfig
- compute.instances.deleteAccessConfig
- compute.instances.get
- compute.addresses.get
- compute.addresses.list
- compute.addresses.use
- compute.zoneOperations.get
- compute.subnetworks.useExternalIp
- compute.projects.get
Para seleccionar qué IPs usar, define filtros con la misma sintaxis que la CLI/API de la nube para listar IPs. Por ejemplo:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: kubeip
namespace: kube-system
spec:
selector:
matchLabels:
app: kubeip
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
template:
metadata:
labels:
app: kubeip
spec:
serviceAccountName: kubeip-service-account
terminationGracePeriodSeconds: 30
priorityClassName: system-node-critical
nodeSelector:
nodegroup: public
kubeip: "use"
tolerations:
- operator: "Exists"
effect: "NoSchedule"
- operator: "Exists"
effect: "NoExecute"
containers:
- name: kubeip
image: doitintl/kubeip-agent
imagePullPolicy: Always
resources:
requests:
cpu: "10m"
memory: "32Mi"
env:
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: LEASE_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: FILTER
value: "Name=tag:kubeip,Values=reserved;Name=tag:environment,Values=prod"
- name: LOG_LEVEL
value: "debug"
- name: LOG_JSON
value: "true"
Esto le indica a KubeIP en AWS que solo considere IPs con los tags kubeip=reserved y environment=prod.
El filtro de KubeIP en AWS admite la misma sintaxis que el comando
describe-addressesde AWS. Para más información, consulta describe-addresses. Si especificas varios filtros, se combinan con unAND, y la solicitud devuelve solo los resultados que cumplen todos los filtros indicados. Los filtros múltiples deben separarse con punto y coma (;).El filtro de KubeIP en Google Cloud admite la misma sintaxis que el comando
gcloud compute addresses listde Google Cloud. Para más información, consulta gcloud topic filter. Si especificas varios filtros, se combinan con unAND, y la solicitud devuelve solo los resultados que cumplen todos los filtros indicados. Los filtros múltiples deben separarse con punto y coma (;).
Pruébalo
El directorio examples contiene configuraciones de Terraform para levantar clusters de GKE y EKS con KubeIP desplegado.
Para ejecutarlo en EKS:
cd examples/aws
terraform init
terraform apply
Y en GKE:
cd examples/gcp
terraform init
# sin soporte de IPv6
terraform apply -var="project_id=<your-project-id>"
# con soporte de IPv6
terraform apply -var="project_id=<your-project-id>" -var="ipv6_support=true"
Esto aprovisionará un cluster con node pools públicos y privados, reservará algunas IPs estáticas y desplegará el DaemonSet de KubeIP configurado para usar las IPs reservadas.
Participa
Como proyecto de código abierto, ¡las contribuciones son bienvenidas! Envía pull requests, abre issues, ayuda con la documentación o corre la voz.
Con el soporte ampliado de proveedores de nube y el modelo simplificado de DaemonSet en la v2, nos entusiasma ver más casos de uso impulsados por KubeIP. Pruébalo en tu entorno y cuéntanos cómo te fue.
KubeIP v2 es una herramienta potente que aporta robustez y flexibilidad a la gestión de IPs públicas estáticas en clusters de Kubernetes, sea cual sea el proveedor de nube. Su capacidad única de asignar IPs públicas directamente a los nodos abre la puerta a múltiples posibilidades. Tanto si necesitas habilitar conexiones entrantes directas como facilitar escenarios de red personalizados, KubeIP v2 te respalda.
Una de las grandes fortalezas de KubeIP v2 es estar listo para el futuro de la conectividad en Internet. Admite direcciones IPv4 e IPv6, lo que asegura su vigencia conforme Internet sigue evolucionando. Además, su despliegue como DaemonSet no solo simplifica la configuración, sino que también mejora la confiabilidad.
KubeIP v2 también destaca por su flexibilidad. Con la posibilidad de desplegarlo en nodos específicos mediante funciones estándar de Kubernetes como node selectors o node affinity, obtienes un control granular sobre la asignación de IPs.
Si bien usar KubeIP conlleva costos, como los de las IPs públicas estáticas y los posibles cargos por transferencia de datos, suelen verse compensados por sus beneficios. La conectividad directa y la flexibilidad para atender requisitos de red únicos que ofrece KubeIP a menudo superan estos costos.
En conclusión, KubeIP v2 es mucho más que una herramienta para asignar IPs públicas estáticas. Es una solución integral que puede mejorar tu networking en Kubernetes, simplificar la gestión de IPs y abrir nuevas posibilidades para tus aplicaciones.