
У нас есть запущенный API, который получает раз в день несколько пакетов больших данных, которые вставляются в mongodb. Мы используем cvallance/mongo-k8s-sidecar
для конфигурации replicationset
Это прекрасно работает в локальной базе данных MongoDatabase.
также в базе данных нет производственного трафика, который мог бы вызвать условия повышения или что-то в этом роде.
Теперь мы развернули его в контейнерном движке Google. Там импорт в целом тоже работает. Но время от времени мы получали исключения timeoutexceptions, например:
Невозможно запустить replSetReconfig, так как узел в данный момент обновляет свою конфигурацию.
или
MongoDB.Driver.MongoCommandException: Ошибка вставки команды: размер BSONObj: 16793637 (0x1004025) недопустим. Размер должен быть от 0 до 16793600 (16 МБ) Первый элемент: вставка: "LandingPageConnectionSet_Stage".
или
Ошибка в рабочем цикле { MongoError: время ожидания соединения 0 с 127.0.0.1:27017 истекло в Function.MongoError.create (/opt/cvallance/mongo-k8s-sidecar/node_modules/mongodb-core/lib/error.js:29:11) в Socket. (/opt/cvallance/mongo-k8s-sidecar/node_modules/mongodb-core/lib/connection/connection.js:198:20) в Object.onceWrapper (events.js:254:19) в Socket.emit (events.js:159:13) в Socket._onTimeout (net.js:411:8) в ontimeout (timers.js:478:11) в tryOnTimeout (timers.js:302:5) в Timer.listOnTimeout (timers.js:262:5)
Я вижу, что процессор, похоже, не достиг своего предела.
Конфигурация Kubernetes для 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
мы также немного изменили конфигурацию, ограничив размер кэша Wiretiger и удалив параметры smallfiles, так что часть конфигурации выглядела так:
- mongod
- "--replSet"
- rs0
- "--bind_ip"
- 0.0.0.0
- "--noprealloc"
- "--wiredTigerCacheSizeGB"
- "1.5"
решение1
Я проверил журналы и панель управления Kubernetes с Боасом Энклером.
На панели инструментов Kubernetes относительно статуса POD имелись следующие подсказки:
Pod Name: kube-lego-*****-***
Status: Evicted
Reason: The node was low on resource: memory.
Вы могли бы получить ту же самую информацию черезkubectl describe pod [podname]
Обратите внимание, что цитированиедокументация: «Если kubelet не может вернуть достаточно ресурсов на узле, kubelet начинает вытеснять модули».
Поэтому я решил, что ошибка связана с MongoDB, поскольку она работала локально без каких-либо проблем. Для дополнительной проверки мы просмотрели журналы ядра, показанные в последовательном выводе консоли, и обнаружили:
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
Мы также заметили, что в файле YAML развертывания не было поля Memory Request. Это проблема, поскольку может случиться так, что даже если есть три узла без рабочей нагрузки, может случиться так, что все POD будут запущены на одном и том же узле, поскольку они теоретически подходят.
Чтобы смягчить такое поведение, есть несколько возможных решений:
Масштабируйте кластер вертикально и вводите значения запросов памяти
Инструктироватьпроцесс mongodb потребляет объем памяти, меньший запрошенного.
Введение ограничения памяти необходимо, если у вас запущено больше контейнеров на одном узле, и вы хотите избежать их уничтожения. Учтите, что таким образом он иногда будет уничтожен, даже если на узле еще есть доступная память.