我在尝试使用 nginx 的上游指令自动部署 docker 容器时遇到了一些奇怪的问题。出于某种原因,当我手动执行以下操作时,它可以工作,但当我尝试自动化时,我没有得到一致的结果。
基本上,我会拉取最新的图像停止,删除 2 个正在运行的容器中的 1 个,然后启动容器,然后更新 nginx 上游配置文件,重新加载 nginx 配置。对第二个容器重复上述操作。
看起来很简单,但出于某种原因,我无法始终在 bash 脚本中使用它。我正在使用 seige 对应用程序进行负载测试。
siege -d1 -t75S -c25 http://192.168.49.4:8087
我的脚本用于自动化部署,在运行脚本之前会提取最新的图像。
#! /bin/bash
appname=appnamexyz;
appport=8000;
host_ip=192.168.49.4;
registry=192.168.254.96;
echo "upstream api_servers {${nl}
server $(docker port ${appname}-1 ${appport}) max_fails=2 fail_timeout=1s;${nl}
server $(docker port ${appname}-2 ${appport}) max_fails=2 fail_timeout=1s;${nl}
}" > /etc/nginx/conf.d/api_upstream.conf
sed -i "s/server $(docker port $appname-1 $appport)/server xxx/g" /etc/nginx/conf.d/api_upstream.conf
docker stop $appname-1
docker rm -f $appname-1
docker run -d --name $appname-1 -p $host_ip::$appport $registry:5000/$appname -APIKey=e5e1c4b8e46d563c3
sed -i "s/server xxx/server $(docker port $appname-1 $appport)/g" /etc/nginx/conf.d/api_upstream.conf
nginx -s reload
sleep 15s
sed -i "s/server $(docker port $appname-2 $appport)/server xxx/g" /etc/nginx/conf.d/api_upstream.conf
docker stop $appname-2
docker rm -f $appname-2
docker run -d --name $appname-2 -p $host_ip::$appport $registry:5000/$appname -APIKey=e5e1c4b8e46d563c350b7
sed -i "s/server xxx/server $(docker port $appname-2 $appport)/g" /etc/nginx/conf.d/api_upstream.conf
nginx -s reload
cat /etc/nginx/conf.d/api_upstream.conf
应用程序将返回 200 秒,然后在重新启动第二个容器时,我将收到 500,502 错误。这是我的应用程序的配置文件。
server {
listen 8087;
server_name 192.168.49.4;
location / {
proxy_pass http://api_servers;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_504;
proxy_connect_timeout 1;
}
}
我应该怎样补救?
答案1
502 对应于后端超时,而 500 是服务器错误,表示配置错误。您可能希望首先修复以下问题:
在睡眠之前,你实际上api_upstream.conf
用
sed -i "s/server xxx/server $(docker port $appname-1 $appport)/g" /etc/nginx/conf.d/api_upstream.conf
(你甚至做了两次...目的?双重复制粘贴?)
但你当时还没有做的是替换第二行,它仍然是
server $(docker port ${appname}-2 ${appport}) max_fails=2 fail_timeout=1s;${nl}
我认为$appname
和$appport
是空的,导致子 shell 失败/为空,这意味着这一行实际上被解释为
server max_fails=2 fail_timeout=1s;
当使用默认循环对请求进行负载平衡时,nginx 可能会遇到一个问题......
您应该确保api_upstream.conf
在使用时始终包含有效数据。您可以server
稍后在其中添加 s,但让部分写入的占位符不会产生任何好处。
答案2
我自己也遇到过同样的问题:容器的启动时间在图像的部署中并不相同......因此,从一个容器重新启动容器并不总是那么快......可能只是你必须在旋转另一个容器之前设置某种一致性检查...你甚至可能希望从 shell 脚本中点击容器进行健康检查,而不是等待任意的 15 秒......?