Tutoriales

Cómo reparar el espacio de nombres de Kubernetes atascado en estado terminado

Los espacios de nombres de Kubernetes aíslan recursos específicos del sistema que normalmente son visibles para todos los procesos. Cada espacio de nombres tiene sus propios servicios, pods e implementaciones en el clúster. Los espacios de nombres en Kubernetes son esencialmente los mismos que los proyectos en OpenShift.

Hoy en día, la mayoría de los productos están en contenedores y se pueden implementar fácilmente en Kubernetes u OpenShift. Esto requiere una implementación y pruebas continuas de la aplicación. He estado trabajando en la automatización de pruebas recientemente, lo que implica crear espacios de nombres, recursos y datos en espacios de nombres, luego ejecutar un conjunto de pruebas y luego eliminar datos y espacios de nombres una vez que se completan las pruebas.

Mientras creaba y eliminaba espacios de nombres con frecuencia en Kubernetes, me topé con un espacio de nombres atascado en terminación estado, simplemente se niega a eliminar.

Yo uso minikube para ejecutar Kubernetes localmente, pero puede usar los siguientes pasos y comandos en cualquier entorno de Kubernetes u OpenShift.

Nota: Los espacios de nombres de ejemplo en mis capturas de pantalla y comandos son tackle-operator.

Problema: eliminar espacio de nombres

A veces, el proceso de eliminación del espacio de nombres se atasca y el comando nunca se completa.Si bien el comando devuelve un mensaje de que se eliminó el espacio de nombres, consultarlo muestra que en realidad está en Terminating Expresar:

$ kubectl delete namespace tackle-operator
namespace "tackle-operator" deleted

$ kubectl get namespace
NAME               	   STATUS    	   AGE
default            	                Active    	   148d
ingress-nginx      	    Active    	   148d
kube-node-lease    	    Active    	   148d
kube-public        	    Active    	   148d
kube-system        	    Active    	   148d
kubernetes-dashboard   Active    	   148d
tackle-operator    	   Terminating       10d

Resulta que el espacio de nombres se eliminó, pero su estado muestra que no se ha ido por completo, aún puede ver el espacio de nombres en la interfaz de usuario de minikube.

Abierto tablero minikube dentro seleccionar espacio de nombres menú desplegable en la parte superior, aún puede seleccionar el espacio de nombres que cree que se ha eliminado.

(Shveta Sachdeva, CC BY-SA 4.0)

Puede intentar eliminarlo de la interfaz de usuario (UI).Para hacer esto, haga clic en los tres puntos que se muestran a la derecha del espacio de nombres y seleccione Eliminar.

Compruebe después de unos minutos (o días, meses, años). Todavía se muestra como terminado.

[ Ready to get started with containers quickly? Download the eBook OpenShift for Developers. ]

¿Por qué algunos espacios de nombres nunca se eliminan?

Kubernetes almacena cada espacio de nombres como un archivo YAML o JSON.

$ kubectl get namespace ${NAMESPACE} -o yaml
apiVersion: v1
kind: Namespace
metadata:
  annotations:
	kubectl.kubernetes.io/last-applied-configuration: |
	kubernetes.io/metadata.name: tackle-operator
spec:
  finalizers:
  - kubernetes
status:
  conditions:
 - lastTransitionTime: "2022-01-19T19:05:31Z"
	message: 'Some content in the namespace has finalizers remaining: tackles.tackle.io/finalizer in 1 resource instances'
	reason: SomeFinalizersRemain
	status: "True"
	type: NamespaceFinalizersRemaining
  phase: Terminating

Tenga en cuenta la inclusión del campo de finalizadores en el JSON anterior.Algunos espacios de nombres tienen un finalizador definido en spec.

Un finalizador es una clave de metadatos especial que le dice a Kubernetes que espere hasta que se cumplan ciertas condiciones antes de eliminar por completo el recurso.

Así que cuando ejecutas un comando como kubectl delete namespace abcdKubernetes está en metadata.finalizers sitio. Si el recurso definido en el finalizador no se puede eliminar por algún motivo, tampoco se eliminará el espacio de nombres. Esto pone el espacio de nombres en un estado terminado a la espera de eliminar los recursos, lo que nunca sucede.

Cuando un objeto ha sido terminado por mucho tiempo, verifíquelo revisando su finalizador metadata.finalizers campos en su YAML.

Eliminar espacio de nombres atascado en estado terminado

Una vez que comprenda la causa del problema, podrá entender por qué la solución es eliminar el finalizador de YAML. Un espacio de nombres solo se puede eliminar correctamente si se eliminan las restricciones que impiden que se elimine el espacio de nombres.

Sin embargo, hay algunas sutilezas en esta tarea. Por ejemplo, no puede simplemente editar el espacio de nombres YAML desde la interfaz de usuario de Kubernetes para eliminar el finalizador porque la interfaz de usuario no actualiza el espacio de nombres. Para ver esto, edite el espacio de nombres para eliminar el terminador y luego actualice. Edite el YAML nuevamente y notará que el finalizador todavía está allí.

[ Learn 16 steps for building production-ready Kubernetes clusters. ]

Esta es la forma correcta.

paso 1: Volcar el contenido del espacio de nombres en un archivo temporal llamado tmp.json:

$ kubectl get namespace ${NAMESPACE} -o json > tmp.json

Paso 2: Edite el archivo temporal en su editor de texto favorito (el mío es Vi):

$ vi tmp.json

Paso 3: eliminar Kubernetes de la matriz del finalizador y guarde el archivo. Ahora puede saltar al paso 4 a menos que esté utilizando OpenShift u OKD. Para esos, debe configurar un proxy temporal. Mantenga este terminal abierto hasta que se elimine el espacio de nombres.Inicie el servidor proxy en http://127.0.0.1:8001usar proxy Subcomando:

$ oc proxy

En una ventana separada, ejecute los siguientes comandos:

$ curl -k -H "Content-Type: application/json" -X PUT --data-binary @tmp.json http://127.0.0.1:8001/api/v1/namespaces/${PROJECT_NAME}/finalize

Etapa 4: Llame a la API de Kubernetes application/json contra esto /finalize Punto final del espacio de nombres para actualizar JSON. Utilice el número de puerto apropiado para su instancia. Estoy usando 44315 porque aquí es donde se ejecuta mi instancia de minikube:

$ curl -k -H "Content-Type: application/json" -X PUT --data-binary @tmp.json http://127.0.0.1:44315/api/v1/namespaces/${NAMESPACE}/finalize

Si no sabe qué puerto está usando su instancia de Kubernetes, mire la barra de URL de su navegador cuando navegue a la interfaz de usuario:

$ curl -k -H "Content-Type: application/json" -X PUT --data-binary @tmp.json http://127.0.0.1:44315/api/v1/namespaces/${NAMESPACE}/finalize
{
  "kind": "Namespace",
  "apiVersion": "v1",
  "metadata": {
	"name": "tackle-operator",
	"creationTimestamp": "2022-01-10T19:13:58Z",
	"deletionTimestamp": "2022-01-19T19:05:18Z",
  "status": {
	"phase": "Terminating",
	"conditions": [
  	{
    	"type": "NamespaceDeletionDiscoveryFailure",
    	"status": "False",
    	"lastTransitionTime": "2022-01-21T04:51:31Z",
    	"reason": "ResourcesDiscovered",
    	"message": "All resources successfully discovered"
  	},
  	{
    	"type": "NamespaceDeletionContentFailure",
    	"status": "False",
    	"lastTransitionTime": "2022-01-19T19:05:31Z",
    	"reason": "ContentDeleted",
    	"message": "All content successfully deleted, may be waiting on finalization"
  	},
}

Eso es. El tablero de minikube ya no muestra espacios de nombres:

$ kubectl get namespace ${NAMESPACE}
Error from server (NotFound): namespaces "${NAMESPACE}" not found

detener la terminación

En mis pruebas, creo y elimino espacios de nombres con frecuencia. Durante este tiempo, encontré el problema de que el espacio de nombres se atascaba en un estado terminado. Desarrollé un procedimiento simple para eliminar completamente los espacios de nombres. Espero que este proceso ayude a otros con el mismo problema.

Publicaciones relacionadas

Deja una respuesta

Tu dirección de correo electrónico no será publicada.

Botón volver arriba