10 mejores prácticas de Kubernetes para una mejor orquestación de contenedores

Hablemos de algunas de las mejores prácticas que se deben seguir al usar Kubernetes.

Kubernetes es una plataforma de orquestación de contenedores de código abierto que automatiza la implementación de contenedores, el escalado y desescalado continuos, el equilibrio de carga de contenedores y muchas cosas más.

Dado que la contenedorización se usa en muchos servidores de producción con miles de contenedores, se vuelve muy importante administrarlos bien, y eso es lo que hace Kubernetes.

Si usa Kubernetes, debe adoptar las mejores prácticas para una mejor orquestación de contenedores.

Aquí hay una lista de algunas de las mejores prácticas de Kubernetes que debe seguir.

#1. Establecer solicitudes de recursos y límites

Cuando está implementando una aplicación grande en un clúster de producción con recursos limitados donde los nodos se quedan sin memoria o CPU, la aplicación dejará de funcionar. Este tiempo de inactividad de la aplicación puede tener un gran impacto en el negocio. Pero puede resolver esto al tener solicitudes y límites de recursos.

Las solicitudes y los límites de recursos son los mecanismos de Kubernetes para controlar el uso de recursos como la memoria y la CPU. Si un pod consume toda la CPU y la memoria, los otros pods se quedarán sin recursos y no podrán ejecutar la aplicación. Por lo tanto, debe establecer solicitudes de recursos y límites en los pods para aumentar la confiabilidad.

Solo para su información, el límite siempre será más alto que la solicitud. Su contenedor no se ejecutará si su solicitud supera el límite definido. Puede establecer solicitudes y límites para cada contenedor en un pod. La CPU se define mediante milicores y la memoria se define mediante bytes (megabyte/mebibyte).

A continuación se muestra un ejemplo de cómo establecer un límite de CPU de 500 milicores y 128 mebibytes, y establecer una cuota para solicitudes de 300 milicores de CPU y 64 mebibytes.

containers:
- name: prodcontainer1
    image: ubuntu
    resources:
        requests:
            memory: “64Mi”
            cpu: “300m”
        limits:                              
            memory: “128Mi”
            cpu: “500m”

#2. Use livenessProbe y readinessProbe

Los controles de salud son muy importantes en Kubernetes.

Proporciona dos tipos de controles de salud: Preparación sondas y vivacidad sondas

Las pruebas de preparación se utilizan para verificar si la aplicación está lista para comenzar a servir tráfico o no. Esta sonda debe pasar en Kubernetes antes de que comience a enviar el tráfico al pod que ejecuta la aplicación dentro de un contenedor. Kubernetes dejará de enviar el tráfico al pod hasta que falle esta verificación de estado de preparación.

Las sondas de actividad se utilizan para verificar si la aplicación aún se está ejecutando (viva) o se ha detenido (muerta). Si la aplicación funciona correctamente, Kubernetes no hace nada. Si su aplicación está muerta, Kubernetes lanzará un nuevo pod y ejecutará la aplicación en él.

Si estas comprobaciones no se realizan correctamente, es posible que los pods se cancelen o que comiencen a recibir las solicitudes de los usuarios incluso antes de que estén listos.

Hay tres tipos de sondas que se pueden utilizar para las comprobaciones de actividad y preparación: HTTP, Mando, y TCP.

Permítame mostrarle un ejemplo del más común que es la sonda HTTP.

Aquí su aplicación tendrá un servidor HTTP dentro. Cuando Kubernetes hace ping en una ruta al servidor HTTP y obtiene una respuesta HTTP, marcará que la aplicación está en buen estado; de lo contrario, no lo estará.

apiVersion: v1
kind: Pod
metadata:
 name: container10
spec:
 containers:
   - image: ubuntu
     name: container10
     livenessProbe:
       httpGet:
         path: /prodhealth
         port: 8080

#3. Crear imágenes de contenedores pequeños

Es preferible usar imágenes de contenedor más pequeñas porque requiere menos almacenamiento y podrá extraer y crear las imágenes más rápido. Dado que el tamaño de la imagen será más pequeño, las posibilidades de ataques de seguridad también serán menores.

Hay dos formas de reducir el tamaño del contenedor: usar una imagen base más pequeña y un patrón de construcción. Actualmente, la última imagen base de NodeJS tiene 345 MB, mientras que la imagen alpina de NodeJS tiene solo 28 MB, más de diez veces más pequeña. Por lo tanto, utilice siempre las imágenes más pequeñas y agregue las dependencias necesarias para ejecutar su aplicación.

Para mantener las imágenes del contenedor aún más pequeñas, puede usar un patrón de construcción. El código se construye en el primer contenedor y luego el código compilado se empaqueta en el contenedor final sin todos los compiladores y herramientas necesarios para hacer el código compilado, lo que hace que la imagen del contenedor sea aún más pequeña.

#4. Otorgar niveles seguros de acceso (RBAC)

Tener un clúster de Kubernetes seguro es muy importante.

El acceso al clúster debe estar bien configurado. Debe definir la cantidad de solicitudes por usuario por segundo/minuto/hora, las sesiones simultáneas permitidas por dirección IP, el tamaño de la solicitud y el límite de rutas y nombres de host. Esto ayudará a mantener el clúster seguro frente a los ataques DDoS.

Los ingenieros desarrolladores y DevOps que trabajan en un clúster de Kubernetes deben tener un nivel de acceso definido. La característica de control de acceso basado en roles (RBAC) de Kubernetes es útil aquí. Puede utilizar Roles y ClusterRoles para definir los perfiles de acceso. Para facilitar la configuración de RBAC, puede usar administradores de rbac de código abierto disponibles para ayudarlo a simplificar la sintaxis o usar Rancher, proporciona RBAC de forma predeterminada.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cluster-role
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list"]

Los secretos de Kubernetes almacenan información confidencial, como tokens de autenticación, contraseñas y claves ssh. Nunca debe verificar los secretos de Kubernetes en el repositorio de IaC, de lo contrario, estará expuesto a aquellos que tienen acceso a su repositorio de git.

DevSecOps es una palabra de moda ahora que habla de DevOps y seguridad. Las organizaciones están adoptando la tendencia porque entienden la importancia de la misma.

#5. Mantenerse al día

Se recomienda tener siempre instalada la última versión de Kubernetes en el clúster.

La última versión de Kubernetes incluye nuevas funciones, actualizaciones de funciones anteriores, actualizaciones de seguridad, correcciones de errores, etc. Si está utilizando Kubernetes con un proveedor de la nube, actualizarlo se vuelve muy fácil.

#6. Usar espacios de nombres

Kubernetes envía tres espacios de nombres diferentes: por defecto, sistema kube, y kube-público.

Estos espacios de nombres juegan un papel muy importante en un clúster de Kubernetes para la organización y seguridad entre los equipos.

Tiene sentido usar el espacio de nombres predeterminado si es un equipo pequeño que trabaja solo entre 5 y 10 microservicios. Pero un equipo en rápido crecimiento o una organización grande tendrá varios equipos trabajando en un entorno de prueba o producción, por lo que cada equipo debe tener un espacio de nombres separado para facilitar la administración.

Si no lo hacen, pueden terminar sobrescribiendo o interrumpiendo accidentalmente la aplicación/función de otro equipo sin siquiera darse cuenta. Se sugiere crear múltiples espacios de nombres y usarlos para segmentar sus servicios en partes manejables.

Este es un ejemplo de creación de recursos dentro de un espacio de nombres:

apiVersion: v1
kind: Pod
metadata:
   name: pod01
namespace: prod
   labels:
      image: pod01
spec:
   containers:
- name: prod01
  Image: ubuntu

#7. Usar etiquetas

A medida que crezcan sus implementaciones de Kubernetes, invariablemente incluirán múltiples servicios, pods y otros recursos. Hacer un seguimiento de estos puede volverse engorroso. Aún más desafiante puede ser describir Kubernetes cómo interactúan estos diversos recursos, cómo desea que se repliquen, escalen y mantengan. Las etiquetas en Kubernetes son muy útiles para resolver estos problemas.

Las etiquetas son pares clave-valor que se utilizan para organizar elementos dentro de la interfaz de Kubernetes.

Por ejemplo, aplicación: kube-app, fase: prueba, rol: front-end. Se utilizan para describir a Kubernetes cómo funcionan juntos varios objetos y recursos dentro del clúster.

apiVersion: v1
kind: Pod
metadata:
 name: test-pod
 labels:
   environment: testing
   team: test01
spec:
 containers:
   - name: test01
     image: "Ubuntu"
     resources:
       limits:
        cpu: 1

Por lo tanto, puede reducir el dolor de la producción de Kubernetes etiquetando siempre los recursos y objetos.

#8. Registro de auditoría

Para identificar amenazas en el clúster de Kubernetes, la auditoría de registros es muy importante. La auditoría ayuda a responder preguntas como qué sucedió, por qué sucedió, quién hizo que sucediera, etc.

Todos los datos relacionados con las solicitudes realizadas a kube-apiserver se almacenan en un archivo de registro llamado audit.log. Este archivo de registro está estructurado en formato JSON.

En Kubernetes, de forma predeterminada, el registro de auditoría se almacena en /var/log/audit.log y la política de auditoría está presente en /etc/kubernetes/audit-policy.yaml >.

Para habilitar el registro de auditoría, inicie kube-apiserver con estos parámetros:

--audit-policy-file=/etc/kubernetes/audit-policy.yaml --audit-log-path=/var/log/audit.log

Aquí hay un archivo audit.log de muestra configurado para registrar cambios en los pods:

apiVersion: audit.k8s.io/v1
kind: Policy
omitStages:
  - "RequestReceived"
rules:
  - level: RequestResponse
    resources:
    - group: ""
      resources: ["pods"]
   - level: Metadata
     resources:
     - group: ""
      resources: ["pods/log", "pods/status"]

Siempre puede regresar y verificar los registros de auditoría en caso de cualquier problema en el clúster de Kubernetes. Le ayudará a restaurar el estado correcto del clúster.

#9. Aplicar reglas de afinidad (nodo/pod)

Hay dos mecanismos en Kubernetes para asociar pods con los nodos de una mejor manera: Vaina y Nodo afinidad. Se recomienda utilizar estos mecanismos para un mejor rendimiento.

Con la afinidad de nodos, puede programar pods en los nodos en función de criterios definidos. Según los requisitos del pod, el nodo coincidente se selecciona y asigna en un clúster de Kubernetes.

apiVersion: v1
kind: Pod
metadata:
  name: ubuntu
spec:
  affinity:
    nodeAffinity:    
preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 2
        preference:        
matchExpressions:
          - key: disktype
            operator: In
            values:
            - ssd          
  containers:
  - name: ubuntu
    image: ubuntu
    imagePullPolicy: IfNotPresent

Con la afinidad de pods, puede programar varios pods en el mismo nodo (para mejorar la latencia) o decidir mantener los pods en nodos separados (para alta disponibilidad) para aumentar el rendimiento.

apiVersion: v1
kind: Pod
metadata:
  name: ubuntu-pod
spec:
  affinity:
    podAffinity:
     
requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
         
matchExpressions:
          - key: security
            operator: In
            values:
            - S1
        topologyKey: failure-domain.beta.kubernetes.io/zone
  containers:
  - name: ubuntu-pod
    image: ubuntu

Después de analizar la carga de trabajo de su clúster, debe decidir qué estrategia de afinidad usar.

#10. Terminación de Kubernetes

Kubernetes finaliza los pods cuando ya no son necesarios. Puede iniciarlo a través de un comando o una llamada API, los pods seleccionados pasan al estado de terminación y no se envía tráfico a esos pods. Luego se envía un mensaje SIGTERM a esos pods, después de lo cual los pods se apagan.

Los pods se terminan correctamente; de ​​forma predeterminada, el período de gracia es de 30 segundos. Si los pods aún se están ejecutando, Kubernetes envía un mensaje SIGKILL que apaga los pods a la fuerza. Finalmente, Kubernetes elimina estos pods del servidor API en la máquina maestra.

En caso de que sus pods siempre tarden más de 30 segundos, puede aumentar este período de gracia a 45 o 60 segundos.

apiVersion: v1
kind: Pod
metadata:
 name: container10
spec:
 containers:
   - image: ubuntu
     name: container10
  terminationGracePeriodSeconds: 60

Conclusión

Espero que estas prácticas recomendadas lo ayuden a organizar mejor los contenedores con Kubernetes. Continúe e intente implementarlos en su clúster de Kubernetes para obtener mejores resultados.

A continuación, explore las mejores herramientas de Kubernetes para el éxito de DevOps.

Publicaciones relacionadas

Botón volver arriba