Docker易伸缩,Container越来越大,各种版本的冲突不断,安装包管理器是怎么处理的,如果还在为这些头疼,还在有这些疑问,可以了解一个小工具——Nix
Docker是作为一个可以容易伸缩应用的工具而开始的,一般会被用作SaaS平台的建设(Docker是dotCloud的一部分,一个提供PaaS服务的平台)。
今天Docker经常被用于分配应用程序,而不是仅仅易于扩展,如果你只是在开发环境下用Docker,只是用它来复制你的开发环境,那你很有可能没有用到Docker的易扩展性。
糟糕的软件分配
Docker经常被用在分配应用程序上,因为现在分配应用程序是一件很糟糕的事情。先让我们看看日常我们能接触到的包管理器:yum、apt- get、npm、composer、gem、cabal等等。每一种语言的生态里都有自己的包管理器。基本上这些包管理器都做着同样的事情:解决依赖性确 保应用程序可用。一般意味着要下载二进制文件,将其放在PATH,亦或者下载JavaScript源码使之可用于正在运行的环境中。
许多包管理器把安装包存在一个全局可变的目录下。例如 /usr/local/bin。现在如果说我们有应用A,依赖于Ruby 1.8.1安装在了/usr/local/bin同时在PATH下可用。假如我们现在要安装不同的应用B,其需要依赖于Ruby 2.2.1 ,因此我们得去升级Ruby。那么现在应用A因为其不能兼容新的Ruby版本就要被破坏了。即因为安装B我们不得不破坏A。换句话说就是安装包是有副作用 的。这是由于全局可变的目录。
由于这些副作用你不能仅仅考虑你安装的东西了。你不得不去担忧会破坏你现有的设置。当然这其实也就是容器的可贵之处:你可随意实验同时重启容器,就 像你可以只运送蛋糕,而不是配方,来避免那些副作用。这也意味着这些东西我们只要运行就能立即工作。并没有那些因为依赖产生的错误。
不好的一面就是容器体积会越来越大。意味着部署会越来越慢变成一个更慢的工具。容器通常包含着整个系统。想想看:你运行的操作系统仅仅是运行着自己的操作系统。虽然看起来不是很好,但是有副作用也不是什么好的做法。
欢迎来到未来:Nix
Nix是一个打破全局可变目录的包管理器,引用Nix网站的一段话:
Nix的一个纯粹的功能就是确保安装或更新包的时候不破坏其它包。 这是因为它不会用较新的版本覆盖依赖关系,而导致其他地方被损坏。同时它还支持回滚,确保安装包在更新的时候不会出现不一致的情况。
让我们回顾一下刚才应用A和B的例子。Nix可以说“A只需要Ruby 1.8.1”同时“B只需要Ruby 2.2.1”。Nix可以让应用程序运行在特定的应用环境里。就像是A在他的PATH中有Ruby 1.8.1,B在他的PATH中有Ruby 2.2.1 。
在Nix的管理下安装包将不再有所谓的副作用。两个不同的Ruby可以同时运行,是因为这里有一个典型的包管理意义上的全局目录(使用nix-env,https://nixos.org/nix/manual/#sec-nix-env。但是这是用户,而不是应用程序。)。这个特有的功能将不断的往全局目录里边塞东西。但是Nix并没有添加其到PATH中。要使用的话得明确的告诉Nix,不然包还是不可用的。
因为Nix是免费的没有副作用,你不需要容器来获得可重复的构建。Nix去除包管理的缺点,从而取代了现在Docker的作用。当你可以用Nix更换整个容器时,你不需要第二次来更换操作系统与您的容器。
有一些情况,其中容器是有意义的。前面已经说了用Docker扩展软件很容易。但大多数Docker使用者不拥有这些类型的问题。他们赋予Docker一种“它只是工作”的感觉。
Docker和Nix并不互相违背。您可以使用Nix来构建你的Docker镜像。现在,你的开发人员可以运行软件,而无需使用Docker,因为他们可以得到相同的设置作为其本地机器上运行,而生产安装使用Docker,方便的缩放的容器。
小贴士
Docker是用于伸缩的,但被滥用来分发可重复的构建。其原因是:包管理器因为这会导致副作用可变全局状态不可预测的。使用像Nix一个很好的包 管理器可重复建立你的软件,你最有可能不需要Docker了。一个好的包管理器可以让你任意玩却不破坏环境,就像容器做的那样。