生产环境下最简单的Docker部署工具

3

我对Docker Hub、Cloud、Swarm、Swarm Mode、docker deploy、docker-compose Deploy等概念感到非常困惑。

对于一个只需要单台物理服务器的生产网站来说,最简单的Docker部署实践是什么?

该网站有一个全面的docker-compose.yml文件,启动了一些包括各种Web服务器、Webpack构建器和数据库在内的12个服务。使用环境变量控制开发或生产环境。

使用命令行工具将Webpack bundles上传到S3 bucket,并将sourcemaps上传到Sentry。bundle哈希用作发布ID,存储在环境变量中(即HTML写入<script src="https://s3.site.com/c578f7cbbf76c117ca56/bundle.js">,其中哈希c57...写入每个服务在docker-compose.yml中指向的环境变量文件中)。

我不需要超过一台服务器,也不需要全面的故障转移策略。我只想在部署代码更新时避免停机时间。我是一名单独的开发人员,因此不需要CI或CD。

我了解到docker-machine已被弃用。Docker Hub处理单个镜像,因此我需要处理“堆栈”或一组相关服务的东西。我知道Docker Cloud的stack.yml文件不支持buildenv_file键,因此我的docker-compose.yml不能直接使用。

(在我的docker-compose.yml中有许多以下模式的出现:

build:
  context: .
  dockerfile: platforms/frontend/server/Dockerfile

在Dockerfile中,例如:
COPY platforms/frontend/server /app/platforms/frontend/server

如果没有构建上下文和Dockerfile位置的分离,compose文件似乎无法转换为堆栈文件。

此外,我认为Docker Cloud / Swarm是用于管理多个故障转移服务器和轮询路由等功能的?我不认为我需要这些。

最后我开始意识到docker-compose deploy存在...这是我需要的工具/策略吗?


说,不到一秒钟的时间。对于少数用户来说,会话可能会失败,但如果他们点击刷新,它就会重新加载。目前(在 Docker 化之前),任何更新都应该是可以忽略的,例如“git checkout feature && php migrate.php”以切换分支并应用任何数据库迁移。鉴于 docker-compose 需要相当长的时间(太长了)来关闭和启动(如果执行 naive ^C git checkout feature && docker-compose-up),我理解需要一个 swarm 来应用滚动更新以避免停机时间。这是最简单的方法吗? - Dagrada
我已经在使用docker exec进行迁移,但这并没有解决代码更改的问题,例如在主机上进行git pullgit checkout,或者更改环境变量(例如按照文章中所述更新webpack发布哈希)。我知道镜像需要重新构建,因此我想在开发机器上构建它们并将它们推送到Hub、私有注册表或Docker Cloud,然后通过单个命令或在ssh会话中执行的脚本将其拉入生产服务器。对于我的基本用例,我不清楚哪种方法是所有选项中推荐的方法? - Dagrada
好的,但是环境变量的更改怎么办?目前,docker-compose.yml中的每个服务都指向一个环境文件。当发布前端JavaScript时,.js文件会上传到CDN,并且需要更新env文件中的变量。我不需要停止和启动docker-compose来获取对该文件的更改吗? - Dagrada
进一步测试表明,我必须运行docker-compose up才能获取更改。即使使用rebuildrestart也无法完成作业。因此,这会导致大约半分钟的停机时间(不是很好)。肯定有更好的方法吧? - Dagrada
1
我认为没有一种“典型”方法。如果需要重复使用相同的过程,则应结合使用环境变量(提供默认值)与 json/yml/php 文件(在新版本发布时提供覆盖)。 - Constantin Galbenu
显示剩余7条评论
1个回答

5
让我先更正一些事情,然后再谈谈您在这种情况下说您“不需要CI/CD”的预期Docker策略,我假设这意味着您将手动部署更新到服务器上。对于团队来说,这个工作流程不是我建议的,但对于“独立开发者”来说,它非常好用且易于操作。

“我知道docker-machine已被弃用。”

不是真的。它会得到持续更新,包括上个月的一个版本。虽然它不是为部署/管理多个服务器而设计的,但如果您只需要单个服务器来进行单个管理员操作,那么它就非常适合远程创建实例、安装docker并设置TLS证书以通过docker CLI进行远程访问:docker-machine env <nodename>

最后我开始意识到docker-compose deploy的存在。

那不是一个命令,也许你想到的是Swarm中的docker stack deploy? 我也不建议在服务器上使用docker-compose。它没有生产工具和功能。请参见我的AMA帖子关于使用单节点Swarm的所有原因
请注意,docker-compose CLI工具用于开发和CI/CD,与docker-compose.yml文件不同,稍后我将讨论这一点。
此外,我认为Docker Cloud / Swarm用于管理多个故障转移服务器和轮询路由等等?我认为我不需要这些。 Docker Cloud将于2018年5月关闭,因此我不会使用它来部署堆栈,但是如果您不需要节点高可用性,则在单个节点中使用Swarm非常好。
好的,那么对于您从本地开发到此prod服务器的工作流程:
  1. 手动构建本地镜像并将其推送到Docker Hub(或其他注册表),或者使用GitHub / Bitbucket存储代码,并在每次提交到特定分支(比如master)时由Docker Hub构建镜像。

  2. 您的docker-compose文件也是一个堆栈文件。 compose文档有专门的章节,用于“构建”(用于CI / CD服务器或本地机器工作流程)和“部署”(Swarm上的功能)。您应该在本地构建或通过Docker Hub或自定义CI服务器构建,而不是在Swarm本身中构建。生产工具通常不用于镜像构建。

  3. 一旦构建了您的服务器(使用docker-machine),您可以使用本地docker CLI来管理远程docker引擎,方法是使用 docker-machine env <name>。您将使用 docker swarm init 创建单节点Swarm,然后它将接受compose文件(也称为堆栈文件)。这些文件与旧的Docker Cloud堆栈类似但不完全相同。

  4. 现在,您可以使用 docker stack deploy -c compose.yml <stackname> 来启动服务,同时设置好您的环境变量、数据卷等。

  5. 对于更新,如果您使用17.12或更高版本的Docker(最新的18.03更好),您可以设置 update-order: start-first,并确保所有服务都定义了健康检查,这样docker就真正知道何时准备好连接,从而实现零停机。

  6. 您可以使用覆盖yaml文件和 docker-compose config 将多个compose文件层叠到单个堆栈部署中。

  7. 对于服务更新,您只需更新compose文件并重新执行 docker stack deploy,它将检测到更改。

  8. 请确保每次使用唯一的镜像标签,以便Docker知道要部署哪个特定的SHA。不要一直使用 <imagename>:latest,期望它知道确切是哪个镜像。

我希望这可以帮到你,如果有更多问题,请在评论中提出,我会根据需要更新此答案。

Bret,非常感谢您详尽的撰写。您给了我许多指针和材料可供查阅 - 我会及时跟进。非常感激! - Dagrada
1
嗨,Bret,我按照你的建议设置了单节点Swarm(忽略了误导性的“在生产中使用Compose”文档页面!)。实际上,我有两个EC2实例,都运行着单节点Swarm,并且有一个弹性IP用于蓝绿部署,这使得我的代码更新具有可靠的约1秒的停机时间,非常棒!(我尝试过使用多节点Swarm进行滚动更新,但是由于能够“几乎实时”测试代码,蓝绿设置似乎更好。多节点仍然可以用于故障转移和扩展,但实际上我不需要)。再次感谢你的指引! - Dagrada
1
为了完整性,我有一台专门运行LetsEncrypt的“cert”机器,以certonly模式自动进行路由53挑战协商,并将证书写入与两个蓝/绿节点共享的EFS卷。任何其他所需的绑定卷也是共享的EFS卷,因此蓝/绿容器是主机中立的。对这个设置非常满意 :) - Dagrada

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接