Docker: RabbitMQ: exec(): Unable to fork, Prometheus node_exporter и Docker limits

Автор: | 15/02/2019

RabbitMQ перестал принимать новые сообщения, и при выполнении запроса – возвращает ошибки вида:

  • exec(): Unable to fork
  • write(): send of 12 bytes failed with errno=104 Connection reset by peer
  • fwrite(): send of 19 bytes failed with errno=32 Broken pipe

Собственно, по сообщениям видно, что проблема с памятью – exec() не может выполнить fork() и выделить место под новый процесс.

Когда начал проверять отжираемую память – внезапно обнаружилось, что Prometheus node_exporter занял почти 60% памяти на сервере.

Используем docker stats:

Вот он:

prometheus-client_node-exporter_1 0.00% 8.925GiB / 15.11GiB 59.06%

Собственно, перезапускаем стек мониторинга – память подчистилась.

Что бы избежать такой проблемы в будущем – добавляем лимиты для контейнеров.

Контейнеры у нас запускаются из Docker Compose файла prometheus-client-compose.yml.

Compose файл версии 2 (для использования с docker-compose) – используем mem_limit, и он будет выглядеть так:

version: '2.4'

networks:
  prometheus-client:

services:

  prometheus-server:
    image: prom/prometheus
    network_mode: "host"
    volumes:
      - /opt/prometheus-client/prometheus-client-conf.yml:/etc/prometheus/prometheus.yml
    restart: unless-stopped

  node-exporter:
    image: prom/node-exporter
    network_mode: "host"
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
    command:
      - '--path.procfs=/host/proc'
      - '--path.sysfs=/host/sys'
      - --collector.filesystem.ignored-mount-points
      - "^/(sys|proc|dev|host|etc|rootfs/var/lib/docker/containers|rootfs/var/lib/docker/overlay2|rootfs/run/docker/netns|rootfs/var/lib/docker/aufs)($$|/)"
      - --collector.supervisord
      - '--collector.supervisord.url=http://supervisoradmin:password@localhost:9001/RPC2'
    restart: unless-stopped
    # For Compose v2 and docker-compose
    mem_limit: 500m
    mem_reservation: 100m

...

Версия 3, для Docker Swarm – используем deploy и resources:

version: '3.3'

networks:
  prometheus-client:

services:

  prometheus-server:
    image: prom/prometheus
    network_mode: "host"
    volumes:
      - /opt/prometheus-client/prometheus-client-conf.yml:/etc/prometheus/prometheus.yml
    restart: unless-stopped

  node-exporter:
    image: prom/node-exporter
    network_mode: "host"
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
    command:
      - '--path.procfs=/host/proc'
      - '--path.sysfs=/host/sys'
      - --collector.filesystem.ignored-mount-points
      - "^/(sys|proc|dev|host|etc|rootfs/var/lib/docker/containers|rootfs/var/lib/docker/overlay2|rootfs/run/docker/netns|rootfs/var/lib/docker/aufs)($$|/)"
      - --collector.supervisord
      - '--collector.supervisord.url=http://supervisoradmin:password@localhost:9001/RPC2'
    restart: unless-stopped
    deploy:
      resources:
        limits:
          memory: 300m
        reservations:
          memory: 100m
...

Тут:

  • limits: максимально допустимый объём памяти
  • reservations: минимально требуемый для контейнера (сервиса) объём

Проверяем лимиты, с помощью того же stats:

Готово.