我在负载均衡器后面滚动部署 Docker 容器时遇到问题。
这是我的 docker compose yml 文件内容。
nginx:
image: nginx_image
links:
- node1:node1
- node2:node2
- node3:node3
ports:
- "80:80"
node1:
image: nodeapi_image
ports:
- "8001"
node2:
image: nodeapi_image
ports:
- "8001"
node3:
image: nodeapi_image
ports:
- "8001"
这是我的 nginx.conf
worker_processes 4;
events { worker_connections 1024; }
http {
upstream node-app {
least_conn;
server node1:8001 weight=10 max_fails=3 fail_timeout=30s;
server node2:8001 weight=10 max_fails=3 fail_timeout=30s;
server node3:8001 weight=10 max_fails=3 fail_timeout=30s;
}
server {
listen 80;
listen 443 ssl;
# ssl on;
ssl_certificate /etc/nginx/ssl/imago.io.chain.crt;
ssl_certificate_key /etc/nginx/ssl/imago.io.key;
location / {
proxy_pass http://node-app;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
}
如果我想要部署一个新构建的镜像,我必须停止节点容器,将其删除并使用新镜像重新创建它。这里的问题是,新容器将获得一个新 IP,而 nginx 容器不知道该新 IP,因此,如果我在重新创建最后一个容器后重新创建负载均衡器后面的 3 个容器,则应用程序将不再提供服务,因为所有 IP在 nginx 机器中 /etc/hosts
和环境变量不再是最新的。
我可以通过 SSH 连接到每个容器,通过从 git 存储库中拉取来更新其代码并重新启动该进程,但这对我来说似乎是错误的。这样做的正确方法是什么?
最佳答案
有一种更简单的方法可以实现此目的,以以下 docker-compose.yml 文件为例:
lb:
image: tutum/haproxy
links:
- app
ports:
- "80:80"
app:
image: tutum/hello-world
这个 docker compose 文件描述了两个服务:
- lb:使用 tutum/haproxy 的负载均衡器图片
- app:监听端口 80 的示例 Web 应用
如果您天真地使用 docker-compose up -d 启动这些服务,您最终将只有 2 个容器(负载均衡器和 Web 应用程序)。
但是如果您运行 docker-compose scale app=3
然后再次运行 docker-compose up -d
,您最终将得到 4 个负载平衡的容器。
这里的关键角色是 tutum/haproxy
docker 镜像,它能够发现它链接到的不同容器。
类似的解决方案是使用 Jason Wilder's nginx-proxy图像,其优点是实时发现新节点;因此您无需重新启动 lb
服务。
lb:
image: jwilder/nginx-proxy
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
ports:
- "80:80"
app:
image: tutum/hello-world
environment:
VIRTUAL_HOST: www.mysite.com
VIRTUAL_HOST
环境变量必须设置为解析为 Docker 主机 IP 地址的域名。
另一种是使用Traefik
lb:
image: traefik
command: --docker
ports:
- "80:80"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
app:
image: tutum/hello-world
labels:
traefik.frontend.rule: Host:www.mysite.com
traefik.frontend.rule
标签必须定义 Traefik rule设置为解析为您的 docker 主机的 IP 地址的域名。
Traefik 还提供不同的 load balancing strategies和 circuit breakers .
关于deployment - 负载均衡器后面的 docker 容器的滚动部署,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32076129/