SSD Nodes Learn 🎉 VPS desde $5.50/mes
Guías Matt ConnorPor Matt Connor · Actualizado 2026-08-21

Cómo solucionar errores del puerto 10250 de kubelet

Corrige el error exacto "address already in use" durante kubeadm init y las reglas de firewall que bloquean kubectl logs, exec y metrics-server en TCP 10250.

Qué es el puerto 10250

El puerto 10250 es la API de kubelet. Todo error que lo menciona corresponde a uno de dos problemas opuestos. O bien otro proceso ya usa el puerto y kubeadm init no puede iniciarse. O bien nada puede alcanzar el puerto y kubectl logs y kubectl exec fallan contra un nodo que, por lo demás, parece estar en perfecto estado.

kubelet es el agente que Kubernetes ejecuta en cada nodo. Inicia contenedores e informa de su estado al plano de control. También escucha en TCP 10250 y proporciona una API HTTPS a la que llama el plano de control. El servidor de API abre una conexión con ese puerto cuando ejecuta kubectl logs, kubectl exec, kubectl attach o kubectl port-forward. metrics-server consulta /metrics/resource en el mismo puerto, lo que permite que kubectl top node funcione.

La API requiere autenticación. kubeadm desactiva el acceso anónimo y configura kubelet para usar la CA del clúster (autoridad certificadora). Por eso, una solicitud sin credenciales devuelve Unauthorized en lugar de proporcionar un shell dentro de uno de los contenedores. Recuerde este detalle, porque también es la forma más rápida de demostrar que se puede alcanzar el puerto. Si los puertos son un concepto nuevo para usted, qué es realmente un puerto en Linux explica el modelo que presupone esta guía.

Ambos modos de fallo se deben al mismo requisito. El puerto 10250 debe estar libre antes de que se inicie kubelet y debe ser accesible desde el plano de control una vez que esté en ejecución.

Qué problema de los dos tiene

Ejecute estos comandos en el nodo afectado. Todos los comandos siguientes debe ejecutarlos usted en su propio servidor.

sudo ss -lntp | grep 10250
sudo systemctl status kubelet --no-pager

ss -lntp muestra los sockets TCP en escucha y el proceso asociado a cada uno. -l indica que están en escucha, -n mantiene los puertos en formato numérico, -t limita la salida a TCP y -p muestra el proceso propietario. Esta última opción requiere root. De lo contrario, la columna del proceso aparece vacía y no obtiene información útil.

Una línea que termina en users:(("kubelet",pid=1043,fd=23)) indica que kubelet está en ejecución y ocupa el puerto. Si esperaba que el puerto estuviera libre, esa es la causa. Si ss no muestra ninguna salida y el plano de control todavía no puede comunicarse con este nodo, el firewall aún no interviene, porque ningún proceso está atendiendo el puerto. Averigüe por qué kubelet está detenido antes de modificar las reglas.

systemctl status kubelet muestra la otra parte del problema. active (running) con una hora de inicio de hace unos minutos es normal. Que kubelet se reinicie cada pocos segundos antes de ejecutar kubeadm init o kubeadm join también es normal: la unidad instalada se inicia durante la instalación, no encuentra ninguna configuración y termina. La documentación de Upstream indica que este bucle de fallos es el comportamiento esperado mientras kubelet espera a que kubeadm le indique qué debe hacer. Si no conoce bien el comportamiento de reinicio de systemd, consulte cómo funcionan los tipos de servicio y las políticas de reinicio de systemd, que proporciona el contexto de esta sección.

Por qué el puerto 10250 ya está en uso al ejecutar kubeadm init

kubeadm init ejecuta comprobaciones previas antes de escribir nada en el disco. Una de esas comprobaciones intenta enlazar cada puerto que necesita el plano de control. Si el enlace falla, kubeadm init se detiene y muestra un error que identifica el puerto 10250. No es un error del programa. kubeadm evita crear un segundo clúster sobre los restos del primero.

En la práctica, hay cuatro causas:

  • Un kubeadm init o kubeadm join anterior que falló durante la ejecución. kubelet ya recibió una configuración, por lo que está en ejecución y mantiene el puerto ocupado.
  • Un kubeadm reset que se inició pero no terminó. reset detiene kubelet, pero no deshabilita la unidad. Por eso, el siguiente reinicio vuelve a iniciar el proceso que escucha en el puerto.
  • k3s u otra distribución de Kubernetes instalada en el mismo servidor. k3s incluye kubelet, y ese kubelet también enlaza el puerto 10250.
  • El paquete kubelet, instalado como dependencia por apt e iniciado por su propia unidad de systemd, en un equipo donde todavía no se ha ejecutado kubeadm.

Determine cuál es la causa antes de cambiar nada:

sudo ss -lntp 'sport = :10250'
systemctl list-units --type=service --state=running | grep -Ei 'kubelet|k3s|k0s'

Si el proceso que escucha pertenece a k3s, deténgalo y decida qué clúster quiere utilizar. k3s y kubeadm no pueden compartir un servidor, porque usan los mismos puertos y el mismo directorio de CNI (interfaz de red de contenedores). El instalador de k3s deja un script de desinstalación en /usr/local/bin/k3s-uninstall.sh en un nodo de servidor y en k3s-agent-uninstall.sh en un nodo agente.

Por qué matar kubelet no libera el puerto

sudo pkill kubelet libera el puerto 10250 durante unos diez segundos. La unidad proporcionada incluye una política de reinicio, por lo que systemd inicia un kubelet nuevo y este vuelve a asociarse al mismo puerto. Puede ver la política directamente:

systemctl show kubelet -p Restart -p RestartSec
sudo systemctl stop kubelet
sudo ss -lntp | grep 10250

Restart=always con RestartSec=10 es la configuración incluida en la unidad. Por eso kill parece funcionar y después deja de hacerlo. systemctl stop es la forma correcta de liberar el puerto, porque systemd deja de reiniciar una unidad que se le ha indicado detener.

Liberar el puerto no basta en un nodo que todavía contiene parte de un clúster. /var/lib/kubelet/config.yaml, los certificados de /etc/kubernetes/pki y cualquier manifiesto de static pod en /etc/kubernetes/manifests siguen presentes. Las comprobaciones previas posteriores detectan esos archivos, y forzarlas deja un clúster cuyos certificados no coinciden con su configuración. Restablezca el nodo correctamente.

Restablecer el nodo correctamente

sudo kubeadm reset -f
sudo rm -rf /etc/cni/net.d
rm -rf $HOME/.kube
sudo systemctl stop kubelet
sudo ss -lntp | grep -E '10250|6443|2379'

-f omite la solicitud de confirmación. El restablecimiento intenta revertir los cambios realizados por init o join. Elimina los archivos y la configuración locales, elimina el miembro local de etcd en un nodo del plano de control, limpia los certificados de /etc/kubernetes/pki y elimina la configuración y los manifiestos de kubelet.

La documentación especifica qué elementos deja atrás el restablecimiento, y cada uno puede causar problemas. No limpia /etc/cni/net.d, por lo que la configuración antigua del complemento CNI permanece y el clúster nuevo la lee. Tampoco limpia las reglas de iptables, nftables o IPVS que kube-proxy aplicó al host. No modifica $HOME/.kube, por lo que kubectl sigue intentando comunicarse con un clúster que ya no existe y devuelve errores de certificado que parecen un problema nuevo.

Las reglas de paquetes que quedan son la parte más problemática. Vaciar las tablas manualmente también elimina las reglas instaladas por ufw, porque ufw en Ubuntu escribe mediante el mismo backend. El servidor queda sin filtrado hasta que se ejecuta sudo ufw reload. Si va a reconstruir el nodo, reinícielo después del restablecimiento. El reinicio elimina las reglas de ejecución añadidas por kube-proxy y requiere menos tiempo que corregir un conjunto de reglas vaciado parcialmente. Por qué las reglas de iptables y las reglas de nftables aparecen en la salida de la otra herramienta explica lo que ocurre internamente.

El último comando ss no debería mostrar ninguna salida. Si no hay ningún proceso escuchando en 10250, 6443 ni 2379, el nodo está listo para un kubeadm init nuevo.

Por qué kubectl logs y kubectl exec agotan el tiempo de espera en el puerto 10250

Esta es la queja opuesta y no se presenta como un problema de puertos. El clúster se inicia. Los nodos están Ready. Los pods se ejecutan. Después, un comando falla:

Error from server: Get "https://10.0.0.12:10250/containerLogs/default/web-0/web": dial tcp 10.0.0.12:10250: i/o timeout

Lea el mensaje desde el final. El servidor de API intentó abrir una conexión TCP con el nodo en el puerto 10250 y no recibió respuesta. i/o timeout significa que los paquetes se descartaron silenciosamente, por lo que algo los está filtrando: el firewall del host en el nodo o el firewall de red independiente de su proveedor, configurado en el panel de control. connect: connection refused en la misma posición significa lo contrario. El paquete llegó y no había ningún proceso escuchando, por lo que kubelet está detenido. Es el mismo par de causas descrito en conexión rechazada frente a conexión agotada, pero aquí se aplica a otro puerto.

Los nodos permanecen Ready durante todo este proceso porque el estado del nodo viaja en la otra dirección. kubelet se conecta hacia fuera al servidor de API en el puerto 6443 y envía su propio latido. Para ello no necesita ninguna conexión entrante en 10250. Por tanto, un puerto 10250 bloqueado permite que el clúster programe pods con normalidad, pero hace que fallen sólo los comandos de logs, exec, port-forward y las métricas.

kubectl top node que responde error: Metrics API not available es el mismo fallo observado a través de metrics-server, cuyo log indica el nodo y el puerto:

unable to fully scrape metrics from node worker-1: unable to fetch metrics from node worker-1: Get "https://10.0.0.12:10250/metrics/resource": dial tcp 10.0.0.12:10250: i/o timeout

Pruebe la ruta antes de editar cualquier regla de firewall

Ejecute esto desde un nodo del plano de control, contra la dirección del worker:

nc -zv 10.0.0.12 10250
curl -sk -o /dev/null -w '%{http_code}\n' https://10.0.0.12:10250/healthz

nc -z abre una conexión, la cierra e imprime succeeded! cuando el puerto acepta la conexión. La línea de curl es una prueba mejor porque demuestra que kubelet está atendiendo solicitudes, en lugar de demostrar únicamente que un puerto está abierto. Imprime 401. Ese es el resultado correcto: el protocolo de enlace TLS (seguridad de la capa de transporte) se completó y kubelet rechazó una solicitud no autenticada, que es exactamente lo que debe hacer. -k omite la comprobación del certificado, lo cual está bien porque está probando la ruta, no la cadena de confianza.

Una pausa larga que termina en un tiempo de espera agotado indica que los paquetes se están descartando. curl: (7) Failed to connect devuelto de inmediato indica que el puerto está cerrado en un host accesible. Pruebe desde el nodo del plano de control, no desde su portátil, porque el plano de control es la única máquina cuyo acceso importa en este caso.

Qué puertos necesita un plano de control y cuáles necesita un worker

Estos son los puertos entrantes que aparecen en la lista de upstream. En un nodo del plano de control, TCP 6443 corresponde al API server y debe estar abierto a todo lo que se ejecute en kubectl. TCP 2379 a 2380 corresponde a las API de cliente y de pares de etcd, y lo utilizan el API server y el propio etcd. TCP 10250 corresponde a la API de kubelet, y lo utilizan el propio nodo y el plano de control. TCP 10259 corresponde a kube-scheduler y TCP 10257 a kube-controller-manager. Ambos sólo los utiliza el propio nodo.

En un worker, TCP 10250 corresponde a la API de kubelet, y lo utilizan el propio nodo y el plano de control. TCP 10256 corresponde a kube-proxy, y lo utilizan el propio nodo y los load balancers que realizan comprobaciones de estado. TCP y UDP 30000 a 32767 corresponden a los servicios NodePort. Este es el intervalo predeterminado y debe ser accesible para quien necesite esos servicios.

El plugin CNI añade sus propios puertos a esta lista, pero no aparecen en ella. Flannel y Calico en modo VXLAN necesitan UDP 4789 entre los nodos. Calico con BGP necesita TCP 179. Consulte la documentación del plugin y abra esos puertos entre los nodos. De lo contrario, los pods de nodos distintos no podrán comunicarse aunque todos los puertos de esta sección estén abiertos.

Abrir 10250 sin exponerlo a Internet

La API de kubelet puede iniciar un proceso dentro de cualquier contenedor de ese nodo. Considere que un puerto 10250 abierto equivale a acceso root al nodo y restrínjalo por dirección de origen. Nunca permita el acceso desde cualquier origen.

sudo ufw allow from 10.0.0.0/24 to any port 10250 proto tcp comment 'kubelet API'
sudo ufw allow from 10.0.0.0/24 to any port 10256 proto tcp comment 'kube-proxy'
sudo ufw status numbered

Sustituya 10.0.0.0/24 por la red que comparten sus nodos. ufw status numbered muestra las reglas activas con un índice, de modo que puede eliminar una regla incorrecta con sudo ufw delete <number>. Conceptos básicos de ufw para un VPS explica las reglas de ordenación que determinan cuál de sus entradas se aplica realmente.

Un ajuste de ufw puede impedir que Kubernetes funcione. El tráfico de los pods que atraviesa el nodo se reenvía, no se entrega localmente, y ufw descarta los paquetes reenviados de forma predeterminada. Establezca DEFAULT_FORWARD_POLICY="ACCEPT" en /etc/default/ufw y ejecute sudo ufw reload. Sin este ajuste, el puerto 10250 puede quedar completamente abierto y el tráfico entre pods de distintos nodos seguirá fallando.

Compruebe también el firewall de su proveedor. La mayoría de los paneles de VPS tienen un firewall de red situado delante del servidor, que ufw status no puede ver. Una regla añadida en el nodo no cambia nada si el paquete nunca llega al servidor.

Cuando el puerto es accesible y la solicitud sigue fallando

Algunos fallos en 10250 se devuelven de inmediato en lugar de quedar bloqueados. Esto indica que la conexión se estableció y que se rechazó la solicitud. x509: certificate signed by unknown authority en el registro de metrics-server indica que kubelet está proporcionando un certificado autofirmado que el scraper no confía. Lo habitual es habilitar la rotación de certificados de servicio de kubelet para que la CA del clúster lo firme y después aprobar la solicitud de firma de certificado, o aceptar el riesgo en un clúster de laboratorio y ejecutar metrics-server con --kubelet-insecure-tls.

Un mensaje que contenga Forbidden junto con nodes/proxy o nodes/metrics indica un fallo de RBAC (control de acceso basado en roles). El llamador llegó a kubelet, kubelet preguntó al servidor de API si esa identidad podía usar el subrecurso y la respuesta fue negativa. Corrija el ClusterRole del llamador. Ningún cambio en el firewall resolverá el problema, porque no se bloqueó nada.

Si sólo necesita un clúster pequeño

Si encuentra estos errores al configurar kubeadm por primera vez en un único VPS, considere si realmente necesita kubeadm. Un clúster k3s de un solo nodo en un VPS le proporciona una API de Kubernetes funcional con un solo comando, con kubelet, kube-proxy y una CNI ya integrados. El puerto 10250 también existe en ese entorno y se le aplican las mismas reglas, pero ya no tiene que ensamblar el plano de control por su cuenta.

FAQ

¿Para qué se utiliza el puerto 10250 en Kubernetes?

Es la API HTTPS autenticada de kubelet en cada nodo, tanto en el plano de control como en los nodos worker. El servidor de API se conecta a ella para kubectl logs, kubectl exec, kubectl attach y kubectl port-forward. metrics-server consulta /metrics/resource en ese puerto para proporcionar kubectl top. El estado del nodo no utiliza este puerto, porque kubelet envía su heartbeat de salida al servidor de API por el puerto 6443. Por eso, bloquear 10250 hace que los nodos aparezcan como Ready, mientras que los registros y exec fallan.

¿Cómo averiguo qué está escuchando en el puerto 10250?

Ejecute sudo ss -lntp | grep 10250 en el nodo. El campo users:((...)) al final de la línea muestra el proceso y su PID. sudo es importante, porque sin root la columna del proceso aparece vacía. Si el propietario es kubelet, sudo systemctl status kubelet --no-pager indica si se trata de un kubelet activo o de uno que se reinicia en un bucle. Si el propietario es k3s, tiene dos distribuciones de Kubernetes instaladas en un mismo servidor y debe eliminar una.

¿Tengo que abrir el puerto 10250 en el firewall?

Sí, entre los nodos. El plano de control debe poder acceder al puerto 10250 de cada nodo, incluido él mismo. De lo contrario, los registros, exec, port-forward y las métricas fallan. Restrinja el acceso por origen a la red que comparten los nodos, por ejemplo sudo ufw allow from 10.0.0.0/24 to any port 10250 proto tcp. No lo abra a Internet: cualquier entidad que pueda autenticarse en ese puerto puede ejecutar un proceso en cualquier contenedor del nodo.

¿Por qué falla kubectl logs sólo con los pods de un nodo?

Porque el bloqueo afecta a un nodo concreto y el servidor de API se conecta al nodo específico que aloja el pod. Lea el texto del error: contiene la dirección IP del nodo al que intentó conectarse. Después, ejecute nc -zv <node-ip> 10250 desde un nodo del plano de control. Un tiempo de espera agotado apunta al firewall de ese nodo o al firewall de red de su proveedor. connection refused indica que kubelet no está ejecutándose allí, así que compruebe systemctl status kubelet en ese nodo.