【问题标题】:GitLab CI/Kubernetes - run postgres migration for test env (not production)GitLab CI/Kubernetes - 为测试环境(非生产环境)运行 postgres 迁移
【发布时间】:2017-06-21 14:03:00
【问题描述】:

我正在将我的 Phoenix 应用程序推送到 Kubernetes 集群以通过 GitLab 进行测试。一旦我的应用程序和 postgres 服务准备就绪,我希望能够在我的 gitlab-ci.yml 脚本中运行 mix ecto.migrate。这是来自gitlab-ci.yml 文件的 sn-p:

review:
  stage: review
  image: dtzar/helm-kubectl

  environment:
    name: review/$CI_COMMIT_REF_NAME
    url: https://$CI_PROJECT_NAME-${CI_ENVIRONMENT_SLUG}.$KUBE_DOMAIN
    on_stop: stop_review

  before_script:
    - command deploy/kinit.sh

  script:
    - helm upgrade --install db --wait --set postgresDatabase=app_db stable/postgresql
    - helm upgrade --install app ./deploy/app_chart --wait --set env.DATABASE_URL="${DATABASE_URL}"

    - export POD_NAME=`kubectl get pod -l "app=${CI_ENVIRONMENT_SLUG}" -o jsonpath='{.items[0].metadata.name}'`
    - kubectl exec $POD_NAME -- mix ecto.migrate

据我了解,--wait 参数意味着每个部署都将在继续之前完成(全部)。我发现虽然 postgres 部署已经完成,但这并不意味着 postgres 服务器已经准备好。

kubectl exec 命令运行时,我经常会收到以下错误:

** (exit) exited in: :gen_server.call(#PID<0.183.0>, {:checkout, #Reference<0.0.1.2678>, true, :infinity}, 5000)
    ** (EXIT) time out
    (db_connection) lib/db_connection/poolboy.ex:112: DBConnection.Poolboy.checkout/3
    (db_connection) lib/db_connection.ex:919: DBConnection.checkout/2
    (db_connection) lib/db_connection.ex:741: DBConnection.run/3
    (db_connection) lib/db_connection.ex:1132: DBConnection.run_meter/3
    (db_connection) lib/db_connection.ex:584: DBConnection.prepare_execute/4
    (ecto) lib/ecto/adapters/postgres/connection.ex:93: Ecto.Adapters.Postgres.Connection.execute/4
    (ecto) lib/ecto/adapters/sql.ex:243: Ecto.Adapters.SQL.sql_call/6
    (ecto) lib/ecto/adapters/sql.ex:193: Ecto.Adapters.SQL.query!/5

当我查看 Kubernetes ui 时,我可以看到我的 postgres pod 出现以下错误:

SchedulerPredicates failed due to PersistentVolumeClaim is not bound: "db-postgresql", which is unexpected.

看到这条消息后,我监控了 pod,一切都很好。但不是在我的部署脚本失败之前。

我最初的想法是,我可以为我的应用程序创建一个initContainer,它使用 psql 成功连接到服务器并检查“app_db”数据库是否存在。这样我就不必担心为超时和重试编写自己的代码 - 我可以利用 Kubernetes 提供的内置机制。

但是,我不想在我的生产环境中执行此操作(我想在生产系统上手动运行mix ecto.migrate)。在这种情况下,initContainer 只是在浪费系统资源。

我可以通过gitlab-ci.yml 脚本实现这一点吗?

【问题讨论】:

    标签: kubernetes phoenix-framework gitlab-ci kubernetes-helm


    【解决方案1】:

    从概念的角度来看,我会:

    1. 在我的 Postgres 容器上配置 readiness probe,以便在引擎启动之前 Pod 不会被视为“正在运行”。

      # in the Pod template:
      # spec.containers['postgres']
      
      readinessProbe:
        exec:
          command:
          - psql
          - -U
          - postgres
          - -c
          - 'SELECT 1'
        initialDelaySeconds: 5
        periodSeconds: 5
      
    2. 在执行我的 Mix 任务之前,等待 Pod 转换到“运行”状态。

      # in gitlab-ci.yml, before "mix ecto.migrate"
      
      - |
          while [ "$(kubectl get pod $POD_NAME -o jsonpath='{$.status.phase}')" != "Running" ]; do
            sleep 1;
          done
      

    【讨论】:

    • 这听起来确实是个好主意。我只在我的登台环境中启动postgres 服务器,所以postgres pod 应该具有将控制“运行”状态的测试/探针是有道理的。过去我一直避免使用此解决方案,因为我想使用默认的舵图。不幸的是,它确实not provide 一种重新配置就绪探测的方法。这意味着我必须分叉并维护它。不是世界末日,但会很好
    • 我看到图表使用pg_isready命令,应该也是一个足够可靠的探针吧,在实践中是不是?
    • 除非我对 helm --wait 参数的行为有误 - 不,这似乎还不够。我可以尝试使用您建议的get pod 命令,看看是否有什么不同
    • 另外值得注意的是,我配置了postgres 服务器来创建一个初始数据库。也许服务器已经准备好但新数据库还没有?但是,如果是这种情况,我会期待“数据库不存在”而不是超时消息
    • 确实 --wait 应该已经涵盖了您,它完全符合我在回答中的意图。目前尚不清楚为什么 Pod 准备就绪并同时抛出 PersistentVolumeClaim 错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-25
    • 1970-01-01
    • 2020-05-14
    • 1970-01-01
    • 1970-01-01
    • 2016-02-17
    相关资源
    最近更新 更多