Los nodos son un componente vital de un clúster de Kubernetes y son responsables de ejecutar las pods. Dependiendo de la configuración de tu clúster, un nodo puede ser una máquina física o virtual.
Un clúster típicamente tiene uno o varios nodos, los cuales son gestionados por el control plane
.
Debido a que los nodos realizan la mayor parte del trabajo de la gestión de carga, es importante asegurarse de que todos tus nodos estén funcionando correctamente. El comando kubectl get nodes
se utiliza para verificar el estado de tus nodos.
NAME STATUS ROLES AGE VERSION
controlplane Ready control-plane 2d11h v1.29.0
node01 Ready <none> 2d10h v1.29.0
Un nodo con un estado NotReady
significa que no se puede utilizar para ejecutar una pod debido a un problema interno.
Posibles razones por las cuales un nodo puede entrar en el estado NotReady y cómo depurarlo.
Estados
Antes de programar un pod en un nodo, Kubernetes verifica si el nodo es capaz de ejecutar la pod o no. La columna STATUS en la salida de kubectl get nodes
representa el estado.
NAME STATUS ROLES AGE VERSION
controlplane Ready control-plane 2d10h v1.29.0
node01 Ready <none> 2d10h v1.29.0
Los posibles valores en STATUS
son:
-
Ready
: El nodo está listo para aceptar pods. -
NotReady
: El nodo ha encontrado algún problema y no se puede programar un pod en él. -
SchedulingDisabled
: El nodo está marcado como no programable. Esta marca se puede realizar mediante el comandokubectl cordon
. -
Unknown
: El nodo no es alcanzable por elcontrol plane
.
Tener un nodo en estado NotReady
significa que el nodo está sin usar y sin participar en la ejecución de pods.
Posibles causas del estado NotReady
:
-
Escasez de recursos. Para operar normalmente, un nodo debe tener suficiente espacio en disco, memoria y capacidad de procesamiento. Si un nodo tiene poco espacio en disco o la memoria disponible es baja, entrará en el estado
NotReady
. Si hay demasiados procesos ejecutándose en el nodo, también cambiará al estado "NotReady". -
Configuración de red incorrecta. Si la red no se ha configurado correctamente en el nodo, el nodo no podrá comunicarse con el nodo maestro y se mostrará como
NotReady
. -
Problemas con el proceso
kubelet
. Kubelet es un componente esencial de Kubernetes y opera en cada nodo del clúster como un agente. Su papel principal es servir de enlace entre el nodo y la API de Kubernetes.Kubelet
informa a la API de Kubernetes sobre el estado del nodo, incluyendo detalles como los recursos disponibles y la salud general del nodo. Además,Kubelet
registra el nodo en el clúster de Kubernetes, permitiendo que el nodo sea reconocido y utilizado para desplegar aplicaciones. SiKubelet
se bloquea o se detiene por alguna razón, su comunicación con la API de Kubernetes se interrumpe. Esto impide que el nodo informe de su estado y reciba instrucciones de la API. Como resultado, el nodo se marca con el estadoNotReady
, lo que indica que NO está preparado para recibir nuevas cargas de trabajo hasta que se resuelva el problema deKubelet
. -
Problemas con Kube-proxy. Kube-proxy es un componente de Kubernetes y opera en cada nodo como un proxy. Mantiene las reglas de red que facilitan la comunicación con los pods, tanto interna como externamente. Si
kube-proxy
se bloquea o se detiene, el nodo se marca comoNotReady
. -
Problemas específicos del proveedor cloud. Supongamos que estás utilizando una solución alojada en la nube como GKE, EKS, AKS, .... En ese caso, algunos problemas específicos del proveedor pueden estar impidiendo que tus nodos funcionen normalmente y se comuniquen con el
control plane
. Estos problemas podrían ser por una configuración incorrecta de IAM, por reglas de red mal configuradas, etc.
Debug del estado NotReady
mas detallado
El estado NotReady
puede ser causado por una multitud de problemas. Es esencial entender que la forma de solucionar estos problemas depende de la causa exacta y de la configuración del clúster.
No hay soluciones universales. Pero, una vez que identifiques la causa raíz, debería ser más fácil resolverla.
Problemas Kube-Proxy
Asegúrate que cada nodo tenga un pod kube-proxy
y esté en el estado "Running".
kubectl get pods -n kube-system -o wide
resultado:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
calico-kube-controllers-9d57d8f49-8smt7 1/1 Running 3 (4h30m ago) 2d10h 192.168.0.2 controlplane <none> <none>
canal-mpvd7 2/2 Running 2 (4h30m ago) 2d10h 172.30.2.2 node01 <none> <none>
canal-t59ms 2/2 Running 2 (4h30m ago) 2d10h 172.30.1.2 controlplane <none> <none>
coredns-86b698fbb6-7dhfx 1/1 Running 1 (4h30m ago) 2d10h 192.168.1.2 node01 <none> <none>
coredns-86b698fbb6-c7h4v 1/1 Running 1 (4h30m ago) 2d10h 192.168.1.3 node01 <none> <none>
etcd-controlplane 1/1 Running 2 (4h30m ago) 2d10h 172.30.1.2 controlplane <none> <none>
kube-apiserver-controlplane 1/1 Running 2 (4h30m ago) 2d10h 172.30.1.2 controlplane <none> <none>
kube-controller-manager-controlplane 1/1 Running 2 (4h30m ago) 2d10h 172.30.1.2 controlplane <none> <none>
kube-proxy-4rlmh 1/1 Running 2 (4h30m ago) 2d10h 172.30.1.2 controlplane <none> <none>
kube-proxy-8whxf 1/1 Running 1 (4h30m ago) 2d10h 172.30.2.2 node01 <none> <none>
kube-scheduler-controlplane 1/1 Running 2 (4h30m ago) 2d10h 172.30.1.2 controlplane <none> <none>
o más especifico para todos los kubeproxy:
kubectl get pods -n kube-system -o wide | grep kube-proxy
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kube-proxy-4rlmh 1/1 Running 2 (4h31m ago) 2d10h 172.30.1.2 controlplane <none> <none>
kube-proxy-8whxf 1/1 Running 1 (4h31m ago) 2d10h 172.30.2.2 node01 <none> <none>
Si alguno de los pods kube-proxy
se encuentra en un estado diferente a Running
, utiliza el siguiente comando para obtener más información:
kubectl describe pod POD_KUBEPROXY_EN_ESTADO_NO_RUNNING -n kube-system
La sección de "Events" registra diversos eventos en el pod, y podría ser un excelente lugar para comenzar a buscar cualquier inconveniente.
Puedes acceder a los logs del pod ejecutando el siguiente comando:
kubectl logs POD_KUBEPROXY_EN_ESTADO_NO_RUNNING -n kube-system
Si el nodo que no esta Ready
NO tiene pod kube-proxy
, entonces debes inspeccionar el daemonset kube-proxy
.
Un daemonset
es una forma de asegurar que todos los nodos en un clúster tengan una copia de un pod corriendo, el daemonset
se encarga automáticamente de asegurar que haya una copia de ese pod en cada nodo del clúster.
kubectl describe daemonset kube-proxy -n kube-system
resultado:
Name: kube-proxy
Selector: k8s-app=kube-proxy
Node-Selector: kubernetes.io/os=linux
Labels: k8s-app=kube-proxy
Annotations: deprecated.daemonset.template.generation: 1
Desired Number of Nodes Scheduled: 2
Current Number of Nodes Scheduled: 2
Number of Nodes Scheduled with Up-to-date Pods: 2
Number of Nodes Scheduled with Available Pods: 2
Number of Nodes Misscheduled: 0
Pods Status: 2 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
Labels: k8s-app=kube-proxy
Service Account: kube-proxy
Containers:
kube-proxy:
Image: registry.k8s.io/kube-proxy:v1.29.0
Port: <none>
Host Port: <none>
Command:
/usr/local/bin/kube-proxy
--config=/var/lib/kube-proxy/config.conf
--hostname-override=$(NODE_NAME)
Environment:
NODE_NAME: (v1:spec.nodeName)
Mounts:
/lib/modules from lib-modules (ro)
/run/xtables.lock from xtables-lock (rw)
/var/lib/kube-proxy from kube-proxy (rw)
Volumes:
kube-proxy:
Type: ConfigMap (a volume populated by a ConfigMap)
Name: kube-proxy
Optional: false
xtables-lock:
Type: HostPath (bare host directory volume)
Path: /run/xtables.lock
HostPathType: FileOrCreate
lib-modules:
Type: HostPath (bare host directory volume)
Path: /lib/modules
HostPathType:
Priority Class Name: system-node-critical
Events: <none>
Problemas Recursos
El siguiente comando sirve para obtener información detallada sobre un nodo:
kubectl describe node NODO_NOT_READY
resultado:
Name: node01
Roles: <none>
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/arch=amd64
kubernetes.io/hostname=node01
kubernetes.io/os=linux
Annotations: flannel.alpha.coreos.com/backend-data: {"VNI":1,"VtepMAC":"f6:5a:70:e7:20:39"}
flannel.alpha.coreos.com/backend-type: vxlan
flannel.alpha.coreos.com/kube-subnet-manager: true
flannel.alpha.coreos.com/public-ip: 172.30.2.2
kubeadm.alpha.kubernetes.io/cri-socket: unix:///var/run/containerd/containerd.sock
node.alpha.kubernetes.io/ttl: 0
projectcalico.org/IPv4Address: 172.30.2.2/24
projectcalico.org/IPv4IPIPTunnelAddr: 192.168.1.1
volumes.kubernetes.io/controller-managed-attach-detach: true
[...]
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason Message
---- ------ ----------------- ------------------ ------ -------
NetworkUnavailable False Sun, 31 Dec 2023 18:57:52 +0000 Sun, 31 Dec 2023 18:57:52 +0000 FlannelIsUp Flannel is running on this node
MemoryPressure False Sun, 31 Dec 2023 23:37:39 +0000 Fri, 29 Dec 2023 13:10:41 +0000 KubeletHasSufficientMemory kubelet has sufficient memory available
DiskPressure False Sun, 31 Dec 2023 23:37:39 +0000 Fri, 29 Dec 2023 13:10:41 +0000 KubeletHasNoDiskPressure kubelet has no disk pressure
PIDPressure False Sun, 31 Dec 2023 23:37:39 +0000 Fri, 29 Dec 2023 13:10:41 +0000 KubeletHasSufficientPID kubelet has sufficient PID available
Ready True Sun, 31 Dec 2023 23:37:39 +0000 Fri, 29 Dec 2023 13:10:50 +0000 KubeletReady kubelet is posting ready status. AppArmor enabled
Addresses:
InternalIP: 172.30.2.2
Hostname: node01
Capacity:
cpu: 1
ephemeral-storage: 20134592Ki
hugepages-2Mi: 0
memory: 2030940Ki
pods: 110
Allocatable:
cpu: 1
ephemeral-storage: 19586931083
hugepages-2Mi: 0
memory: 1928540Ki
pods: 110
System Info:
Machine ID: 388a2d0f867a4404bc12a0093bd9ed8d
System UUID: 1d3e87e7-ec41-400e-9e8a-9fbba2d3adc8
Boot ID: 0f813b78-e5d3-4cca-b969-763745e13991
Kernel Version: 5.4.0-131-generic
OS Image: Ubuntu 20.04.5 LTS
Operating System: linux
Architecture: amd64
Container Runtime Version: containerd://1.6.12
Kubelet Version: v1.29.0
Kube-Proxy Version: v1.29.0
PodCIDR: 192.168.1.0/24
PodCIDRs: 192.168.1.0/24
Non-terminated Pods: (4 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits Age
--------- ---- ------------ ---------- --------------- ------------- ---
kube-system canal-mpvd7 25m (2%) 0 (0%) 0 (0%) 0 (0%) 2d10h
kube-system coredns-86b698fbb6-7dhfx 50m (5%) 0 (0%) 50Mi (2%) 170Mi (9%) 2d10h
kube-system coredns-86b698fbb6-c7h4v 50m (5%) 0 (0%) 50Mi (2%) 170Mi (9%) 2d10h
kube-system kube-proxy-8whxf 0 (0%) 0 (0%) 0 (0%) 0 (0%) 2d10h
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
Resource Requests Limits
-------- -------- ------
cpu 125m (12%) 0 (0%)
memory 100Mi (5%) 340Mi (18%)
ephemeral-storage 0 (0%) 0 (0%)
hugepages-2Mi 0 (0%) 0 (0%)
Events: <none>
En la sección Conditions
muestra si el nodo se está quedando sin recursos o no. Posibles estados:
- MemoryPressure: Si es Verdadero, indica que el nodo se está quedando sin memoria.
- DiskPressure: Si es Verdadero, indica que al nodo le falta espacio.
- PIDPressure: Si es Verdadero, indica que hay demasiados procesos en ejecución en el nodo.
- NetworkUnavailable: Si es Verdadero, indica que la red del nodo no está configurada correctamente.
- Ready: Un valor Falso en este campo es equivalente al estado
NotReady
. Si el controlador del nodo no ha tenido noticias delnode-monitor-grace-period
(por defecto, 40 segundos), el valor seráUnknown
.
Si alguna de las primeras cuatro condiciones es Verdadera, habrás identificado el problema.
Problemas Kubelet
Si todos los campos de Conditions
estan en Unknown
, podría indicar que kubelet
esta caido.
Para realizar debug, primero accede por SSH al nodo y verifica el estado del proceso kubelet.
Si se está ejecutando como un servicio de systemd, utiliza el siguiente comando:
systemctl status kubelet
resultado:
● kubelet.service - kubelet: The Kubernetes Node Agent
Loaded: loaded (/lib/systemd/system/kubelet.service; enabled; vendor preset: enabled)
Drop-In: /usr/lib/systemd/system/kubelet.service.d
└─10-kubeadm.conf
Active: active (running) since Sun 2023-12-31 18:56:43 UTC; 4h 48min ago
Docs: https://kubernetes.io/docs/
Main PID: 1650 (kubelet)
Tasks: 11 (limit: 2338)
Memory: 61.6M
CGroup: /system.slice/kubelet.service
└─1650 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/>
Si el campo Active
muestra "inactive (dead)", significa que el proceso kubelet se ha detenido.
Para descubrir la posible razón del fallo, verifica los logs con el siguiente comando:
journalctl -u kubelet
Una vez que has realizado fix, reinicia el kubelet con:
systemctl restart kubelet
Problemas conectividad
Si Conditions
muestra NetworkUnavailable
, indica un problema en la comunicación de red entre el nodo y la API Kubernetes.
Algunas posibles soluciones:
- Si el nodo está configurado para usar un proxy, verifica que el proxy permita el acceso a los endpoints de la API Kubernetes.
- Asegúrate de que las tablas de enrutamiento estén configuradas adecuadamente para evitar bloquear la comunicación con la API Kubernetes.
Para obtener la dirección de la API, ejecuta:
kubectl cluster-info
resultado:
Kubernetes control plane is running at https://172.30.1.2:6443
CoreDNS is running at https://172.30.1.2:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
Puedes ejecutar el siguiente comando desde dentro del nodo para verificar que pueda alcanzar el servidor API:
nc -vz IP_CONTROL_PLANE_O_ENDPOINT PUERTO
resultado:
Connection to 172.30.1.2 6443 port [tcp/*] succeeded!
Si el resultado es succeeded
, la comunicacion de red funciona correctamente.
Top comments (0)