2017-02-13 75 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行为。

相关问题