驴Qu茅 hacer si los certificados est谩n podridos y el racimo se convierte en una calabaza?

Si en respuesta al comando kubectl get pod obtienes:

 Unable to connect to the server: x509: certificate has expired or is not yet valid 

entonces, muy probablemente, ha pasado un a帽o, los certificados de sus kubernetes han expirado, los componentes del cl煤ster han dejado de usarlos, la interacci贸n entre ellos se ha detenido y su cl煤ster se ha convertido en una calabaza.

imagen

驴Qu茅 hacer y c贸mo restaurar un cl煤ster?

Primero, debemos comprender d贸nde se encuentran los certificados que deben actualizarse.

Dependiendo de la forma en que se instal贸 el cl煤ster, la ubicaci贸n y el nombre de los archivos de certificado pueden variar. Entonces, por ejemplo, al crear un cl煤ster, Kubeadm descompone los archivos de certificado de acuerdo con las mejores pr谩cticas . Por lo tanto, todos los certificados se encuentran en el /etc/kuberenetes/pki , en archivos con la extensi贸n .crt , claves privadas, respectivamente, en los archivos .key . Adem谩s en /etc/kubernetes/ archivos .conf con configuraci贸n de acceso para el administrador de cuentas de usuario, controlador de administrador, sheduler y kubelet desde el nodo maestro. Los certificados en archivos .conf encuentran en el campo user.client-certificate-data en forma codificada en base64.

Puede ver la fecha de vencimiento a qui茅n se emiti贸 y qui茅n firm贸 el certificado utilizando este peque帽o script shcert

shcert
 #!/bin/bash [ -f "$1" ] || exit if [[ $1 =~ \.(crt|pem)$ ]]; then openssl x509 -in "$1" -text -noout fi if [[ $1 =~ \.conf$ ]]; then certfile=$(mktemp) grep 'client-certificate-data:' "$1"| awk '{ print $2}' | base64 -d > "$certfile" openssl x509 -in "$certfile" -text -noout rm -f "$certfile" fi 


Todav铆a hay certificados que usan kubelet en los nodos de trabajo para la autenticaci贸n en la API. Si us贸 kubeadm join para agregar nodos al cl煤ster, lo m谩s probable es que el nodo se haya conectado utilizando el procedimiento de arranque TLS , en cuyo caso kubelet puede renovar su certificado autom谩ticamente si se le da la opci贸n --rotate-certificates . En versiones recientes de kubernetes, esta opci贸n ya est谩 habilitada de forma predeterminada.
Verificar que el nodo est茅 conectado usando el procedimiento de arranque TLS es bastante simple: en este caso, el archivo /etc/kubernetes/kubelet.conf generalmente se especifica en el archivo de certificado del cliente en el archivo /var/lib/kubelet/pki/kubelet-client-current.pem que es un enlace simb贸lico al certificado actual.

Tambi茅n puede ver las fechas de vencimiento de este certificado utilizando el script shcert

Volvemos al problema de la renovaci贸n de certificados.

Si instal贸 el cl煤ster usando kubeadm, tengo buenas noticias para usted. A partir de la versi贸n 1.15, kubeadm puede actualizar casi todos los certificados de plano de control con un comando

 kubeadm alpha certs renew all 

Este comando renovar谩 todos los certificados en el directorio / etc / kubernetes, incluso si ya han expirado y todo se ha roto.

Solo el certificado de kubelet no se actualizar谩; este es el que se encuentra en el archivo /etc/kubernetes/kubelet.conf .
Actualizaci贸n: kubeadm, a partir de la versi贸n 1.17, incluye en todos los nodos (incluso en el primer asistente donde se realiz贸 kubeadm init) la renovaci贸n autom谩tica del certificado culet. La comprobaci贸n es muy simple: en /etc/kubernetes/kubelet.conf ruta al archivo /var/lib/kubelet/pki/kubelet-client-current.pem se indicar谩 en el campo del certificado del cliente

Para renovar este certificado, use el comando crear cuenta de usuario

 kubeadm alpha kubeconfig user --client-name system:node:kube.slurm.io --org system:nodes > /etc/kubernetes/kubelet.conf 

Si el sistema tiene una cuenta de usuario, este comando actualiza el certificado de esta cuenta. No olvide especificar el nombre de host correcto en la opci贸n --client-name , puede ver --client-name nombre de host en el campo Asunto de un certificado existente:

 shcert /etc/kubernetes/kubelet.conf 

Y, por supuesto, despu茅s de actualizar los certificados, debe reiniciar todos los componentes del plano de control, reiniciar todo el nodo o detener los contenedores con etcd, api, controlador-administrador y planificador con el docker stop , y luego reiniciar kubelet systemctl restart kubelet .

Si su cl煤ster tiene una versi贸n anterior: 1.13 o menos, simplemente no funcionar谩 para actualizar kubeadm a 1.15, ya que arrastra las dependencias de kubelet y kubernetes-cni, lo que puede causar problemas, ya que el rendimiento de los componentes del cl煤ster difiere en las versiones en m谩s de uno escenario, no garantizado. La forma m谩s f谩cil de salir de esta situaci贸n es instalar kubeadm en otra m谩quina, tomar el archivo binario /usr/bin/kubeadm , copiarlo en los nodos maestros del cl煤ster fallecido y usarlo solo para renovar certificados. Y despu茅s de revitalizar el cl煤ster, actual铆celo paso a paso utilizando m茅todos regulares, instalando kubeadm una versi贸n m谩s nueva cada vez.

Y finalmente, de la versi贸n 1.15, kubeadm aprendi贸 c贸mo renovar todos los certificados al actualizar un cl煤ster con el kubeadm upgrade . Entonces, si actualiza regularmente su cl煤ster al menos una vez al a帽o, sus certificados siempre ser谩n v谩lidos.

Pero si el cl煤ster no est谩 instalado usando kubeadm, entonces deber谩 recoger openssl y renovar todos los certificados individualmente.

El problema es que los certificados contienen campos extendidos y diferentes herramientas de instalaci贸n de cl煤ster pueden agregar su propio conjunto de campos. Adem谩s, los nombres de estos campos en la configuraci贸n de openssl y en la salida del contenido del certificado est谩n correlacionados, pero de forma d茅bil. Es necesario googlear y seleccionar.

Dar茅 una configuraci贸n de ejemplo para openssl, en secciones separadas de las cuales se describen los atributos extendidos, espec铆ficos para cada tipo de certificado. Nos referiremos a la secci贸n correspondiente al crear y firmar csr. Esta configuraci贸n se utiliz贸 para revitalizar el grupo establecido hace un a帽o por el ranchero.

openssl.cnf
 [req] distinguished_name = req_distinguished_name req_extensions = v3_req [v3_req] keyUsage = nonRepudiation, digitalSignature, keyEncipherment extendedKeyUsage = clientAuth [client] keyUsage = critical,digitalSignature, keyEncipherment extendedKeyUsage = clientAuth [apiproxyclient] keyUsage = critical,digitalSignature, keyEncipherment extendedKeyUsage = clientAuth, serverAuth [etcd] keyUsage = critical,digitalSignature, keyEncipherment extendedKeyUsage = clientAuth, serverAuth subjectAltName = @alt_names [api] keyUsage = critical,digitalSignature, keyEncipherment extendedKeyUsage = clientAuth, serverAuth subjectAltName = @alt_names [alt_names] DNS.1 = ec2-us-east-1-1a-c1-master-2 DNS.2 = ec2-us-east-1-1a-c1-master-3 DNS.3 = ec2-us-east-1-1a-c1-master-1 DNS.4 = localhost DNS.5 = kubernetes DNS.6 = kubernetes.default DNS.7 = kubernetes.default.svc DNS.8 = kubernetes.default.svc.cluster.local IP.1 = 10.0.0.109 IP.2 = 10.0.0.159 IP.3 = 10.0.0.236 IP.4 = 127.0.0.1 IP.5 = 10.43.0.1 


Los atributos reales y los nombres adicionales en el certificado se pueden ver con el comando

 openssl x509 -in cert.crt -text 

Al renovar el certificado para la API del servidor, tuve un problema: el certificado actualizado no funcionaba. La soluci贸n fue emitir un certificado que fuera v谩lido por 1 a帽o en el pasado.

En openssl, no puede emitir un certificado v谩lido en el pasado con un comando simple, el c贸digo establece estrictamente que el certificado es v谩lido solo desde el momento actual. Pero puede retroceder localmente en el tiempo usando la biblioteca libfaketime

 yum install libfaketime LD_PRELOAD=/usr/lib64/faketime/libfaketime.so.1 FAKETIME="-365d" openssl x509 -req ... 

Emitimos certificados extendidos de acuerdo con el siguiente algoritmo:

Creamos una CSR utilizando un certificado existente, especifique la secci贸n deseada con una lista de atributos avanzados en el archivo de configuraci贸n:

 openssl x509 -x509toreq -in "node.cert" -out "node.csr" -signkey "node.key" -extfile "openssl.cnf" -extensions client 

Lo firmamos con el certificado ra铆z correspondiente, cambiando el tiempo hace 1 a帽o y especificando la secci贸n deseada con una lista de atributos avanzados en el archivo de configuraci贸n

 LD_PRELOAD=/usr/lib64/faketime/libfaketime.so.1 FAKETIME="-365d" openssl x509 -req -days 36500 -in "node.csr" -CA "kube-ca.pem" -CAkey "kube-ca-key.pem" -CAcreateserial -out "node.new.cert" -extfile "openssl.cnf" -extensions client 

Verificamos los atributos y reiniciamos los componentes del plano de control.

Sergey Bondarev,
Profesor slurm
slurm.io

Source: https://habr.com/ru/post/465733/


All Articles