Cuando se trabaja con Kubernetes usualmente nos enfocamos en la creación de pods y deployments y otros recursos (servicios, ingress, secrets, configmaps, etc) necesarios en nuestra aplicación. Se delega en el cluster de Kubernetes la orquestración de nuestras aplicaciones. Pocas veces debemos de interactuar directamente con los nodos, y mucho menos tener que acceder a los nodos directamente por medio de ssh.
Una razón para acceder a un nodo de Kubernetes por SSH, podría ser para verificar la existencia o contenido de algún archivo o configuración de manera directa. En mi caso, se montó un volumen de tipo hostPath y necesitaba verificar que los archivos realmente eran creados en el nodo.
Ahora bien, como acceder al nodo por ssh, y poder navegar en dicho nodo y ejecutar cualquier comando necesario. Podríamos intentar acceder directamente por medio de SSH, sin embargo para ello se necesita muchas veces una conexión segura entre nuestra máquina y la instancia del nodo. Si por ejemplo estamos usando EKS (Kubernetes en AWS) vamos a necesitar de SSH keys o algún tipo de infraestructura tipo Bastion para dicho propósito. Es por esto que muchas veces requerimos de alternativas menos complejas.
NSenter script
Este es un pequeño script que instala un pod en el cluster de kubernetes, esta imagen utiliza una nsenter
el cual es pequeño programa del paquete util-linux
, que nos permite hacer justo lo que necesitamos.
#!/bin/sh node=${1} nodeName=$(kubectl get node ${node} -o template --template='{{index .metadata.labels "kubernetes.io/hostname"}}') nodeSelector='"nodeSelector": { "kubernetes.io/hostname": "'${nodeName:?}'" },' podName=${USER}-nsenter-${node} kubectl run ${podName:?} --restart=Never -it --rm --image overriden --overrides ' { "spec": { "hostPID": true, "hostNetwork": true, '"${nodeSelector?}"' "tolerations": [{ "operator": "Exists" }], "containers": [ { "name": "nsenter", "image": "alexeiled/nsenter:2.34", "command": [ "/nsenter", "--all", "--target=1", "--", "su", "-" ], "stdin": true, "tty": true, "securityContext": { "privileged": true } } ] } }' --attach "$@"
Este script puede descargarse en nuestras más y al ejecutarlo le indicamos como parámetro el nombre del nodo en kubernetes al cual necesitamos acceder.
# get cluster nodes kubectl get nodes # output NAME STATUS ROLES AGE VERSION ip-192-168-151-104.us-west-2.compute.internal Ready <none> 8d v1.13.7-eks-c57ff8 ip-192-168-171-140.us-west-2.compute.internal Ready <none> 7d11h v1.13.7-eks-c57ff8 # open superuser shell on specified node ./nsenter-node.sh ip-192-168-151-104.us-west-2.compute.internal
Una vez el script corre, tenemos acceso al prompt desde el cual podemos visualizar el contenido del nodo indicado
# If you don't see a command prompt, try pressing enter. # prompt [root@ip-192-168-151-104 ~] ls
Kubectl-ssh plugin
Provider-agnostic way of opening a remote shell to a Kubernetes node. Enables you to access a node even when it doesn’t run an SSH server or when you don’t have the required credentials. Also, the way you log in is always the same, regardless of what provides the Kubernetes cluster (e.g. Minikube, Kind, Docker Desktop, GKE, AKS, EKS, …)
https://github.com/luksa/kubectl-plugins#kubectl-ssh-node
Basicamente, esta opción hace lo mismo que el script mencionado anteriormente, crea un pod en cluster de kubernetes y accede al nodo desde dicho pod por medio de utilidades de Linux. La diferencia es que este es un plugin instalado a kubectl
por lo cual lo accedemos diferente.
kubectl ssh node my-node # access a node in a multi-node cluster
Conclusiones
En lo particular prefiero la opción del script de nsenter-node.sh
ya que no require de instalación, y su uso es muy sencillo. Ambas opciones me permite acceder por shell al nodo indicado sin necesidad de SSH keys, VPN, Bastion, u otra infraestructura para acceder a los servidores que funcionan como nodo de Kubernetes.
Referencias:
- https://alexei-led.github.io/post/k8s_node_shell/
- https://medium.com/@marko.luksa/a-consistent-provider-agnostic-way-to-ssh-into-any-kubernetes-node-99328372d09f
- https://github.com/luksa/kubectl-plugins#kubectl-ssh-node