
Wir haben eine API im Einsatz, die einmal am Tag mehrere Batches großer Datenmengen empfängt, die in eine MongoDB eingefügt werden. Wir verwenden die cvallance/mongo-k8s-sidecar
für die Replikationsset-Konfiguration
Dies funktioniert perfekt auf einer lokalen Mongo-Datenbank.
es gibt auch keinen Produktionsverkehr auf der Datenbank, der zu erhöhten Bedingungen oder ähnlichem führen könnte.
Nun haben wir es in einer Google Container Engine bereitgestellt. Dort funktioniert der Import im Allgemeinen auch. Aber von Zeit zu Zeit erhalten wir TimeoutExceptions wie diese:
replSetReconfig kann nicht ausgeführt werden, da der Knoten derzeit seine Konfiguration aktualisiert
oder
MongoDB.Driver.MongoCommandException: Befehlseinfügung fehlgeschlagen: BSONObj-Größe: 16793637 (0x1004025) ist ungültig. Größe muss zwischen 0 und 16793600 (16 MB) liegen. Erstes Element: einfügen: „LandingPageConnectionSet_Stage“.
oder
Fehler in Arbeitsschleife { MongoError: Verbindung 0 zu 127.0.0.1:27017 ist bei Function.MongoError.create (/opt/cvallance/mongo-k8s-sidecar/node_modules/mongodb-core/lib/error.js:29:11) bei Socket abgelaufen. (/opt/cvallance/mongo-k8s-sidecar/node_modules/mongodb-core/lib/connection/connection.js:198:20) bei Object.onceWrapper (events.js:254:19) bei Socket.emit (events.js:159:13) bei Socket._onTimeout (net.js:411:8) bei ontimeout (timers.js:478:11) bei tryOnTimeout (timers.js:302:5) bei Timer.listOnTimeout (timers.js:262:5)
Ich sehe, dass die CPU offenbar nicht am Limit ist.
Kubernetes-Konfiguration für 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
Wir haben auch die Konfiguration leicht geändert, indem wir die Wiretiger-Cachegröße begrenzt und die Smallfiles-Optionen entfernt haben, sodass der Teil in der Konfiguration folgendermaßen aussah:
- mongod
- "--replSet"
- rs0
- "--bind_ip"
- 0.0.0.0
- "--noprealloc"
- "--wiredTigerCacheSizeGB"
- "1.5"
Antwort1
Ich habe die Protokolle und das Kubernetes-Dashboard mit Boas Enkler überprüft.
Im Kubernetes Dashboard zum Status der PODs gab es folgende Hinweise:
Pod Name: kube-lego-*****-***
Status: Evicted
Reason: The node was low on resource: memory.
Sie hätten die gleichen Informationen erhalten können überkubectl describe pod [podname]
Beachten Sie, dass das Zitieren derDokumentation: „Wenn der Kubelet nicht genügend Ressourcen auf dem Knoten zurückfordern kann, beginnt er mit der Räumung von Pods.“
Daher ging ich davon aus, dass der Fehler bei Mongodb lag, da es vor Ort ohne Probleme funktionierte. Zur Überprüfung gingen wir die Kernel-Protokolle durch, die in der seriellen Konsolenausgabe angezeigt wurden, und fanden:
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
Uns fiel auch auf, dass in der YAML-Datei des Deployments kein Feld für Speicheranforderungen vorhanden war. Dies ist ein Problem, da es passieren kann, dass selbst wenn drei Knoten ohne Arbeitslast vorhanden sind, alle PODs auf demselben Knoten gestartet werden, da sie theoretisch passen.
Um dieses Verhalten zu mildern, gibt es einige mögliche Lösungen:
Skalieren Sie den Cluster vertikal und führen Sie Speicheranforderungswerte ein
AnweisenDer MongoDB-Prozess verbraucht weniger Speicher als angefordert.
Die Einführung eines Speicherlimits ist wichtig, wenn Sie mehrere Container auf demselben Knoten ausführen und vermeiden möchten, dass diese dadurch beendet werden. Bedenken Sie, dass sie auf diese Weise manchmal beendet werden, auch wenn auf dem Knoten noch Speicher verfügbar ist.