【问题标题】:injected db credentials change when I deploy new app version to cloud当我将新应用程序版本部署到云时,注入的数据库凭据发生变化
【发布时间】:2021-07-15 21:09:04
【问题描述】:

我将 Web 应用程序部署到本地 cloudfoundry 环境。作为我的 DEV 环境的数据库服务,我选择了市场服务google-cloudsql-postgres,计划为postgres-db-f1-micro。我使用 Web UI 创建了一个名为 myapp-test-database 的实例,并在 CF Manifest 中提到了它:

applications:
- name: myapp-test
  services:
   - myapp-test-database

起初,一切都很好。我什至可以重新部署现有的工件。但是,当我构建我的应用程序的新版本并将其推送到 CF 时,注入的凭据会更新,并且应用程序无法再访问表:

PSQLException: ERROR: permission denied for table 

这些表仍然存在,但归前一个用户所有。它们是由 public 架构中的 ORM 自动创建的。

虽然 -OLD 应用程序仍然存在,但我可以从 CF Web UI 或 $VCAP_SERVICES 检索旧用户名/密码并删除表。

这一切都是因为滚动应用部署吗?但是接下来应该会有很多抱怨。

【问题讨论】:

  • 如果您严格执行cf push(或重新启动/重新暂存),则不涉及代理(云控制器不与它对话),因此如果您的凭据发生变化,它会发生在 CF 发生的事情之外。通过cf 可以修改您的凭据的唯一操作是执行unbind / bind。许多(但不是全部)服务代理将丢弃unbind 上的凭据,并为bind 提供新的、唯一的凭据。
  • While the -OLD application still exists -> 听起来您没有使用cf7 中的滚动部署功能。该功能不使用两个应用程序,它在 CF 中使用不同的原语。如果您在 CF 中有两个不同的应用程序(即cf apps 显示两个),则您必须有两个单独的绑定,这意味着两个单独的凭据。如果您需要两个应用程序具有相同的凭据,则可以改用服务密钥。服务键类似于绑定,但与应用程序无关。然后,您可以通过用户提供的服务或环境变量传递服务密钥凭据。
  • @DanielMikusa 是的,看起来我们使用的构建脚本模拟了滚动部署。您使用服务密钥的建议有帮助!我真的很失望 cf 不能像绑定服务那样向$VCAP_SERVICES 注入服务密钥凭据
  • 这并不是服务密钥的真正意图。不支持 CF 的应用程序存在服务密钥,即不了解 VCAP_SERVICES,以及非 CF 部署的服务以使用 CF 上的服务(至少这是我的理解)。对于像这种情况这样的其他情况,它们可能很方便,但不是主要目的。如果您使用滚动部署,则不会有此限制。您还可以与您的服务提供商讨论共享用户的其他功能。

标签: postgresql google-cloud-sql cloud-foundry


【解决方案1】:

如果您严格执行cf push(或restart/restage),则不涉及代理(云控制器不与其对话),并且服务凭据不会更改。

通过cf 命令可以修改您的凭据的唯一操作是执行unbind 后跟bind。许多(但不是全部)服务代理将丢弃unbind 上的凭据,并为bind 提供新的、唯一的凭据。这通常是可取的,这样您就可以在凭据被泄露时轮换凭据。

如果您有自定义脚本或 cf cli 插件来实现滚动部署,则可能会出现问题。像这样的大多数工具将使用两个单独的应用程序实例,这意味着您将拥有两个单独的绑定和两组单独的凭据。

如果您必须拥有一组凭据,您可以使用服务密钥来解决此问题。服务键类似于绑定,但不与 CloudFoundry 中的应用程序关联。

服务密钥的缺点是它不会像绑定一样通过$VCAP_SERVICES 自动暴露给您的应用程序。要解决此问题,您可以将服务密钥凭据传递给用户提供的服务,然后将其绑定到您的应用程序,或者您可以通过其他环境变量将它们传递到您的应用程序,例如 DB_URL

另一种选择是放弃使用脚本和 cf cli 插件进行蓝/绿部署,并使用现在内置于 Cloud Foundry 中的支持。对于cf cli 版本7+,cf push 有一个--strategy 选项,可以将其设置为rolling 以执行滚动部署。这不会创建多个应用程序实例,因此只会存在一个服务绑定和一组凭据。

【讨论】:

    【解决方案2】:

    使用额外的bind parameter“用户名”请求静态用户名:

    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-binding

    注意:cf CLI v6.x 中的应用清单不支持任意参数。 cf CLI v7.0 及更高版本的应用清单支持任意参数。

    但是,我在这里找不到新语法:https://docs.cloudfoundry.org/devguide/deploy-apps/manifest-attributes.html#services-block。我使用的语法来自其他一些 SO 问题。

    【讨论】:

      猜你喜欢
      • 2017-02-28
      • 1970-01-01
      • 2022-10-24
      • 2014-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-16
      • 2021-12-28
      相关资源
      最近更新 更多