Соединение с базой данных отклонено с Symfony / PHP

Попытка развернуть приложение Symfony 3.2/Doctrine на Swisscom PaaS.

Buildpack (PHP 7, httpd и т. д.) установлен, композитор работает и устанавливает зависимости, но при вызове дополнительных команд композитора, таких как cache:clear, я получаю:

[Doctrine\DBAL\Exception\ConnectionException]                              
An exception occured in driver: SQLSTATE[HY000] [2002] Connection refused

мой manifest.yml:

applications:
- services:
 - dbservice
buildpack: php_buildpack
host: myapp
name: MyApp
instances: 1
memory: 640M
env:
 SYMFONY_ENV: prod
 PHP_INI_SCAN_DIR: .bp-config/php/conf.d

мои параметры.json:

"WEB_SERVER": "httpd",
"COMPOSER_INSTALL_OPTIONS": ["--no-dev --optimize-autoloader --no-progress --no-interaction"],
"COMPOSER_VENDOR_DIR": "vendor",
"SYMFONY_ENV": "prod",
"WEBDIR": "web",
"PHP_MODULES": "fpm",
"PHP_VERSION": "{PHP_70_LATEST}",
"PHP_EXTENSIONS": [
 "bz2",
 "zlib",
 "curl",
 "mcrypt",
 "openssl",
 "mbstring",
 "pdo",
 "pdo_mysql"
],
"ZEND_EXTENSIONS": [
 "opcache"
]

И вот как я считываю учетные данные базы данных из VCAP и устанавливаю параметры в Symfony (который отлично работает с локальной настройкой VCAPSERVICES env vars):

$vcapServices = json_decode($_ENV['VCAP_SERVICES']);

$container->setParameter('database_driver', 'pdo_mysql');

$db = $vcapServices->{'mariadb'}[0]->credentials;

$container->setParameter('database_host', $db->host);
$container->setParameter('database_port', $db->port);
$container->setParameter('database_name', $db->name);
$container->setParameter('database_user', $db->username);
$container->setParameter('database_password', $db->password);

// Just for debug:

echo 'User: ';
var_dump($container->getParameter('database_user'));

echo 'Db: ';
var_dump($db);

Служба запущена, оба var_dump передают ожидаемые значения. Но все равно в соединении отказывают.

Что я делаю не так?

****EDIT**** Похоже, что здесь есть похожая проблема, но без решения: Cloud Foundry p-mysql

****РЕДАКТИРОВАТЬ****

Я отладил прямо до инструкции, где вызывается конструктор PDO.

Вызывается со следующими параметрами:

$dsn = mysql:host=10.0.20.18;port=3306;dbname=CF_DB922DD3_CACB_4344_9948_746E585732B5;
$username = "myrealusername"; // as looked up in VCAP_SERVICES
$password = "myrealpassword"; // as looked up in VCAP_SERVICES
$options = array();

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

Требуется ли unix_socket для успешного подключения?

****РЕДАКТИРОВАТЬ****

Поскольку Symfony использует некоторые постустановочные команды композитора (в данном случае, например, для очистки и разогрева кеша), которые требуют уже работающего соединения с базой данных, это не поддерживается службами БД облачным фондом, пока контейнер не полностью собран. и развернуто?

У меня заканчиваются идеи.


person LBA    schedule 02.12.2016    source источник


Ответы (3)


Извините за проблему и спасибо за отзыв. Swisscom изменил группы безопасности. Дополнительные сведения см. в разделе группы безопасности приложений.

Cloud Foundry по умолчанию блокирует все исходящие сетевые подключения из контейнеров приложений. Администраторы могут переопределить это поведение блокировки по умолчанию с помощью групп безопасности приложений (ASG).

ASG — это набор правил исходящего трафика, которые определяют один или несколько отдельных протоколов, портов и пунктов назначения, к которым разрешен доступ к сети.

Cloud Foundry имеет два набора ASG по умолчанию: default-staging и default-running. Все контейнеры приложений в Cloud Foundry используют базовую политику одного из них.

Правило Galera as a Service (MariaDB) было реализовано только в running. Мы добавили правило также в staging.

person Josefine    schedule 06.12.2016

На всякий случай, если у кого-то есть аналогичная проблема, это было решение:

В конце концов я смог решить эту проблему только с поддержкой поставщика PaaS (swisscomdev).

Очевидно, что подключение к базе данных не было предоставлено/возможно во время подготовки/развертывания нашего приложения, но кеш Symfony:clear/warmup требовал полного подключения к базе данных на этапе постобработки композитора.

После исправления в платформе swisscomdev на основе cloudfoundry все заработало, как и ожидалось.

person LBA    schedule 06.12.2016

По моему опыту, Connection refused может означать одно из следующего:

  • Брандмауэр (iptables?) блокирует нелокальный доступ к порту
  • Сервер mysql даже не слушает порт
  • Сервер mysql прослушивает ipv6 порт 3306, а клиент пытается подключиться через ipv4.

Сначала давайте попробуем сузить круг, запустив базовый тест telnet:

telnet 10.0.20.18 3306

Это должно приветствовать вас полуискаженным сообщением с четким упоминанием MySQL. Если это не так, вам нужно вернуться к более общим ограничениям, таким как брандмауэры и политики.

Поскольку вы уверены, что сервер работает, я предлагаю проверить, не блокирует ли вас брандмауэр или SELinux. Однако не знаю, насколько вы контролируете систему PaaS Swisscom.

Если у вас есть SSH-доступ к службе PaaS, вы можете попробовать запустить tcpdump для захвата любого трафика. См. эту статью: https://serverfault.com/questions/507627/debugging-a-connection-refused-response-on-port-21

Надеюсь, это даст вам некоторый намек...

person Jovan Perovic    schedule 02.12.2016
comment
спасибо, в конце концов, при поддержке swisscomdev я узнал, что во время подготовки соединение с базой данных было недоступно. подтвердит это в понедельник и предоставит обновленную информацию здесь. - person LBA; 03.12.2016
comment
поэтому я смог подключиться к работающей базе данных отовсюду, единственной «недостающей ссылкой» была неполная привязка моего приложения к службе базы данных во время подготовки приложения. - person LBA; 03.12.2016