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.
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 abcd
Kubernetes 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:8001
usar 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.