Имеется два 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 всё работает.