LINUX.ORG.RU
ФорумAdmin

Один Docker контейнер не может связаться с другим Docker контейнером

 ,


0

1

Имеется два docker compose файла.

infra/docker-compose.yaml:

services:
  watchtower:
    container_name: watchtower
    image: containrrr/watchtower
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - $HOME/.docker/config.json:/config.json
    command: --label-enable
  prometheus:
    container_name: prometheus
    image: prom/prometheus
    user: root
    restart: unless-stopped
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - ./data/prometheus:/prometheus
    networks:
      - prometheus-network
networks:
  prometheus-network:
    driver: bridge

app/docker-compose.yaml:

services:
  backend:
    container_name: app-backend
    image: ...
    restart: unless-stopped
    environment:
      - DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}
    networks:
      - postgres-network
      - prometheus-network
    depends_on:
      - postgres
    labels:
      - "com.centurylinklabs.watchtower.enable=true"
  frontend:
    container_name: app-frontend
    ...
  postgres:
    container_name: app-postgres
    image: postgres:17-alpine
    ...
networks:
  postgres-network:
    driver: bridge
  prometheus-network:
    name: infra_prometheus-network
    external: true

Соответственно, запускается сначала infra, потом app.

Если зайти в контейнер app-backend и попробовать ping prometheus, то всё работает. Также можно попинговать самих себя - ping app-backend.

Если зайти в контейнер app-postgres и попробовать ping app-backend, то всё тоже работает.

Если зайти в контейнер prometheus и попробовать ping app-backend, то будет bad address 'app-backend'. Более того, если попробовать сделать ping prometheus, то эта команда тоже потерпит неудачу - то есть контейнер не видит сам себя.

Делаем docker inspect infra_prometheus-network:

[
    {
        "Name": "infra_prometheus-network",
        "Id": "ffec05671b873e60def53db831d4eb3966ba39bab74c01e8c7175362ae7da347",
        "Created": "2024-10-11T22:59:25.742311072Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.24.0.0/16",
                    "Gateway": "172.24.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": true,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "09bf47aa0f971ba2c9b686cb7bef947bd32eb7351ad41ec318118399345785d4": {
                "Name": "prometheus",
                "EndpointID": "dea3bb0a3e470cbcc9561ad8ef481c363f24a8c98628c4efd9d0193060092961",
                "MacAddress": "02:42:ac:18:00:02",
                "IPv4Address": "172.24.0.2/16",
                "IPv6Address": ""
            },
            "fa4dc2216105c90ccb1d165b6ce2b99dd43263a1bb459b43d0ce44a89330a9f8": {
                "Name": "app-backend",
                "EndpointID": "caa1b1371b290e7afd0273dd9a4e02781e2c895ed21d2913585739e233bc4784",
                "MacAddress": "02:42:ac:18:00:03",
                "IPv4Address": "172.24.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {
            "com.docker.compose.network": "prometheus-network",
            "com.docker.compose.project": "infra",
            "com.docker.compose.version": "2.29.7"
        }
    }
]

Видим, что IP контейнера app-backend - 172.24.0.3. Заходим в контейнер prometheus и делаем ping 172.24.0.3 - всё работает. То есть связь между контейнерами есть, но DNS не работает, причём только в одну сторону.

Пинговать внешние ресурсы типа Google из контейнера prometheus успешно получается, так что такой хотя бы DNS работает.

В чём может быть дело?

UPD: Проблема в официальном образе прометиуса - Один Docker контейнер не может связаться с другим Docker контейнером (комментарий), точнее скорее даже в базовом образе из которого он сделан. На неофициальном образе на базе alpine всё работает.

★★★★★

Последнее исправление: KivApple (всего исправлений: 1)

Список имён контейнера:

docker container inspect ${CONTAINER} -f '{{range $k,$v:=.NetworkSettings.Networks}}{{range $n:=$v.DNSNames}}{{$n}}.{{println $k}}{{end}}{{end}}'

В зависимости от конфигурации сетей, и откуда пинг, часть из них может быть недоступна.

neumond
()

Пост целиком не читал. Но в случае запуска с разных директорий и разные docker-compose для каждого докер коспозе создаётся своя отдельная сеть.

Читай про сети в докер. Это все настраивается.

kostik87 ★★★★★
()
Ответ на: комментарий от kostik87

Проблема не в этом.

Я запустил в итоге прометиус из образа linuxtips/prometheus_alpine и он РАБОТАЕТ в той же конфигурации.

Проблема не в конфигурации Docker compose, а в том, что prom/prometheus построен на базе более минимального образа, чем alpine и там то ли чего-то не хватает, то ли что-то устаревшее.

Я натыкался на информацию, что в каких-то версиях всяких облегчённых libc был/есть баг, влияющий на резолвинг DNS в докере.

Теперь вопрос, можно ли это как-то обойти хитрыми настройками докера или нет.

KivApple ★★★★★
() автор топика
Ответ на: комментарий от KivApple

Ну если ты запустил все в одном докер композе, то это другое.

Если ты под конфигурацией имеешь в виду это.

Я натыкался на информацию, что в каких-то версиях всяких облегчённых libc был/есть баг, влияющий на резолвинг DNS в докере.

Попробуй собрать свой контейнер с прометеус на базе минимального образа того дистрибутива, в котором ты проверил работу пинг.

kostik87 ★★★★★
()
Ответ на: комментарий от KivApple

Вот ради этого я потратил 40 минут своего времени, читал твой пост, разбирался как оно работает, составил команду, которая наведёт тебя на мысль. Чтобы ты просто не читая мой пост, по ключевому слову пинг, ответил выпиской того что я и так понял.

neumond
()
Ответ на: комментарий от kostik87

Я запустил не в одном. У меня есть инфраструктурный докер композ с общими вещами для всех контейнеров (сейчас там watchtower и prometheus, в будущем будет ещё nginx, когда я унесу его с хоста). И отдельные докер композы для разных приложений.

Идея в том, что приложения друг от друга не зависят, только от инфраструктуры.

Так вот - связь между композами на самом деле работает. Пинги ходят по прямым IP и DNS работает в контейнерах alpine. Но DNS не работает в контейнере прометиуса, который на базе busybox (пинги тоже ходят, тем не менее, но только по IP). Не работает настолько, что прометиус даже сам себя не может по имени пинговать.

KivApple ★★★★★
() автор топика