使用deb软件包就像将其部署为应用程序的容器一样,是否有任何缺点?


15

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

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

对于没有端口冲突且所有依赖项都在虚拟环境中维护的小型服务而言,“将dep-packages作为原始容器”似乎很有意义。

但是,我的直觉告诉我,如果deb软件包非常合适,它将更加常见,并且docker将被宣传为一种针对特定语言的解决方案。使用诸如deb包之类的东西来部署我们的服务,而不是使用诸如docker这样的完整系统是否有任何弊端?


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

嗯,这不是专门针对使用deb-package而不是docker容器。我将从博客中添加更多信息到问题中。
avi

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

Answers:


16

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

可能的答案是,如果您愿意为应用程序编写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

和a 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添加节点源存储库和一些帮助程序包(如apt-transport-https)会更加复杂。)

因此,实际上可以同时使用Debian软件包Docker,但是…

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

这是一个正确的障碍,这使我们开始自问,为什么Docker被证明是作为临时打包系统而受欢迎的,而不是旨在成为一个打包系统。(往上看。)

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

  • Docker规范与shell脚本非常接近,无论它来自何处,我们都使用shell安装软件。

  • Docker提供了一个“内置”(付费)服务来托管其产生的人工制品Docker Hub

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

结论

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


6

是的,有缺点。

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

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

docker的主要目标是将每个应用程序与托管系统以及同一主机上的其他应用程序隔离。进行这种隔离的原因有两个:1.避免使应用程序被占用以接管主机或影响另一个应用程序2.为应用程序提供确切的依赖关系并防止其受到系统更新或另一个应用程序的影响依赖性。


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

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

5

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

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

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

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

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

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


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

1

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.