使用Symfony / PHP拒绝数据库连接

时间:2016-12-02 10:53:09

标签: symfony cloudfoundry swisscomdev

尝试将Symfony 3.2 / Doctrine应用程序部署到Swisscom PaaS。

安装了Buildpack(PHP 7,httpd等),composer正在运行并安装依赖项,但是当调用composer后命令时,比如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

my options.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

**** **** EDIT

我调试了调用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();

任何看起来都像在Web控制台中可以看到服务绑定一样。

成功连接需要 unix_socket 吗?

**** **** EDIT

由于Symfony正在使用一些作曲家安装后命令(在这种情况下,例如清除和预热缓存),这些命令需要已经有效的数据库连接,只要容器是cloudfoundry就不支持数据库服务。没有完全建立和部署?

我的想法已经不多了。

3 个答案:

答案 0 :(得分:2)

对此问题表示歉心,并感谢您的反馈。 Swisscom修改了安全组。有关详细信息,请参阅Application Security Groups

  

Cloud Foundry会阻止来自应用程序的所有出站网络连接   容器默认情况下。管理员可以覆盖它   应用程序安全组(ASG)的默认行为。

     

ASG是指定一个或多个的出口规则的集合   允许网络访问的各个协议,端口和目标   到。

     

Cloud Foundry有两组默认的ASG:default-staging和   default-running。 Cloud Foundry中的所有应用程序容器都使用a   来自其中一个的基本政策。

Galera即服务(MariaDB)的规则仅在running中完成。我们还将规则添加到staging

答案 1 :(得分:1)

万一有人遇到类似的问题,这就是解决方案:

最后,我只能通过PaaS提供商(swisscomdev)支持来解决这个问题。

显然,在我们的应用程序的暂存/部署期间没有提供/可能的数据库连接,但Symfony的缓存:clear / warmup在编写器后处理阶段需要完整的数据库连接。

在基于cloudfoundry的swisscomdev平台上修复后,一切都按预期工作。

答案 2 :(得分:0)

根据我的经验,Connection refused可能意味着其中一件事:

  • 防火墙(iptables?)阻止了对端口的非本地访问
  • mysql服务器甚至没有收听端口
  • 当客户端尝试通过mysql进行连接时,ipv6服务器正在3306端口ipv4上进行侦听。

首先让我们尝试通过运行基本的telnet测试来缩小范围:

telnet 10.0.20.18 3306

这应该用一些半乱码的消息来问候你,并明确提到MySQL。如果没有,那么您需要回到更一般的限制,例如防火墙和策略。

由于您肯定服务器正在运行,我建议您检查是否被防火墙或SELinux阻止。不过,不知道你对Swisscom的PaaS系统有多少控制权。

如果您具有对PaaS服务的SSH访问权限,则可以尝试运行tcpdump来捕获任何流量。请参阅此文章:https://serverfault.com/questions/507627/debugging-a-connection-refused-response-on-port-21

希望这会给你一些提示......