GitLab CI / Kubernetes - 为测试环境运行postgres迁移(非生产)

时间:2017-06-21 14:03:01

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

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

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.

看到此消息后,我会监控播放器,一切都很顺利。但是在我的部署脚本失败之前。

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

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

我是否可以通过gitlab-ci.yml脚本实现这一目标?

1 个答案:

答案 0 :(得分: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转换到“Running”状态。

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