我的团队目前正在尝试确定是否应将我们的Nodejs应用程序部署为deb软件包,而不是尝试在诸如Docker这样的容器中运行它。

我从这里阅读此博客得到了这个想法,一些将deb包用于预先存在的python应用程序的良好论据。这个博客吸引我们的主要观点是维护Docker生态系统的问题(端口共享,权限,Docker映像的托管等)。

看起来像“ dep-packages as the原始容器”对于小型服务非常有意义,因为小型服务无需担心端口冲突,并且所有依赖项均在虚拟环境中维护。

我的直觉告诉我,如果deb软件包非常合适,这将更为常见,而docker将被宣传为一种针对特定语言的解决方案。使用诸如deb包之类的东西来部署我们的服务,而不是使用诸如docker之类的完整系统有什么缺点吗?

评论

这些并不是互斥的,您可以将deb包部署在Docker容器中。也许您应该问微服务与虚拟机?

嗯,不,这不是专门用于使用deb-package而非docker容器。我会将来自博客的更多信息添加到问题中。

“我们认为升级内核以更快地交付代码是一个过分的解决方案。”这对我来说听起来是错误的。还有什么比更快地交付代码更重要的呢?

#1 楼

首先,尽管有时将Docker视为临时包装系统并使用它,但它实际上解决了一个完全不同的问题:Docker与运行程序有关。 Docker系统允许描述可以随意缩放的服务,并控制大量的容器。 Debian软件包用于安装程序,它们能够处理软件版本之间的依赖关系。 Docker当然没有资格作为后裔打包系统:每个“包”只能有一个依赖关系,系统没有“递归构建”选项,并且不支持复杂的版本约束!

一个可能的答案就是这样,如果您愿意为您的应用程序编写Debian软件包,则还可以使用Docker来部署您的应用程序。这可以通过配置脚本apt_setup.sh来实现,该脚本看起来像

apt-key add - <<EOF
-----BEGIN PGP PUBLIC KEY BLOCK-----
<YOUR RELEASE OFFICER PGP KEY GOES HERE>
EOF

cat >> /etc/apt/sources.list <<EOF
deb https://my.organisation.org/repo debian-jessie main
apt-get update -y
apt-get upgrade -y
EOF


,然后按照Dockerfile的方式

ADD apt_setup.sh /root
RUN sh -ex /root/apt_setup.sh && rm /root/apt_setup.sh
RUN apt-get install -y my-node-js-package


(在您的特定情况下,apt_setup.sh会更加复杂,添加了nodesource存储库和一些帮助程序包,例如apt-transport-https。)软件包和Docker同时进行,但是...


我的直觉[…]告诉我,如果deb软件包很合适,那会更常见


这是一个正确的提示,这使我们开始自问,为什么Docker被证明是作为即席打包系统而流行的,而不是旨在成为一个打包系统。 (请参见上文。)

来自给定发行版的“官方”打包系统只是在许多其他计算环境中安装软件的可能性。还有许多其他来源可用,例如特定于社区的软件包管理器(例如npm或opam),端口树(例如pkgsrc)和纯源代码分发。从这个角度来看,很容易理解Docker作为即席打包系统的成功:


Docker规范与shell脚本非常接近,无论它来自何处,我们都使用shell安装软件。
Docker提供了一个“内置”(付费)服务来托管其生成的工件Docker Hub。

现在Debian软件包相对于作为软件包系统的Docker映像有何优势?严格控制安装时的依赖性。 (也存在升级和降级的可能性,但如果我们实施不可变服务器模式,则没有实际意义。)这将导致

结论

如果将一个产品部署在一个版本中(这对于SaaS是典型的),则您的版本管理需求非常简单,并且使用Docker作为临时包管理器应该没有任何硬缺点。一旦使用单个产品或多个产品的多个版本,您需要解决的版本约束问题的复杂性就会增加,并且您需要一个合适的工具,如果您使用的是Debian软件包或某些配置管理系统,不同来源的混合软件。

#2 楼

是的,有缺点。

使用.deb软件包,您将无法在同一主机上拥有同一应用程序的两个版本。您将不得不依靠发行版可用的软件包,例如,如果您的应用程序依赖于Node.js,则要么受发行版的困扰,要么必须安装自己的发行版。

现在,当如果您想在同一主机上托管多个应用程序,那么当它们在两个不同版本中依赖同一事物时(它们在这里保留nodejs),您将很快陷入困境。

docker将每个应用程序与托管系统以及同一主机上的其他应用程序隔离。进行这种隔离的原因有两个:
1.避免为了使应用程序能够占用主机或影响另一个应用程序而破坏应用程序
2.为应用程序提供确切的依赖关系并防止它成为应用程序。受系统更新或其他应用程序依赖关系的影响。

评论


嗯,没有人建议使用发行版的ruby,node,python等。您也将它们打包,然后放在/ opt中。您的包裹将取决于这些。您绝对可以使用deb软件包安装应用程序的多个版本,Debian本身就有很多示例。实际上,这是管理多个版本的最佳方法。这个答案是完全错误的。

– figtrap
18-3-12在19:29



@figtrap好,尝试使用官方的elastic.co存储库并同时安装elasticsearch v。2.3和v。5.6。您要描述的是安装两个不同的软件包,如果您正在执行正确的.deb软件包,则需要进行大量调整。当您在堆栈深处需要两个不同版本的libc时,这对于构建依赖关系和维护而言都是一场噩梦。

–滕西拜
18年3月12日在21:39

#3 楼

正确完成安装程序的Debian(或RedHat)软件包是一个好习惯。软件包用于部署不经常更改的应用程序。 Debian软件包涉及一些开销,例如版本管理,依赖性管理,安装前和安装后脚本等。

在许多情况下,从旧版本升级到新版本需要仔细编写脚本,注意到版本等详细信息。因为难以更改现有状态。在不更改任何内容的情况下,用新状态完全替换当前状态会更加容易。

一旦您决定完全替换每个部署上的配置或依赖项或应用程序,因为它更容易且错误更少容易大多数组织(用于)切换到全新的VM或云实例。这意味着将在“干净”的服务器上安装软件包,并且在服务器上更改文件和配置不再是问题。

那些创建软件包并且不了解谬误的开发人员结果,突变的复杂性遭受了很多困难。

当您只需要替换应用程序时,替换虚拟机就不是最佳选择,这就是引入轻量级容器作为答案的原因。使用Docker(或其他LWC),您可以替换用户库,包括所有依赖项,而无需替换服务器本身。您还可以在同一服务器上托管具有不同依赖性的同一应用程序的多个版本,并且仅在升级时切换传入的网络流量。以及回滚时切换网络流量(蓝绿色),这对于通过程序包管理部署非常困难。

容器引入了一种将所有应用程序代码以及相关性和配置捆绑到映像中的方法。该映像具有多个属性,使其比传统的操作系统软件包要好得多。例如,它具有启用版本控制的标签,但它也具有可节省空间的图层。它提供了一种使用注册表的简便方法,可以将这些映像发送到服务器和开发环境。这些映像几乎可以完全在任何环境和任何服务器中作为容器执行。这包括开发人员的笔记本电脑以及生产环境。同样,使用VM和/或基于软件包的软件版本要困难得多。在开发人员的笔记本电脑上测试了相同的图像,并在生产中保持相同的位和字节消除了许多“在我的机器上工作”的问题。

评论


到目前为止,我发现它将“在我的机器上工作”替换为“在我的机器上工作,但在Docker中表现异常”。

–马特·莫兰(Matt Moran)
17年5月11日在7:50

#4 楼

专门谈论Docker的图像打包部分,而不是容器运行时,有一些小问题。最大的是,Docker映像更像chroot,这意味着您可以避免意外地依赖于共享系统状态,因为使用中的每个文件都必须明确包含在映像中,而系统包可能会提取您未使用的动态链接期望或以其他方式与其他软件包交织在一起。这可能会导致在您不知情的情况下加载复杂的C依赖项,例如OpenSSL。此外,使用deb软件包不会对Docker的存储系统中的共享位进行重复数据删除。对于某些人来说,这可能是一件好事,更好的I / O性能和更少的移动部件,但是对于其他人来说,这可能是个问题。