Mejores prácticas de gestión de clusters

Descubra las mejores prácticas para gestionar clusters que ha creado Container Engine for Kubernetes (OKE).

Esta sección contiene las mejores prácticas para la gestión de clusters y Container Engine for Kubernetes.

Mejores prácticas: uso de etiquetas de Kubernetes

Le recomendamos que utilice etiquetas de Kubernetes para organizar los diversos recursos de Kubernetes (como servicios, pods, contenedores, redes) que componen un cluster.

Las etiquetas de Kubernetes son pares clave-valor que le ayudan a mantener estos recursos y a realizar un seguimiento de cómo interactúan entre sí en un cluster.

Por ejemplo, puede utilizar oci.oraclecloud.com/oke-is-preemptible=true label (que Container Engine for Kubernetes aplica a los nodos de trabajador alojados en instancias preferentes) con selectores de nodos de Kubernetes y afinidad/antiafinidad de nodos para controlar qué pods están programados en esos nodos de trabajador.

Consulte Etiquetas, anotaciones y marcas conocidas en la documentación de Kubernetes.

Mejores prácticas: uso del etiquetado de recursos de OCI

Recomendamos utilizar el etiquetado de recursos de OCI para organizar los muchos recursos (como nodos de trabajador, redes virtuales en la nube, equilibradores de carga y volúmenes en bloque) que utilizan los clusters de Kubernetes que crea con Container Engine for Kubernetes. Cuando hay un gran número de recursos distribuidos en varios compartimentos de un arrendamiento, puede resultar difícil realizar un seguimiento de los recursos utilizados para fines específicos. Del mismo modo, puede resultar difícil agregar los recursos, generar informes sobre ellos y realizar acciones masivas sobre ellos.

El etiquetado permite definir claves y valores y asociarlos a recursos. A continuación, puede utilizar las etiquetas para organizar y mostrar los recursos según las necesidades de su empresa.

Consulte Etiquetado de recursos relacionados con cluster de Kubernetes.

Mejores prácticas: definición de solicitudes y límites de recursos

Se recomienda definir:

  • solicitudes de recursos, para especificar la cantidad mínima de recursos que un contenedor puede utilizar
  • límites de recursos, para especificar la cantidad máxima de recursos que un contenedor puede utilizar

Al trabajar con un cluster de Kubernetes, un desafío común es el fallo ocasional de una aplicación al desplegar en un cluster debido a la disponibilidad limitada de recursos en ese cluster. El fallo se debe a que no se han definido las solicitudes de recursos y los límites de recursos.

Si no define límites y solicitudes de recursos, los pods de un cluster pueden empezar a utilizar más recursos de los necesarios. Si un pod comienza a consumir más CPU o memoria en un nodo, es posible que el programador de kube no pueda colocar nuevos pods en el nodo e incluso que el nodo en sí se bloquee.

Consulte Solicitudes y límites en la documentación de Kubernetes.

Mejores prácticas: reserva recursos para daemons del sistema operativo y Kubernetes

Recomendamos utilizar los indicadores de kubelet --kube-reserved y --system-reserved para reservar recursos de CPU y memoria para los daemons del sistema Kubernetes (como kubelet y container runtime) y los daemons del sistema operativo (como sshd y systemd), respectivamente. Por ejemplo:

  • --kube-reserved=cpu=500m,memory=1Gi
  • --system-reserved=cpu=100m,memory=100Mi

Los pod que se ejecutan en un nodo de trabajador pueden consumir todos los recursos de CPU y memoria disponibles y, por lo tanto, evitar que otros procesos esenciales (como los daemons del sistema operativo y Kubernetes) se ejecuten en el nodo. Cuando los daemons del sistema operativo y Kubernetes no se pueden ejecutar, el nodo de trabajador puede dejar de responder, ser inestable y bloquearse inesperadamente con una carga pesada.

Para evitar que los pods soliciten recursos que necesitan los daemons del sistema operativo y Kubernetes, incluya los indicadores de kubelet --kube-reserved y --system-reserved como opciones kubelet-extra-args en un script cloud-init personalizado. Para obtener más información y ver un ejemplo, consulte Ejemplo 4: Uso de un script cloud-init personalizado para reservar recursos para Kubernetes y daemons del sistema operativo.

Al utilizar el indicador de kubelet --kube-reserved para reservar una parte de los recursos de CPU y memoria de un nodo de trabajador para su uso por parte de los daemons del sistema Kubernetes, tenga en cuenta las siguientes recomendaciones:

  • La cantidad de recursos de CPU que recomendamos reservar para los daemons del sistema Kubernetes depende del número de núcleos de CPU en el nodo de trabajador, como se muestra en la siguiente tabla:
    Número de núcleos de CPU en el nodo de trabajador 1 2 3 4 5 Mayor que 5
    CPU recomendada para reservar, en milicore (m) 60 m 70 m 80 m 85 m 90 m 2,5 m adicionales por cada núcleo adicional en el nodo de trabajador
  • La cantidad de recurso de memoria que recomendamos reservar para los daemons del sistema Kubernetes depende de la cantidad de memoria en el nodo de trabajador, como se muestra en la siguiente tabla:
    Memoria en nodo de trabajador, en GiB 4 GiB 8 GiB 16 GiB 128 GiB Más de 128 GiB
    Memoria recomendada para reservar, en GiB 1 GiB 1 GiB 2 GiB 9 GiB 20 MiB adicionales por cada GiB adicional de memoria de nodo de trabajador

Al utilizar el indicador de kubelet --system-reserved para reservar una parte de los recursos de CPU y memoria de un nodo para su uso por parte de los daemons del sistema operativo, tenga en cuenta las siguientes recomendaciones:

  • La cantidad de recurso de CPU que recomendamos reservar para los daemons del sistema operativo (independientemente de la unidad de nodo) es de 100 m (milicore).
  • La cantidad de recurso de memoria que recomendamos reservar para los daemons del sistema operativo (independientemente de la unidad de nodo) es de 100 Mi (mebibytes).

Tenga en cuenta que es posible que nuestras recomendaciones de CPU y memoria para los indicadores de kubelet --kube-reserved y --system-reserved no sean óptimas para las cargas de trabajo que desea ejecutar, por lo que puede que necesite modificar los valores en consecuencia. También puede que necesite ajustar los valores a lo largo del tiempo.

Para ver la diferencia entre el total de recursos de un nodo de trabajador y los recursos del nodo que pueden utilizar las cargas de trabajo, ejecute el siguiente comando:

kubectl get node <NODE_NAME> -o=yaml | grep -A 6 -B 7 capacity

Salida de ejemplo:

  allocatable:
    cpu: 15743m
    ephemeral-storage: "34262890849"
    hugepages-1Gi: "0"
    hugepages-2Mi: "0"
    memory: 234972476Ki
    pods: "110"
  capacity:
    cpu: "16"
    ephemeral-storage: 37177616Ki
    hugepages-1Gi: "0"
    hugepages-2Mi: "0"
    memory: 257197372Ki
    pods: "110"

La diferencia entre la CPU y la memoria "capacidad" y "asignables" en la salida de ejemplo incluye las reservas de CPU y memoria para los daemons del sistema operativo y Kubernetes.

Nota

A partir de junio de 2024, las recomendaciones para las reservas de recursos de CPU y memoria para los daemons del sistema operativo y Kubernetes que se describen en esta sección se utilizan como valores por defecto para todas las imágenes de OKE, para todas las versiones de Kubernetes soportadas. Las recomendaciones también se utilizan como valores por defecto para todas las imágenes de plataforma para Kubernetes versión 1.30 y posteriores. Los valores por defecto se aplican tanto al especificar una imagen de OKE publicada en junio de 2024 (o posterior) como al actualizar la versión de Kubernetes que se ejecuta en un cluster a la versión 1.30 (o posterior). Si especifica una imagen de OKE publicada en junio de 2024 (o posterior) o si actualiza un cluster a la versión 1.30 de Kubernetes, le recomendamos que compruebe que las reservas por defecto son adecuadas para las cargas de trabajo que desea ejecutar.

recomendaciones adicionales:

  • Antes de aplicar cambios de reserva a clusters de producción, realice siempre una referencia y pruebe el impacto de los cambios de reserva en un entorno que no sea de producción.
  • Utilice los indicadores de kubelet --eviction-hard o --eviction-soft para definir los umbrales adecuados para la memoria y la presión del disco. Al definir estos umbrales, el sistema Kubernetes puede proteger la estabilidad del sistema expulsando pods menos importantes cuando sea necesario. Para obtener más información, consulte Desalojo de presión de nodo en la documentación de Kubernetes.
  • Tenga en cuenta que si se reservan demasiados recursos, se puede infrautilizar los nodos. Su objetivo es encontrar un equilibrio adecuado entre garantizar la disponibilidad de recursos para componentes críticos y maximizar la disponibilidad de recursos para cargas de trabajo. Recomendamos que empiece con reservas de recursos más grandes y reduzca gradualmente los tamaños de reserva según la observación, en lugar de comenzar con reservas de recursos más pequeñas que son demasiado bajas y corren el riesgo de inestabilidad del sistema. Utilice métricas de herramientas de supervisión y alertas para observar el uso de recursos por parte de Kubernetes y los componentes del sistema a lo largo del tiempo.
  • Al reservar recursos, tenga en cuenta las diferencias en la unidad de nodo y el tipo de carga de trabajo. Los nodos grandes pueden requerir reservas absolutas más grandes que los nodos más pequeños. Las cargas de trabajo con necesidades de recursos específicas o patrones de repartición conocidos pueden requerir reservas de recursos mayores o menores.

Para obtener más información sobre cómo reservar recursos, consulte Reserva de recursos informáticos para daemons del sistema en la documentación de Kubernetes.

Mejores Prácticas: Proporcionar Nodos Dedicados Utilizando Tintas y Tolerancias

Le recomendamos que utilice las marcas y tolerancias de Kubernetes para limitar las aplicaciones que utilizan muchos recursos a nodos de trabajador específicos.

El uso de taints y tolerations permite mantener los recursos de nodo disponibles para las cargas de trabajo que los requieren y evita la programación de otras cargas de trabajo en los nodos.

Por ejemplo, al crear un cluster mediante Container Engine for Kubernetes, puede definir nodos de trabajador para que tengan una unidad de GPU o una unidad con un gran número de CPU potentes. Estos nodos de trabajador bien especificados son ideales para cargas de trabajo de procesamiento de datos de gran tamaño. Sin embargo, este hardware especializado suele ser costoso de implementar. Por lo tanto, normalmente se recomienda limitar las cargas de trabajo que se pueden programar en estos nodos. Para limitar las cargas de trabajo que se pueden programar en los nodos de trabajador bien especificados, agregue una mancha a los nodos. Por ejemplo, al ejecutar uno de los siguientes comandos:

  • kubectl taint nodes <node-name> special=true:NoSchedule
  • kubectl taint nodes <node-name> special=true:PreferNoSchedule

Después de agregar una mancha a los nodos de trabajador bien especificados, agregue una tolerancia correspondiente a los pods que desea permitir para utilizar los nodos.

Del mismo modo, puede utilizar oci.oraclecloud.com/oke-is-preemptible=true label (que Container Engine for Kubernetes se aplica a los nodos de trabajador alojados en instancias preferentes) con tolerancias de Kubernetes para controlar qué pods están programados en esos nodos de trabajador.

Consulte Etiquetas y tolerancias en la documentación de Kubernetes.

Mejores prácticas: control de la programación de pod mediante selectores de nodos y afinidad

Hay varias formas de restringir un pod para que se ejecute en nodos concretos o para especificar una preferencia para que un pod se ejecute en nodos concretos. Los enfoques recomendados utilizan todos los selectores de etiquetas para facilitar la selección. A menudo, el programador de kube hará automáticamente una colocación razonable sin tales restricciones o preferencias. Sin embargo, hay algunas circunstancias en las que puede que desee controlar el nodo en el que se ejecuta un pod.

En estas situaciones, se recomienda controlar la programación de pods en nodos mediante selectores de nodos de Kubernetes, afinidad de nodos y afinidad entre pods.

El uso de selectores de nodos, afinidad de nodos y afinidad entre pods permite al programador de kube aislar lógicamente cargas de trabajo, como por ejemplo por el hardware del nodo.

Por ejemplo, puede asignar a los nodos una etiqueta para indicar que tienen almacenamiento SSD conectado localmente. Para especificar que un pod se ejecute sólo en nodos con almacenamiento SSD conectado localmente, debe incluir esa etiqueta como selector de nodo en la especificación del pod. Kubernetes solo programa los pods en nodos con etiquetas coincidentes.

Consulte Asignación de pods a nodos en la documentación de Kubernetes.

Mejores prácticas: uso de herramientas de terceros para la copia de seguridad y la recuperación ante desastres

Recomendamos que utilice herramientas de terceros (como Kasten, Rancher, Trilio o Velero) con Container Engine for Kubernetes para la copia de seguridad y la recuperación ante desastres.

Las capacidades combinadas de copia de seguridad y recuperación ante desastres de estas herramientas y Container Engine for Kubernetes pueden proporcionar una plataforma de Kubernetes fiable, sólida y escalable lista para producción.

Consulte Una guía sencilla para la recuperación ante desastres de Kubernetes en regiones con Kasten by Veeam, por ejemplo.