我是否错误地部署了 Google Cloud?

我是否错误地部署了 Google Cloud?

我之前使用过 Heroku 和 AWS,现在正在使用 App Engine 和 Cloud SQL(Postgres)在 Google Cloud 平台上建立服务。

我们尝试使用 12 因素原则来构建该应用程序。

事实证明这个设置非常繁琐,我开始怀疑我是否从根本上错过了什么。

以下是一些让我感到困惑的事情:

  1. 被鼓励写密码进入最终进入源代码控制的文件中 (app.yaml)。
  2. 需要破解加载环境变量的解决方法(如果我不想将它们提交给源代码控制)。
  3. 发现要连接到云 SQL 实例,我需要一行引用 app.yaml 中的特定实例 - 所以现在我需要 app.staging.yaml 和 app.production.yaml?
  4. 发现该行似乎仅支持 1 个 DB 实例,并且不清楚如果我们希望应用程序连接到 2 个 DB,是否支持。

我是否错过了服务器管理中的一些重大发展,而这些已成为最佳实践?刚刚发现第 3 点和第 4 点后,我真的开始认为我的设置中一定出现了根本性错误。是吗?

答案1

我还没有专门尝试按照您描述的方式配置应用程序,但我知道这些不是 Google 想要的结果。为了解决一些具体问题:

  1. 连接到 Cloud SQL具体说以下内容表明存储密码不是他们的本意,并为秘密提供单独的解决方案。

    # Remember - storing secrets in plaintext is potentially unsafe. Consider using
    # something like https://cloud.google.com/secret-manager/docs/overview to help keep
    # secrets secret.
    
  2. 根据本文,Google App engine 不支持 app.yaml 中的环境变量(有关 Google App Engine 类似问题的评论)。我针对类似问题的解决方案是以下代码:

    #!/bin/bash
    # deploy-helper.sh
    
    prepare_yaml() {
        [ -z "$1" ] && echo "ERROR: template.yaml filename must be provided." && exit 1
    
        template="${1}"         # ARG #1 : filename of template yaml
        finalYAML=$(mktemp)     # make temporary file
    
        generated_stdin_cmds="$(echo "cat <<EOF >\"$finalYAML\""; cat $template; echo EOF;)"
        source /dev/stdin <<< "$generated_stdin_cmds"
        echo "$finalYAML";      # return filepath of filled-in file
        return 0
    }
    
    # Set environment variables 
    TYPE="prod"                     # in script file
    source env/production.vars      # read them in from a file
    
    DEPLOYMENT_FILE="app.flexible.yaml"
    tmpfile="$(prepare_yaml "app.tpl.yaml")"
    if [ $? -eq 0 ]; then
        mv "$tmpfile" "$PWD/$DEPLOYMENT_FILE"   # gcloud wants specific filename
        gcloud app deploy "$DEPLOYMENT_FILE"
        rm "$DEPLOYMENT_FILE"                   # Cleanup temporary file
    fi
    

    注意:此脚本也可以使用 subprocess 库以 Python 编写。这就是我为 GKE 项目自动构建的方法。

    接下来,获取应用程序 app.yaml 文件并添加 bash 变量字符串替换,如本示例 app-tpl.flexible.yaml:

    # example app-tpl.flexible.yaml
    ---
    runtime: custom
    env: flex
    env_variables:
      MYSQL_SOCK: "/cloudsql/${project}:${region}:${instance}"
      MYSQL_DB: "${db_name}"
      MYSQL_USER: "${db_user}"
      MYSQL_PASSWORD: "${db_pw}"
    

    制作包含必要变量的文件(在源代码管理中被忽略)

    #!/bin/bash
    # FILE: env/production.vars
    
    project="project-name"
    region="europe-west1"
    instance="prod001"
    db_name="db001"
    db_user="root"
    db_pw="qwerty"
    
  3. 这应该由答案 #2 解决。在要执行的脚本上添加一个标志/选项,用于交换 SQL 实例或更改环境变量名称。

  4. 看起来你需要配置两个 CloudSQL 连接实例,然后自动 CloudSQL 代理将能够连接到 2 个数据库。请参阅cloud.google.com/sql/docs/mysql/connect-app-engine-flexible和这个回答因为他们使用不同的端口号来工作。

祝你好运!

答案2

@codejedi 的上述回答(使用 Google Secrets Manager 或在部署期间注入它们)是我今天要采取的措施。

在我发布这个问题时(2018 年 4 月),Google Secrets Manager 还要 18 个月才会发布。

我最终决定自己解决这个问题使用数据存储区

相关内容