我将一个web应用程序部署到本地cloudfoundry环境中。作为我的DEV环境的数据库服务,我选择了计划为postgres-db-f1-micro
的Marketplace服务google-cloudsql-postgres
。使用Web UI,我创建了一个名为myapp-test-database
的实例,并在CF Manifest:中提到了它
applications:
- name: myapp-test
services:
- myapp-test-database
起初,一切都很好。我甚至可以重新部署现有的工件。然而,当我构建新版本的应用程序并将其推送到CF时,注入的凭据会更新,应用程序无法再访问表:
PSQLException: ERROR: permission denied for table
这些表仍然存在,但它们归前一个用户所有。它们是由ORM在public
模式中自动创建的。
当-OLD
应用程序仍然存在时,我可以从CF Web UI或$VCAP_SERVICES
中检索旧的用户名/密码并删除表。
这都是因为滚动应用程序部署吗?但接下来应该会有很多抱怨。
如果您严格执行cf push
(或restart
/restage
(,则不会涉及代理(云控制器不会与它对话(,服务凭据也不会更改。
通过cf
命令可以修改凭据的唯一操作是先执行unbind
,然后执行bind
。许多(但不是全部(服务代理将丢弃unbind
上的凭据,并为bind
提供新的、唯一的凭据。这通常是可取的,这样您就可以在凭据受损时轮换凭据。
如果您有自定义脚本或cf cli插件来实现滚动部署,则可能会出现问题。像这样的大多数工具都将使用两个独立的应用程序实例,这意味着您将拥有两个独立绑定和两组独立凭据。
如果您必须有一组凭据,则可以使用服务密钥来解决此问题。服务密钥类似于绑定,但与CloudFoundry中的应用程序无关。
服务密钥的缺点是,它不会像绑定一样通过$VCAP_SERVICES
自动暴露给您的应用程序。要解决此问题,可以将服务密钥cred传递到用户提供的服务中,然后将其绑定到应用程序,也可以通过其他环境变量(如DB_URL
(将其传递到应用程序中。
另一种选择是不再使用脚本和cf cli插件进行蓝/绿部署,而是使用现在内置在Cloud Foundry中的支持。对于cf
cli版本7+,cf push
具有--strategy
选项,该选项可以设置为rolling
以执行滚动部署。这不会创建多个应用程序实例,因此只存在一个服务绑定和一组凭据。
使用额外的绑定参数请求一个静态用户名"用户名":
cf bind-service my-app-test-CANDIDATE myapp-test-database -c "{"username":"myuser"}"
使用cf7+可以向清单中添加参数:
applications:
- name: myapp-test
services:
- name: myapp-test-database
parameters: { "username": "myuser" }
https://docs.cloudfoundry.org/devguide/services/application-binding.html#arbitrary-params结合
注意:在cf CLI v6.x的应用程序清单中不支持任意参数。在cf CLI 7.0及更高版本的应用程序列表中支持任意参数
但是,我在这里找不到新语法:https://docs.cloudfoundry.org/devguide/deploy-apps/manifest-attributes.html#services-块。我使用的语法来自其他一些SO问题。