2

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

已安装 Buildpack(PHP 7、httpd 等),composer 正在运行并安装依赖项,但是当调用 composer after-commands 时,例如 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

我的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

****编辑****

我一直调试到调用 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 ?

****编辑****

由于 Symfony 正在使用一些 composer post-install-commands(在这种情况下,例如清除和预热缓存),这需要已经工作的数据库连接,只要容器没有完全构建,cloudfoundry 的 DB 服务不支持此连接并部署?

我的想法不多了。

4

3 回答 3

2

很抱歉这个问题,感谢您的反馈。Swisscom 修改了安全组。有关详细信息,请参阅应用程序安全组

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

ASG 是一组出口规则,它们指定一个或多个单独的协议、端口和目标以允许网络访问。

Cloud Foundry 有两组默认的 ASG:default-stagingdefault-running. Cloud Foundry 中的所有应用程序容器都使用其中之一的基本策略。

Galera 即服务 (MariaDB) 的规则仅在running. 我们也将规则添加到staging.

于 2016-12-06T13:28:30.703 回答
1

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

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

显然,在我们的应用程序的暂存/部署期间没有提供/可能的数据库连接,但是 Symfony 的缓存:清除/预热在作曲家后期处理阶段需要完整的数据库连接。

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

于 2016-12-06T13:15:58.807 回答
0

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

  • 防火墙 ( iptables?) 正在阻止对端口的非本地访问
  • 服务器mysql甚至没有监听端口
  • mysql服务器正在侦听ipv6端口,而3306客户端尝试通过ipv4.

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

telnet 10.0.20.18 3306

这应该会以一些含糊不清的信息来迎接您,并明确提及MySQL. 如果没有,那么您需要回到更一般的限制,例如防火墙和策略。

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

如果您对 PaaS 服务具有 SSH 访问权限,则可以尝试运行tcpdumpdo capture any traffic。请参阅这篇文章:https ://serverfault.com/questions/507627/debugging-a-connection-refused-response-on-port-21

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

于 2016-12-02T17:29:01.393 回答