У меня есть рой докеров, на котором запущен наш бизнес-стек, определенный в docker-compose.yml на двух серверах (узлах). В docker-compose определен cAdvisor, запускающийся на каждом из двух таких узлов:
cadvisor:
image: gcr.io/google-containers/cadvisor:latest
command: "--logtostderr --housekeeping_interval=30s"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /:/rootfs:ro
- /var/run:/var/run
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
- /dev/disk:/dev/disk/:ro
ports:
- "9338:8080"
deploy:
mode: global
resources:
limits:
memory: 128M
reservations:
memory: 64M
На третьем сервере я запускаю докер отдельно от роя докеров на узлах 1 и 2, и этот сервер используется для запуска Prometheus и Grafana. Prometheus настроен на очистку только ресурса node1: 9338 для получения информации cAdvisor.
Иногда у меня возникает проблема с тем, что при очистке node1: 9338 не все контейнеры, работающие на обоих узлах 1 и 2, отображаются в статистике cAdvisor.
Я предполагал, что cAdvisor синхронизирует свою информацию в рое, поэтому я могу настроить Prometheus только на использование node1: 9338 в качестве точки входа в рою докеров и очистки информации.
Или мне также нужно добавить node2: 9338 в мою конфигурацию Prometheus, чтобы всегда получать всю информацию обо всех узлах? Если да, то как это масштабировать, потому что мне нужно будет добавлять каждый новый узел в конфигурацию Prometheus.
Запуск Prometheus вместе со стеком бизнеса в одном рое - не вариант.
редактировать: Сегодня я испытал странное поведение при открытии URL-адреса метрик cAdvisor http: // node1: 9338 / metrics, а также http: // node2: 9338 / metrics, поскольку я вижу одну и ту же информацию обо всех контейнерах, запущенных на node1, на обоих URL-адресах. Информация о контейнерах, запущенных на node2, отсутствует при запросе http: // node2: 9338 / metrics.
Может быть, внутренняя балансировка нагрузки докера направляет запрос от http: // node2: 9338 / metrics к node1: 9338 cAdvisor, поэтому метрики node1 отображаются, несмотря на запрос node2?
cAdvisor просматривает информацию о контейнере, предоставленную Linux на этой машине, но ничего не знает о Swarm. Вы захотите, чтобы Прометей очистил все ваши машины.
На самом деле проблема заключалась во внутренней балансировке нагрузки в докере в режиме роя.
Как я писал в своем первоначальном посте, мы добавляли cAdvisor в наш файл docker-compose и создавали экземпляр docker-swarm через
docker stack deploy --prune --with-registry-auth -c docker-compose.yml MY_STACK
Конфигурация cAdvisor с
deploy:
mode: global
приводит к одному экземпляру на узел, но запрос определенного узла через http: // node2: 9338 / metrics не означает, что вы получите результат работы cAdvisor на этом узле. Внутренняя сеть докеров может перенаправить ваш запрос на http: // node1: 9338 / metrics, так что вы не сможете очистить реальные результаты cAdvisor от node2.
Решение, которое сработало для меня, заключалось в том, чтобы явно указать докеру использовать mode: host
в разделе портов cAdvisor в моем файле docker-compose. Моя последняя конфигурация выглядит так:
cadvisor:
image: gcr.io/google-containers/cadvisor:latest
command: "--logtostderr --housekeeping_interval=30s"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /:/rootfs:ro
- /var/run:/var/run
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
- /dev/disk:/dev/disk/:ro
ports:
- target: 8080
published: 9338
protocol: tcp
mode: host
deploy:
mode: global
resources:
limits:
cpus: "1"
memory: 128M
reservations:
memory: 64M
Обратите внимание на измененный раздел портов.