Связь между сервисами в стеке Docker Swarm

Вопрос или проблема

Я совсем нов в Docker Swarm и думал, что переход от Docker Compose будет простым.

Я сталкиваюсь с проблемами в коммуникации между разными сервисами.

version: '3.8'
services:
  frankenphp:
    restart: always
    image: frankenphp-app:latest
    ports:
      - '9000:80'
    volumes:
      - mystack_caddy_data:/data
      - mystack_caddy_config:/config
    depends_on:
      - mysql
    networks:
      - mystack_network

  mysql:
    restart: always
    image: 'mysql/mysql-server:8.0'
    ports:
      - '3306:3306'
    environment:
      MYSQL_ROOT_PASSWORD: 'password'
      MYSQL_ROOT_HOST: '%'
      MYSQL_DATABASE: 'database'
      MYSQL_USER: 'user'
      MYSQL_PASSWORD: 'password'
      MYSQL_ALLOW_EMPTY_PASSWORD: 1
    volumes:
      - 'mystack_mysql:/var/lib/mysql'
    healthcheck:
      test:
        - CMD
        - mysqladmin
        - ping
        - '-ppassword'
      retries: 3
      timeout: 5s
    networks:
      - mystack_network

volumes:
  mystack_caddy_data:
  mystack_caddy_config:
  mystack_mysql:

networks:
  mystack_network:
    driver: overlay

Я разворачиваю этот стек, просто ввёдя:

docker stack deploy -c stack.yml my stack

Мой сервис frankenphp не может разрешить имя хоста mysql – это работает нормально при использовании Docker Compose.

Я пробовал использовать mysql, stack.mysql, mysql.stack, mystack.mysql и mysql.mystack – попытки были основаны на неправильном использовании Google и ChatGPT.

Я не могу понять, как это работает.

Может кто-то сможет объяснить, как это работает?

Ответ или решение

Понимание подключения сервисов в Docker Swarm является важной частью работы с этой технологией, особенно для тех, кто переходит с Docker Compose, который на первый взгляд может показаться более простым. Ваша проблема с разрешением имени хоста для сервиса MySQL в стеке Docker Swarm может возникнуть по ряду причин, которые мы подробно разберем ниже.

1. Основы сетевого взаимодействия в Docker Swarm

Docker Swarm использует сетевую архитектуру с наложением (overlay networking), которая обеспечивает взаимодействие между контейнерами, работающими на разных хостах. Все сервисы, определенные в одном стеке, могут общаться друг с другом, используя их имена сервисов как DNS-имена.

Пример:

Если ваш сервис называется mysql, вы должны быть в состоянии обратиться к нему из другого сервиса (например, frankenphp) по имени mysql, без необходимости указывать другие префиксы или суффиксы.

2. Проверка конфигурации вашего файла

Ваш файл docker-compose.yml (или stack.yml в случае с Docker Swarm) выглядит в целом корректно:

version: '3.8'
services:
  frankenphp:
    ...
    depends_on:
      - mysql
    networks:
      - mystack_network

  mysql:
    ...
    networks:
      - mystack_network

volumes:
  ...

networks:
  mystack_network:
    driver: overlay

Убедитесь, что оба сервиса находятся в одной сети (mystack_network), что вы уже сделали, и это позволяет их взаимодействовать.

3. Убедитесь в актуальности образов

Иногда проблемы с подключением могут быть вызваны использованием устаревших образов. Убедитесь, что вы используете актуальные версии образов. Вы можете использовать команду:

docker pull frankenphp-app:latest
docker pull mysql/mysql-server:8.0

4. Проверка зависимости (depends_on)

Параметр depends_on в Docker Compose используется для указания порядка запуска сервисов. Однако это не сигнализирует о готовности сервиса для подключения. Например, сервис mysql может запуститься, но еще не быть готовым к обработке соединений. В вашем случае можно использовать healthcheck, чтобы убедиться, что MySQL готов к соединению прежде чем пытаться подключиться.

5. Использование healthcheck

Вы уже добавили healthcheck для MySQL, что является хорошей практикой. Убедитесь, что MySQL проходит проверку состояния, прежде чем ваш frankenphp сервис попытается к нему подключиться. Вы можете добавитьretry в ваше приложение, чтобы минимизировать проблемы с временными задержками подключения.

6. Проверка логов

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

docker service logs mystack_frankenphp
docker service logs mystack_mysql

Это может предоставить дополнительную информацию о том, что происходит в момент попыток подключения.

Заключение

Суммируя, обращение между сервисами в Docker Swarm должно работать по именам сервисов. Вам нужно убедиться, что оба сервиса находятся в одной сетевой конфигурации, что MySQL готов принимать соединения и что образы актуальны. Если у вас все еще возникают проблемы, рассмотрите возможность добавления логики повторных попыток в ваше приложение для обработки временных задержек.

Если все вышеперечисленные шаги не приводят к решению проблемы, возможно, имеет смысл обратить внимание на сетевые правила вашего Docker Swarm, либо ознакомиться с документацией, связанными с конкретной версией Docker, которую вы используете.

Оцените материал
Добавить комментарий

Капча загружается...