Mongodb en Kubernetes Timeouts al insertar una gran cantidad de datos

Mongodb en Kubernetes Timeouts al insertar una gran cantidad de datos

Tenemos una API en ejecución que recibe una vez al día varios lotes de datos de gran tamaño que se insertan en un mongodb. Usamos el cvallance/mongo-k8s-sidecarpara la configuración del conjunto de replicación.

Esto funciona perfectamente en una base de datos mongo local.

Tampoco hay tráfico de producción en la base de datos que pueda generar condiciones de aumento.

Ahora lo implementamos en un motor de contenedores de Google. Allí también funciona la importación en general. Pero de vez en cuando tenemos excepciones de tiempo de espera como esta:

No se puede ejecutar replSetReconfig porque el nodo está actualizando su configuración actualmente

o

MongoDB.Driver.MongoCommandException: Error al insertar el comando: el tamaño de BSONObj: 16793637 (0x1004025) no es válido. El tamaño debe estar entre 0 y 16793600(16 MB). Primer elemento: inserte: "LandingPageConnectionSet_Stage".

o

Error en el bucle de trabajo {MongoError: se agotó el tiempo de espera de la conexión 0 a 127.0.0.1:27017 en Function.MongoError.create (/opt/cvallance/mongo-k8s-sidecar/node_modules/mongodb-core/lib/error.js:29:11) en el zócalo. (/opt/cvallance/mongo-k8s-sidecar/node_modules/mongodb-core/lib/connection/connection.js:198:20) en Object.onceWrapper (events.js:254:19) en Socket.emit (events. js:159:13) en Socket._onTimeout (net.js:411:8) en ontimeout (timers.js:478:11) en tryOnTimeout (timers.js:302:5) en Timer.listOnTimeout (timers.js: 262:5)

Puedo ver que la CPU parece no estar al límite.

Configuración de Kubernetes para mongodb

---
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: fast
provisioner: kubernetes.io/gce-pd
parameters:
  type: pd-ssd
---
apiVersion: v1
kind: Service
metadata:
  name: mongo
  labels:
    name: mongo
spec:
  ports:
  - port: 27017
    targetPort: 27017
  clusterIP: None
  selector:
    role: mongo
---
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  name: mongo
spec:
  serviceName: "mongo"
  replicas: 3
  template:
    metadata:
      labels:
        role: mongo
        environment: test
    spec:
      terminationGracePeriodSeconds: 10
      containers:
        - name: mongo
          image: mongo:3.6
          command:
            - mongod
            - "--replSet"
            - rs0
            - "--bind_ip"
            - 0.0.0.0
            - "--smallfiles"
            - "--noprealloc"
          ports:
            - containerPort: 27017
          volumeMounts:
            - name: mongo-persistent-storage
              mountPath: /data/db
        - name: mongo-sidecar
          image: cvallance/mongo-k8s-sidecar
          env:
            - name: MONGO_SIDECAR_POD_LABELS
              value: "role=mongo,environment=test"
  volumeClaimTemplates:
  - metadata:
      name: mongo-persistent-storage
      annotations:
        volume.beta.kubernetes.io/storage-class: "fast"
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 32Gi

También cambiamos poco la configuración limitando el tamaño de caché de Wiretiger y eliminando las opciones de archivos pequeños para que la parte de la configuración se viera así:

   - mongod
    - "--replSet"
    - rs0
    - "--bind_ip"
    - 0.0.0.0
    - "--noprealloc"
    - "--wiredTigerCacheSizeGB"
    - "1.5"

Respuesta1

Revisé los registros y el panel de Kubernetes con Boas Enkler.

En el panel de Kubernetes con respecto al estado de los POD había las siguientes sugerencias:

Pod Name: kube-lego-*****-***     
Status: Evicted 
Reason: The node was low on resource: memory.

Podrías haber recuperado la misma información a través dekubectl describe pod [podname]

Note que citar eldocumentación: "Si kubelet no puede reclamar suficientes recursos en el nodo, kubelet comienza a desalojar Pods".

Por lo tanto, creí que el error con Mongodb ya que estaba funcionando en las instalaciones sin ningún problema, para verificarlo revisamos los registros del Kernel mostrados por la salida serial de la consola y encontramos:

Memory cgroup out of memory: Kill process 4**7 (mongod) score 1494 or sacrifice child
...
Memory cgroup out of memory: Kill process 1**8 (mongod) score 1538 or sacrifice child

También notamos que no había ningún campo de Solicitud de memoria en el archivo YAML de la implementación. Esto es un problema ya que puede suceder que incluso si hay tres nodos sin carga de trabajo, puede suceder que todos los POD se inicien en el mismo nodo ya que teóricamente encajan.

Para mitigar este comportamiento existen algunas posibles soluciones:

  • Escale verticalmente el clúster e introduzca valores de solicitud de memoria

  • Instruirel proceso mongodb consuma una cantidad de memoria menor que la solicitada.

  • La introducción del límite de memoria es esencial si tiene más contenedores ejecutándose en el mismo nodo y desea evitar que este los elimine. Tenga en cuenta que de esta manera a veces se eliminará incluso si todavía hay memoria disponible en el nodo.

información relacionada