Jenkins Kubernetes Pod Template
El otro día nos encontramos con un problema no muy común con uno de nuestros clientes…
Resulta que algunas de las pipelines de Jenkins dejaron de funcionar ya que los nodos destinados a la ejecución de ciertas tareas, usaban nodos Kubernetes como ejecutores y se quedaban esperando que los pods encargados arrancaran:
[Pipeline] node Still waiting to schedule task All nodes of label ‘docker-build-xxxxxx’ are offline
Aquí os dejo un enlace con el plugin y su configuración por si os interesa usar esta gran funcionalidad
El problema
Decidimos entrar a inspeccionar los nodos de Kubernetes para revisar la ejecución de los pods del namespace destinado a estas tareas y la API de Kubernetes nos responde lo siguiente en todos los comandos que lanzamos desde nuestro kubectl:
Unable to authenticate the request due to an error: [x509: certificate has expired or is not yet valid, x509: certificate has expired or is not yet valid]
Bingo! resulta que el certificado de nuestro Kubernetes que se usa para el cliente kubectl y el etcd ha expirado. Esto representa un pequeño problema ya que para renovar un certificado en Kubernetes, utilizamos las conexiones a la API para hacerlo, pero estas llamadas requieren de tener un certificado válido.
Entonces qué hacemos??
Geko al rescate
Existe una solución que pasa por destruir los certificados a mano y con el comando kubeadm inicializarlos engañando al control plane para que crea que no existen certificados previos.
Nuestro consejo es mover todos los certificados a una carpeta temporal para luego forzar la inicialización de nuevos certificados y finalmente inicializar la config de todo el cluster de kubernetes
$ cd /etc/kubernetes/pki/ $ mkdir -p /tmp/oldcerts/etcd $ mv {apiserver.crt,apiserver-etcd-client.key,apiserver-kubelet-client.crt,front-proxy-ca.crt,front-proxy-client.crt,front-proxy-client.key,front-proxy-ca.key,apiserver-kubelet-client.key,apiserver.key,apiserver-etcd-client.crt} /tmp/oldcerts $ mv etcd/* /tmp/oldcerts/etcd $ kubeadm init phase certs all --apiserver-advertise-address $ cd /etc/kubernetes/ $ mv {admin.conf,controller-manager.conf,kubelet.conf,scheduler.conf} /tmp/oldcerts $ kubeadm init phase kubeconfig all $ reboot
Tras el reinicio, nuestro cluster habrá arrancado utilizando los nuevos certificados y ya podremos copiar las credenciales en nuestro directorio home o en nuestro sistema personal para poder hacer las llamadas a la API.
$ cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
Una vez copiado el config , ya podemos utilizar el cliente kubectl para conectar a nuestro K8S.
En nuestro caso eliminamos todos los pods huérfanos generados con jenkins en el namespace llamado «cicd»:
for docker in `kubectl get pods -n cicd | awk {'print $1'}`;do kubectl delete pod $docker -ncicd;done
Esperamos que os sirva para rescatar vuestro Kubernetes con certificados expirados! y recordar dejarnos vuestros comentarios…
Si os podemos ayudar con la configuración, incidencias o mejoras de vuestra plataforma Kubernetes, no dudéis en contactarnos.