2017-06-21 88 views
1

我推出我的Phoenix應用程序到Kubernetes集羣以通過GitLab進行測試。一旦我的應用程序和postgres服務準備就緒,我希望能夠在我的gitlab-ci.yml腳本中運行mix ecto.migrate。下面是來自gitlab-ci.yml文件的一個片段:GitLab CI/Kubernetes - 爲測試env運行postgres遷移(非生產)

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莢:

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

從概念的角度來看我想:

  1. 配置在我的Postgres容器readiness probe,所以不被認爲是莢「運行」,直到發動機了。

    # in the Pod template: 
    # spec.containers['postgres'] 
    
    readinessProbe: 
        exec: 
        command: 
        - psql 
        - -U 
        - postgres 
        - -c 
        - 'SELECT 1' 
        initialDelaySeconds: 5 
        periodSeconds: 5 
    
  2. 在執行我的混合任務之前,等待Pod轉換到「正在運行」狀態。

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

這聽起來像是一個好主意。我只在我的臨時環境中啓動'postgres'服務器,所以'postgres' pod應該有控制「正在運行」狀態的測試/探針。在過去,我避免了這個解決方案,因爲我想使用默認的舵圖。不幸的是,它[不提供](https://github.com/sapcc/helm-charts/blob/master/common/postgresql/templates/deployment.yaml)重新配置準備就緒探測器的方法。這意味着我必須分叉並維護它。不是世界末日,但它本來不錯 – Mitkins

+0

我看到圖表使用'pg_isready'命令,它應該也是一個足夠可靠的探測器,是不是在實踐中? –

+0

除非我對helm'--wait'參數的行爲錯誤 - 不,它似乎不夠。我可以嘗試使用你建議的'get pod'命令,看看是否有什麼區別 – Mitkins