在单个生产服务器上自动启动和停止多个容器

75次阅读
没有评论

问题描述

正在为大学的一个项目工作,他有以下需求:
1. 希望能够启动和停止具有不同应用程序的(docker)容器。
2. 只有一个(大学)服务器可供使用。
3. 希望使用大学的GitLab来自动化启动和停止过程。

用户目前的想法是:
用户在现有的GitLab项目上创建一个新的分支。如果分支具有特定的格式,例如Deploy-0x-name,则在服务器上部署一个新的容器,并通过网络访问。如果删除分支,则容器也会从服务器中删除。用户不确定应该使用哪些工具。他考虑使用Kubernetes,但似乎对于单个服务器设置来说并不理想。至少这是他所了解到的。此外,他并不需要在不同容器实例之间进行负载均衡,因为每个应用程序只会运行一个实例。尽管如此,他仍然需要管理多个应用程序。

在这种情况下,是否有更好的替代方案,或者应该采用完全不同的方法?

解决方案

请注意以下操作注意版本差异及修改前做好备份。

方案1

在这种情况下,使用Kubernetes可能过于复杂,因为它是为在多台机器上运行容器而设计的。然而,你可以使用MiniKube在单个服务器上运行Kubernetes。你可以在自己的笔记本电脑上运行它,虽然它被认为是“开发模式”而不是“生产就绪”,因为没有人期望在单个服务器上运行关键业务系统。但是,如果你只有一个服务器,那么使用MiniKube是可以的。

如果你不使用Kubernetes,你将不得不自己创建大量的“应用程序基础设施”。你需要从头开始编写软件,使其始终运行,并公开一个Webhook,供GitLab调用,然后进行大量的“从头开始”的容器管理。

虽然这完全可能,但我不建议尝试。你必须担心容器崩溃、容器在服务器重启后启动、服务器操作系统补丁后的一切工作情况。

一旦你运行了“MiniKube”(在自己的笔记本电脑上启动!),你的问题就变得容易得多了。它将记住应该运行的容器,并在服务器重新启动时重新启动它们(你需要在服务器重新启动时启动MiniKube)。它还公开了标准的Kubernetes API,旨在使容器的管理变得容易。这使得解决你的问题变得更加容易。

你说你想为每个分支运行一个容器,并使用特定的命名约定。这有点不寻常。通常,我们会将“master”作为服务器的状态,并在每个“服务”上使用一个文件夹。尽管如此,每个分支一个应用程序是可行的。无论是GitLab、GitHub Actions还是BitBucket Pipeline,我都会使用Helm作为管理容器的工具。

我会创建一个带有Helm的Docker镜像,并通过环境变量将凭据(例如用户名和密码)传递给GitLab,并将分支名称作为参数传递。然后,在构建运行时,你可以在容器中使用脚本构建应用程序,然后运行Helm来安装或升级应用程序。你可以使用分支名称作为Helm应用程序名称。Helm将使用存储库中该分支上的内容创建或更新应用程序。

首先,在你的笔记本电脑上安装Helm和MiniKube。然后,按照Helm文档的指导,将其打包并安装到你的笔记本电脑上的MiniKube中。一旦你有了原型解决方案,请在服务器上安装MiniKube,并尝试通过在你的笔记本电脑上运行一个具有Helm的Docker镜像来管理应用程序。最后,让GitLab运行经过测试的Helm Docker镜像。

方案2

由于你只有一个服务器和几个服务,我不确定Kubernetes是否是一个很好的选择。它非常强大,值得学习,所以也许可以尝试一下。

在这种情况下,更好的方法是使用Ansible。它是一种配置即代码(CasC),可以在GitLab的流水线中自动化。Ansible的另一个好处是它会强迫你学习更多关于系统、服务和网络的知识,而不是使用类似Kubernetes的工具。

另一种方法是使用Hashicorp的Nomad,我对此不太熟悉。它与Kubernetes类似吗?也许有点类似?但更简单。不确定它与Ansible相比如何。

最后一种方法,我不太推荐,就是通过SSH登录到服务器,并使用bash和/或docker compose进行操作。这是一种较为困难的方式,而且没有学习Ansible这样的技能的好处。

此外,还有像Chef和Puppet这样的Ansible替代方案,但我认为Ansible是最好的选择。

评论:
1. 每个容器一个分支是一个真正的反模式。我在一个项目上看到过这种“使用分支而不是文件夹”的模式,它使得一切都变得更加困难 – 实际上意味着多个main/master分支而不是一个。
2. 我不确定相对于使用K8s清单文件的kubectl apply -f来说,使用Helm的额外复杂性是否合理。kubectl的方法与GitOps工具(如ArgoCD)很好地配合使用,这些工具还具有从GitHub等轮询仓库更改或从Webhook触发的功能。

正文完