deployment - 负载均衡器后面的 docker 容器的滚动部署

标签 deployment docker docker-compose

我在负载均衡器后面滚动部署 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 strategiescircuit breakers .

关于deployment - 负载均衡器后面的 docker 容器的滚动部署,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32076129/

相关文章:

javascript - 部署 Next.js

python-3.x - 将 python 日志记录添加到 FastApi 端点,托管在 docker 上不显示 API 端点日志

docker - 无法连接到 wurstmeister/kafka

docker - 声明环境变量,其值包括 docker/docker-compose 的空间

java - 自动化 Web 测试服务器部署

android - 谷歌播放控制台 : Promoted app from Alpha to Beta but still needs to Pre register

networking - Kubernetes如何确保动态部署?如何更改数据路径?

azure - 如何修复 Azure CI 上的控制台日志编码问题?

docker - 如何使docker层为单层

ruby-on-rails - Rails 5没有Cron的常规任务