2017-02-13 77 views
2

我將一個nginx代理服務和一個rails應用程序服務部署到一個docker swarm中。 nginx取決於我的docker-compose文件中的應用程序。如何讓nginx等待我的上游服務在Docker Swarm中啓動?

我的nginx.conf文件將流量引導到我的上游應用服務(在端口3000上公開),就像這樣(僅顯示上游部分)。

upstream puma { 
    server app:3000; 
} 

我的搬運工,撰寫文件看起來像這樣:

version: '3.1' 

services: 

    app: 
    image: my/rails-app:latest 
    networks: 
     - proxy 

    web: 
    image: my/nginx:1.11.9-alpine 
    command: /bin/sh -c "nginx -g 'daemon off;'" 
    ports: 
     - "80:80" 
    depends_on: 
     - app 
    networks: 
     - proxy 


networks: 

    proxy: 
    external: true 

我的主機設置爲羣經理。

這一切都完全正常 - 沒有問題。

然而,即使我有一個取決於我的搬運工,撰寫文件部分 - (?)的應用服務可能不完全由nginx的服務啓動的時間準備,所以當上遊服務配置部分嘗試DNS解析「應用程序:3000」,它似乎沒有找到它完全。所以,當我訪問我的網站,我在nginx的日誌中發現以下錯誤消息:

2017/02/13 10:46:07 [error] 8#8: *6 connect() failed (111: Connection refused) while connecting to upstream, client: 10.255.0.3, server: www.mysite.com, request: "GET/HTTP/1.1", upstream: "http://127.0.53.53:3000/", host: "preprod.local" 

如果我殺了正在運行nginx的服務泊塢窗容器,片刻後羣重新安排,並將其返回,如果然後我訪問它的工作原理完全正常,並且該請求成功傳遞到app:3000。

我該如何防止這種情況發生 - 啓動時間有一點點的時候,當nginx啓動的時候它還不能正確解析名爲app:3000的羣集服務 - 而是嘗試將流量傳遞到IP地址....

順便說一句 - 同樣的情況,如果我重新啓動我的虛擬機 - 當泊塢窗(在羣模式)再次提出服務 - 我可以結束了同樣的問題。重新啓動nginx容器解決了這個問題。

回答

5

我已經想出了一個辦法 - 這是使用Dockerfile或docker-compose文件的HEALTHCHECK部分。

首先,它在羣模式

docker stack deploy -c docker-compose.yml mystack 

泊塢部署堆棧時將只需重新啓動服務任務,如果它不能夠好像是不是真的使用depends_on選項由於其他原因正確啓動或失敗。所以depends_on選項沒有那麼有用。

所以這是我的最終解決方案,到目前爲止,它工作得很好:

version: '3.1' 

services: 

    app: 
    image: my/rails-app:latest 
    networks: 
     - proxy 

    web: 
    image: my/nginx:1.11.9-alpine 
    command: /bin/sh -c "nginx -g 'daemon off;'" 
    ports: 
     - "80:80" 
    networks: 
     - proxy 
    healthcheck: 
     test: ["CMD", "wget", "-qO-", "http://localhost/healthcheck"] 
     interval: 5s 
     timeout: 3s 
     retries: 3 

networks: 

    proxy: 
    external: true 

所以我要做的就是,從nginx的服務器我試着在我的Rails應用程序訪問的路線 - 我創建一個叫做/ healthcheck,它返回一個200的狀態代碼。

所以當我嘗試訪問它時,結果是失敗(應用服務器還沒有準備好) - nginx將會重新啓動。希望當它再次啓動時,應用程序服務器將可用,並且上游應用程序:3000指令將執行正確的DNS解析。

所以通過這種方式,我已經「砍死」了可以在羣集模式下工作的(缺少的)depends_on行爲。

相關問題