Poner los nodos en modo de mantenimiento

Cuando necesites reparar o mantener nodos, primero debes poner los nodos en modo de mantenimiento. Esto vacía de forma correcta los Pods y las cargas de trabajo existentes, y excluye los Pods críticos del sistema, como el servidor de la API. El modo de mantenimiento también evita que el nodo reciba asignaciones de Pods nuevas. En el modo de mantenimiento, puedes trabajar en los nodos sin correr el riesgo de interrumpir el tráfico del Pod.

Cómo funciona

Google Distributed Cloud proporciona una forma de colocar nodos en modo de mantenimiento. Este enfoque permite que otros componentes del clúster sepan de forma correcta que el nodo está en modo de mantenimiento. Cuando colocas un nodo en modo de mantenimiento, no se pueden programar Pods adicionales en el nodo y los Pods existentes se detienen.

En lugar de usar el modo de mantenimiento, puedes usar de forma manual los comandos de Kubernetes, como kubectl cordon y kubectl drain, en un nodo específico.

Cuando usas el proceso del modo de mantenimiento, Google Distributed Cloud hace lo siguiente:

1.29

  • Google Distributed Cloud agrega el taint baremetal.cluster.gke.io/maintenance:NoSchedule a los nodos especificados para evitar la programación de Pods nuevos en el nodo.

  • Google Distributed Cloud usa la API de expulsión para expulsar cada Pod. Este método de vaciado de nodos respeta PodDisruptionBudgets (PDB). Puedes configurar los PDB para proteger tus cargas de trabajo mediante la especificación de un nivel tolerable de interrupción para un conjunto de Pods mediante los campos minAvailable y maxUnavailable. Desviar los nodos de esta manera proporciona una mejor protección contra las interrupciones de la carga de trabajo. El vaciado de nodos basado en la expulsión está disponible como DG para la versión 1.29.

  • Se aplica un tiempo de espera de 20 minutos para garantizar que los nodos no se detengan a la espera de que se detengan los Pods. Es posible que los Pods no finalicen si están configurados para tolerar a todos los taints o si tienen finalizadores. Google Distributed Cloud intenta detener todos los Pods, pero si se supera el tiempo de espera, el nodo se pone en modo de mantenimiento. Este tiempo de espera evita que la ejecución de Pods bloquee las actualizaciones.

1.28 y anteriores

  • Google Distributed Cloud agrega el taint baremetal.cluster.gke.io/maintenance:NoSchedule a los nodos especificados para evitar la programación de Pods nuevos en el nodo.

  • Google Distributed Cloud agrega el taint baremetal.cluster.gke.io/maintenance:NoExecute. En el taint NoExecute, el kube-scheduler de Google Distributed Cloud detiene los Pods y vacía el nodo. Este método de vaciado de nodos no respeta los PDB.

  • Se aplica un tiempo de espera de 20 minutos para garantizar que los nodos no se detengan a la espera de que se detengan los Pods. Es posible que los Pods no finalicen si están configurados para tolerar a todos los taints o si tienen finalizadores. Google Distributed Cloud intenta detener todos los Pods, pero si se supera el tiempo de espera, el nodo se pone en modo de mantenimiento. Este tiempo de espera evita que la ejecución de Pods bloquee las actualizaciones.

Vaciado basado en expulsiones

No hay cambios de procedimiento asociados con el cambio al vaciado de nodos basado en la expulsión del vaciado basado en taints. El cambio solo afecta la lógica de conciliación.

Esta función no se encuentra en la misma etapa de lanzamiento para todas las versiones compatibles:

  • 1.29: DG
  • 1.28: No disponible
  • 1.16: No disponible

Orden de vaciado

Antes de la versión 1.29, el desvío de nodos basado en taints que realiza kube-scheduler de Google Distributed Cloud no empleaba un algoritmo particular para desviar Pods de un nodo. Con el vaciado de nodos basado en la expulsión, los Pods se expulsan en un orden específico según la prioridad. La prioridad de expulsión se asocia con criterios de Pods específicos, como se muestra en la siguiente tabla:

Orden de vaciado Criterios de Pod (deben coincidir con todos) y
1

Se expulsan los Pods que coinciden con los siguientes criterios:

  • Pods sin spec.prorityClassName
  • Pods que no coinciden con ningún nombre conocido de Container Storage Interface (CSI)
  • Pods que no pertenecen a un DaemonSet
2

Se expulsan los Pods que coinciden con los siguientes criterios:

  • Pods que pertenecen a un DaemonSet
  • Los Pods no tienen PriorityClass
  • Pods que no coinciden con ningún nombre conocido de Container Storage Interface (CSI)
3

Se expulsan los Pods que coinciden con los siguientes criterios:

  • Pods con Spec.ProrityClassName
  • Pods que no coinciden con ningún nombre conocido de Container Storage Interface (CSI)

El orden de expulsión de los Pods coincidentes se basa en PriorityClass.value, de menor a mayor.

4

Espera a que CSI limpie las activaciones de PV/PVC después de que se expulsen todos los Pods. Usa Node.Status.VolumesInUse para indicar que se limpiaron todos los volúmenes.

5

Se expulsan los Pods que coinciden con los siguientes criterios:

  • Pods que coinciden con un nombre conocido de Container Storage Interface (CSI)

Estos Pods aún necesitan vaciarse, porque kubelet no proporciona compatibilidad de actualización in situ.

Debido a que el vaciado de nodos basado en la expulsión respeta los PDB, la configuración de PDB puede bloquear el vaciado de nodos en algunas circunstancias. Para obtener información sobre la solución de problemas sobre el vaciado de grupos de nodos, consulta Verifica por qué un nodo lleva mucho tiempo en estado de desvío.

Inhabilitar el vaciado de nodos basado en la expulsión

El vaciado de nodos basado en la expulsión está habilitado de forma predeterminada para los clústeres en la versión secundaria 1.29 o para los clústeres que se actualizan a la versión secundaria 1.29. Si el vaciado de nodos basado en la expulsión causa problemas con las actualizaciones o el mantenimiento del clúster, puedes volver al vaciado de nodos basado en taints si agregas la anotación baremetal.cluster.gke.io/maintenance-mode-ignore-pdb: true al recurso del clúster.

Coloca un nodo en modo de mantenimiento

Elige los nodos que deseas poner en modo de mantenimiento mediante la especificación de los rangos de IP para los nodos seleccionados en maintenanceBlocks en tu archivo de configuración del clúster. Los nodos que elijas deben estar listos y funcionando en el clúster.

Para poner los nodos en modo de mantenimiento, realiza lo siguiente:

  1. Edita el archivo de configuración del clúster para seleccionar los nodos que deseas poner en modo de mantenimiento.

    Puedes editar el archivo de configuración con el editor que prefieras o puedes editar el recurso personalizado del clúster de forma directa si ejecutas el siguiente comando:

    kubectl -n CLUSTER_NAMESPACE edit cluster CLUSTER_NAME
    

    Reemplaza lo siguiente:

    • CLUSTER_NAMESPACE: el espacio de nombres del clúster.
    • CLUSTER_NAME: el nombre del clúster
  2. Agrega la sección maintenanceBlocks al archivo de configuración del clúster a fin de especificar una sola dirección IP o un rango de direcciones para los nodos que deseas poner en modo de mantenimiento.

    En el siguiente ejemplo, se muestra cómo seleccionar varios nodos mediante la especificación de un rango de direcciones IP:

    metadata:
      name: my-cluster
      namespace: cluster-my-cluster
    spec:
      maintenanceBlocks:
        cidrBlocks:
        - 172.16.128.1-172.16.128.64
    
  3. Guarda y aplica la configuración actualizada del clúster.

    Google Distributed Cloud comienza a poner los nodos en modo de mantenimiento.

  4. Ejecuta el siguiente comando para obtener el estado de los nodos del clúster:

    kubectl get nodes --kubeconfig=KUBECONFIG
    

    El resultado es similar al siguiente:

    NAME                       STATUS   ROLES           AGE     VERSION
    user-anthos-baremetal-01   Ready    control-plane   2d22h   v1.27.4-gke.1600
    user-anthos-baremetal-04   Ready    worker          2d22h   v1.27.4-gke.1600
    user-anthos-baremetal-05   Ready    worker          2d22h   v1.27.4-gke.1600
    user-anthos-baremetal-06   Ready    worker          2d22h   v1.27.4-gke.1600
    

    Ten en cuenta que los nodos aún son programables, pero los taints evitan que se programen Pods (sin una tolerancia adecuada) en el nodo.

  5. Ejecuta el siguiente comando para obtener la cantidad de nodos en el modo de mantenimiento:

    kubectl get nodepools --kubeconfig ADMIN_KUBECONFIG 
    

    La respuesta debería ser similar al siguiente ejemplo:

    NAME   READY   RECONCILING   STALLED   UNDERMAINTENANCE   UNKNOWN
    np1    3       0             0         1                  0
    

    Esta columna UNDERMAINTENANCE en esta muestra que un nodo está en modo de mantenimiento.

    Google Distributed Cloud también agrega los siguientes taints a los nodos cuando se ponen en modo de mantenimiento:

    • baremetal.cluster.gke.io/maintenance:NoExecute
    • baremetal.cluster.gke.io/maintenance:NoSchedule

Quita un nodo del modo de mantenimiento

Para quitar nodos del modo de mantenimiento, realiza lo siguiente:

  1. Edita el archivo de configuración del clúster para borrar los nodos que deseas quitar del modo de mantenimiento.

    Puedes editar el archivo de configuración con el editor que prefieras o puedes editar el recurso personalizado del clúster de forma directa si ejecutas el siguiente comando:

    kubectl -n CLUSTER_NAMESPACE edit cluster CLUSTER_NAME
    

    Reemplaza lo siguiente:

    • CLUSTER_NAMESPACE: el espacio de nombres del clúster.
    • CLUSTER_NAME: el nombre del clúster
  2. Edita las direcciones IP para quitar nodos específicos del modo de mantenimiento o quita la sección maintenanceBlocks para quitar todos los nodos del modo de mantenimiento.

  3. Guarda y aplica la configuración actualizada del clúster.

  4. Usa los comandos kubectl para verificar el estado de los nodos.

Cierra y reinicia un clúster

Si es necesario cerrar un clúster completo, sigue las instrucciones de las siguientes secciones para apagar un clúster y volver a abrirlo de manera segura.

Cómo cerrar un clúster

Si vas a cerrar un clúster que administra clústeres de usuario, primero debes cerrar todos los clústeres de usuario administrados. Las siguientes instrucciones se aplican a todos los tipos de clústeres de Google Distributed Cloud.

  1. Verifica el estado de todos los nodos del clúster:

    kubectl get nodes --kubeconfig CLUSTER_KUBECONFIG
    

    Reemplaza CLUSTER_KUBECONFIG por la ruta de acceso del archivo kubeconfig para el clúster.

    El resultado es similar al siguiente:

    NAME        STATUS   ROLES           AGE    VERSION
    control-0   Ready    control-plane   202d   v1.27.4-gke.1600
    control-1   Ready    control-plane   202d   v1.27.4-gke.1600
    control-2   Ready    control-plane   202d   v1.27.4-gke.1600
    worker-0    Ready    worker          202d   v1.27.4-gke.1600
    worker-1    Ready    worker          202d   v1.27.4-gke.1600
    worker-2    Ready    worker          202d   v1.27.4-gke.1600
    worker-3    Ready    worker          202d   v1.27.4-gke.1600
    worker-4    Ready    worker          154d   v1.27.4-gke.1600
    worker-5    Ready    worker          154d   v1.27.4-gke.1600
    worker-6    Ready    worker          154d   v1.27.4-gke.1600
    worker-7    Ready    worker          154d   v1.27.4-gke.1600
    worker-8    Ready    worker          154d   v1.27.4-gke.1600
    worker-9    Ready    worker          154d   v1.27.4-gke.1600
    

    Si el STATUS de un nodo no es Ready, te recomendamos que soluciones los problemas del nodo y continúes solo cuando todos los nodos sean Ready.

  2. Si cierras un clúster de usuario, verifica el estado de los nodos del clúster de administrador:

    kubectl get nodes --kubeconfig ADMIN_KUBECONFIG
    

    Reemplaza ADMIN_KUBECONFIG por la ruta de acceso del archivo kubeconfig para el clúster de administración.

    Los pasos posteriores dependen del clúster de administrador. Si el STATUS de un nodo no es Ready, te recomendamos que soluciones los problemas del nodo y continúes solo cuando todos los nodos sean Ready.

  3. Verifica el estado del clúster que deseas cerrar:

    bmctl check cluster -c CLUSTER_NAME --kubeconfig ADMIN_KUBECONFIG
    

    Reemplaza lo siguiente:

    • CLUSTER_NAME: Es el nombre del clúster que verificas.

    • ADMIN_KUBECONFIG: Es la ruta de acceso del archivo kubeconfig para el clúster de administración.

    Corrige cualquier problema informado antes de continuar.

  4. Asegúrate de que todos los Pods etcd estén en ejecución en el clúster que vas a cerrar:

    kubectl get pods --kubeconfig CLUSTER_KUBECONFIG -A \
        -l component=etcd
    

    Reemplaza CLUSTER_KUBECONFIG por la ruta de acceso del archivo kubeconfig para el clúster.

    El resultado es similar al siguiente:

    NAMESPACE     NAME                   READY   STATUS    RESTARTS   AGE
    kube-system   etcd-control-0-admin   1/1     Running   0          2d22h
    kube-system   etcd-control-1-admin   1/1     Running   0          2d22h
    kube-system   etcd-control-2-admin   1/1     Running   0          2d22h
    

    Si el STATUS de un Pod no es Running, te recomendamos que soluciones los problemas del Pod y continúes solo cuando todos los Pods sean Running.

  5. Realiza una copia de seguridad como se describe en Cómo crear una copia de seguridad de un clúster.

    Es importante realizar una copia de seguridad de etcd antes de cerrar tu clúster para que se pueda restablecer si tienes algún problema cuando lo reinicias. Los daños de Etcd, las fallas de hardware del nodo, los problemas de conectividad de red y, posiblemente, otras condiciones pueden impedir que el clúster se reinicie de forma correcta.

  6. Si quieres cerrar un clúster con nodos trabajadores, coloca los nodos trabajadores en modo de mantenimiento.

    En este paso, se minimiza la cantidad de escritura en etcd, lo que reduce la probabilidad de que se deba conciliar una gran cantidad de escrituras de etcd cuando se reinicie el clúster.

  7. Coloca los nodos del plano de control en el modo de mantenimiento.

    Este paso evita las operaciones de escritura dañadas para las cargas de trabajo con estado durante el cierre del nodo.

  8. Apaga los nodos del clúster en la siguiente secuencia:

    1. Nodos trabajadores
    2. Nodos del balanceador de cargas del plano de control
    3. Nodos del plano de control, que comienzan con los seguidores de etcd y finalizan con el líder de etcd

      Si tienes un clúster de alta disponibilidad (HA), puedes encontrar el líder de etcd mediante SSH para conectarte a cada nodo del plano de control y ejecutar el siguiente comando de etcdctl:

      ETCDCTL_API=3 etcdctl \
          --cacert /etc/kubernetes/pki/etcd/ca.crt \
          --cert /etc/kubernetes/pki/etcd/server.crt \
          --key /etc/kubernetes/pki/etcd/server.key \
          --write-out=table endpoint status
      

      La respuesta incluye una columna IS LEADER, que muestra true si el nodo es el líder de etcd.

En este punto, tu clúster se apagará por completo. Después de realizar el mantenimiento necesario, puedes reiniciar tu clúster como se describe en la siguiente sección.

Reinicia el clúster

Usa los siguientes pasos para reiniciar un clúster que se desactivó por completo.

  1. Enciende las máquinas de nodos en el orden inverso de la secuencia de apagado.

  2. Quita los nodos del plano de control del modo de mantenimiento.

    Para obtener instrucciones, consulta Quita un nodo del modo de mantenimiento.

  3. Quita los nodos trabajadores del modo de mantenimiento.

  4. Ejecuta las verificaciones de estado del clúster para asegurarte de que funcione correctamente:

    bmctl check cluster -c CLUSTER_NAME --kubeconfig ADMIN_KUBECONFIG
    
  5. Si un problema, como el bucle de fallas de etcd, impide que el clúster se reinicie de forma correcta, intenta restablecerlo desde la última copia de seguridad segura conocida. Para obtener instrucciones, consulta Restablece un clúster.

Modo de facturación y mantenimiento

La facturación de Google Distributed Cloud se basa en la cantidad de CPU virtuales que tiene tu clúster para los nodos capaces de ejecutar cargas de trabajo. Cuando pones un nodo en modo de mantenimiento, se agregan los taints NoExecute y NoSchedule al nodo, pero no inhabilitan la facturación. Después de poner un nodo en modo de mantenimiento, acordona el nodo (kubectl cordon NODE_NAME) para marcarlo como no programable. Una vez que un nodo se marca como no programable, el nodo y sus CPU virtuales asociadas se excluyen de la facturación.

Como se describe en la página de precios, puedes usar kubectl para ver la capacidad de CPU virtual (que se usa para la facturación) de cada uno de los clústeres de usuario. El comando no considera si el nodo es programable o no, solo proporciona un recuento de CPU virtuales por nodo.

Para identificar la cantidad de CPU virtuales por nodo del clúster de usuario, haz lo siguiente:

kubectl get nodes \
    --kubeconfig USER_KUBECONFIG \
    -o=jsonpath="{range .items[*]}{.metadata.name}{\"\t\"} \
    {.status.capacity.cpu}{\"\n\"}{end}"

Reemplaza USER_KUBECONFIG por la ruta de acceso del archivo kubeconfig del clúster de usuario.