如何在 docker(blue/green 部署)中快速故障转移 nginx 上游容器
How to fast failover nginx upstream containers in docker (blue/green deployment)
如何让 dockerized nginx 在其中一个上游容器出现故障时快速进行故障转移?在非 docker 环境中,故障转移似乎是瞬时的,但在 dockerized 时有几个请求超时。
我在同一节点应用程序的两个实例前面的单个 node/vm 上使用 nginx 作为负载 balancer/proxy。我想象新版本部署如下(通常称为 blue-green deployments):
- 新版节点应用推送到github
- Docker hub 构建新镜像
- 其中一个上游容器被关闭、升级并重新部署
- 当其中一个容器被关闭时,nginx 会自动故障转移到另一个活动容器
- 部署升级后的容器后,另一个容器也会离线 upgrade/redeployment
然而,在 nginx 上并不能无缝地执行#4。当我为了版本提升而关闭一个上游容器时,nginx 将超时几个请求(以循环方式),因为它发现其中一个容器已关闭。我没有在非 docker 环境中发生过这种情况。
这是我的 docker 云堆栈文件:
load-balancer:
image: 'foo/load-balancer:latest'
links:
- node-blue
- node-green
ports:
- '80:80'
node-blue:
image: 'foo/node-app:latest'
node-green:
image: 'foo/node-app:latest'
nginx.conf 看起来像:
events {
worker_connections 1024;
}
http {
gzip on;
upstream app {
server node-green;
server node-blue;
}
server {
listen 80;
server_name app.local;
location / {
proxy_pass http://app;
}
}
}
经过一番折腾,我想出了一个合理的解决方案。为 dockercloud/haproxy. Apparently the load balancer needs to be able to listen to docker cloud events 换出自定义 nginx 容器,并进行相应调整。
堆栈文件现在看起来像:
load-balancer:
image: 'dockercloud/haproxy:1.5.3'
restart: always
roles:
- global
links:
- node-blue
ports:
- '80:80'
node-blue:
image: 'foo/node-app:latest'
environment:
- VIRTUAL_HOST=app.local
node-green:
image: 'foo/node-app:latest'
environment:
- VIRTUAL_HOST=app.local
当我想部署一个新版本时,我只是运行下面的脚本:
docker-cloud service set --link node-green:node-green load-balancer
docker-cloud service redeploy node-blue --sync
docker-cloud service set --link node-blue:node-blue load-balancer
docker-cloud service redeploy node-green --sync
如何让 dockerized nginx 在其中一个上游容器出现故障时快速进行故障转移?在非 docker 环境中,故障转移似乎是瞬时的,但在 dockerized 时有几个请求超时。
我在同一节点应用程序的两个实例前面的单个 node/vm 上使用 nginx 作为负载 balancer/proxy。我想象新版本部署如下(通常称为 blue-green deployments):
- 新版节点应用推送到github
- Docker hub 构建新镜像
- 其中一个上游容器被关闭、升级并重新部署
- 当其中一个容器被关闭时,nginx 会自动故障转移到另一个活动容器
- 部署升级后的容器后,另一个容器也会离线 upgrade/redeployment
然而,在 nginx 上并不能无缝地执行#4。当我为了版本提升而关闭一个上游容器时,nginx 将超时几个请求(以循环方式),因为它发现其中一个容器已关闭。我没有在非 docker 环境中发生过这种情况。
这是我的 docker 云堆栈文件:
load-balancer:
image: 'foo/load-balancer:latest'
links:
- node-blue
- node-green
ports:
- '80:80'
node-blue:
image: 'foo/node-app:latest'
node-green:
image: 'foo/node-app:latest'
nginx.conf 看起来像:
events {
worker_connections 1024;
}
http {
gzip on;
upstream app {
server node-green;
server node-blue;
}
server {
listen 80;
server_name app.local;
location / {
proxy_pass http://app;
}
}
}
经过一番折腾,我想出了一个合理的解决方案。为 dockercloud/haproxy. Apparently the load balancer needs to be able to listen to docker cloud events 换出自定义 nginx 容器,并进行相应调整。
堆栈文件现在看起来像:
load-balancer:
image: 'dockercloud/haproxy:1.5.3'
restart: always
roles:
- global
links:
- node-blue
ports:
- '80:80'
node-blue:
image: 'foo/node-app:latest'
environment:
- VIRTUAL_HOST=app.local
node-green:
image: 'foo/node-app:latest'
environment:
- VIRTUAL_HOST=app.local
当我想部署一个新版本时,我只是运行下面的脚本:
docker-cloud service set --link node-green:node-green load-balancer
docker-cloud service redeploy node-blue --sync
docker-cloud service set --link node-blue:node-blue load-balancer
docker-cloud service redeploy node-green --sync