git - 如何在不终止连接的情况下更新 docker web 应用程序?

标签 git docker go nginx continuous-deployment

我有一个 docker-compose.yml,它有两个服务:一个数据库和我的 Go 应用程序。我的 CI/CD 管道调用托管此 docker 容器的服务器并运行此 bash 脚本:

git fetch &> /dev/null
diffs=$(git diff master origin/master)

if [ ! -z "$diffs" ]
then
    echo "Pulling code from GitHub..."
    git checkout master
    git pull origin master

    # update server
    docker-compose up --build -d

    # kill all unused docker containers
    docker system prune -f
else
    echo "Already up to date"
fi

问题是,如果有任何未完成的 http 连接到我的容器,它们将被终止。我已经使用 "gopkg.in/tylerb/graceful.v1" 在终止之前等待未完成的连接完成,但如果客户端不断发出单独的重叠请求,这在技术上永远不会停止。

此服务在 nginx 反向代理后面:

upstream goapp {
    server 127.0.0.1:8080;
}

我的一个想法是在一个新端口上部署 docker 应用程序(不确定是否可以使用 docker-compose),然后告诉 nginx 添加一个新服务器到 upstream(例如 server 127.0.0.1:8081;) 用于所有新的传入连接。然后允许 8080 上的容器正常关闭(然后以某种方式从 upstream` 中删除)。这是可能的还是有更好的方法来做到这一点?

最佳答案

在关注高可用性的同时使用单个主机(如使用 docker-compose 所示)对我来说似乎很奇怪。稍后会详细介绍。

ATTENTION The following is simplified, vastly in parts. Furthermore, the terminology is off here and there for the sake of simplicity.

但是,有一个服务的概念,它同时可用 for docker swarmfor Kubernetes .在 Kubernetes parlay 中,服务是一个虚拟负载均衡器/透明反向代理,它知道后端可以由基本上任意数量的容器或 pod 支持(此后简称为容器,因为这在技术上对 Kubernetes 来说也不是错误的)。这些容器当然每个都运行您的应用程序。引擎知道容器是否正在关闭或变得不可用,并将请求路由到处于事件状态的容器。到目前为止,还不错。

现在,两个引擎都有不同的概念,称为“滚动更新”。实际发生的情况是,如果您的服务由多个容器支持是这样的:

Hi, I am your orchestration engine! Uh, you want to update the image for the containers backing service X? Lets see... Well, X has two backing containers, so we can do a rolling update. Uh, a new request for the service: Sending it to the second container. While it is processed, I fire up a container with the new image... Takes a while... There it is! Sending all new requests to the updated container. Now shutting down the first of the old containers... Down! Firing up a second container with the new image... Done! Great, now sending all new requests to the updated containers. Trying to stop the remaining old container... Waiting till it processed the request, but at most 30s, then I‘ll kill it... Ah, not required, already shut down...

I am pleased to inform you that I successfully updated service X to use new containers with the shiny new version of your application!

小 secret

docker-compose 技术上应该能够做同样的事情,如果你将你的服务扩展到 > 1,然后更改撰写文件然后做一个

docker-compose up

然而,所有这些关于不断开连接然后在单台机器上运行的模糊说法似乎是在试图在划艇上安装战舰大炮。我的建议:如果您的服务实际上使用临时容器(如果您以任何方式、形状或形式使用您很可能不使用的装载),请使用 docker swarm。否则,请使用 Kubernetes。虽然它的学习曲线可能有点陡峭(一开始,它会很快变平),但在更复杂的设置中是值得的。

编辑 保持包括当前上传在内的单个 session 是完全不同的事情,虽然并非完全不可能,但需要相当复杂的反向代理和/或同样复杂的应用程序设置。通常,宣布维护窗口更容易。

关于git - 如何在不终止连接的情况下更新 docker web 应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57440918/

相关文章:

eclipse - EGit 自动添加新文件

ruby - 备份所有 git repos 并使用相同脚本设置 cron 作业的脚本

amazon-web-services - Docker 容器无法连接到 Internet

Docker 和 Makefile 构建

将产生 goroutines 的 golang 方法

GitLab SSH 权限被拒绝(公钥)

git - 用另一个分支完全替换分支

.net - 无法从其他容器 : Connection refused - 1/1 brokers are down 连接到 Kafka Docker 容器

go - 有没有办法根据内容动态解码 json?

go - 为任何客户端创建 HTTPS 测试服务器